// 注:本内容为作者原创,禁止在其他网站复述内容以及用于商业盈利,如需引用,请标明出处:http://www.cnblogs.com/lv_anchoret/

 Preface

当初写这个库,是为了支持光线追踪的学习,所以,学完第一本书,这时候,我们整合一些物理光学方面的运算,封装到我们的泛型库里面

新库增加的目录:

--lvgm

  ----opticsfunc.hpp

  ----randfunc.cpp

 Ready

需要大家拥有之前的向量库做支持

我们这一篇涉及到的库文件比较少

我们这一篇涉及到的基本是函数

据说,写库一般用hpp比较好,所以我们开始用hpp写C++泛型库

 theory

1.反射

2.折射

公式中的η为相对折射率:n2/n1

而由于入射光线方向的随机性和eta的不同,可能导致 1-η*η*(1-cosθ1 * cosθ1)小于0,此时取根号毫无意义

而事实上,这也就是全反射现象。即:当光线从光密介质进入光疏介质中如果入射角大于某个临界值的时候,就会发生全反射现象。

该临界角即折射角为90°时对应的入射角,也就是cosθ2恰好等于0的时候

完整工程应用见https://www.cnblogs.com/lv-anchoret/p/10217719.html

3.单位球体内部随机向量

根据一个完全随机算法,确保生成一个0~1的随机数,用这样的三个随机数构建一个三维向量t

设 β = 2 * t - (1,1,1)

即保证了β的每一个分量均随机分布于0~1

这样的话,我们的向量β就等于时一个单位正方体之内的存在,而我们需要的是单位球体

所以,我们筛出单位球体外的,通过x^2 + y^2 + z^2 >= 1.0 式(a) 筛掉球体之外的

如果β = (x,y,z),也就是式(a)也就等价于 β·β >= 1.0

4. 生成单位球体表面随机点(向量)

推导详情见https://www.cnblogs.com/lv-anchoret/p/10518961.html

5.单位圆盘内的随机向量

和上面一样,减少一维即可

 实现

/// opticsfunc.hpp

// -----------------------------------------------------
// [author] lv
// [ time ] 2019.1
// [brief ] optics functions
// reflect
// refract
// ----------------------------------------------------- #pragma once #include <lvgm\type_vec\type_vec.h> namespace lvgm
{ /*
@in: the Incident light
@n: the Surface normal
@ret: the reflected light
*/
template<typename T>
const T reflect(const T& in, const T& n)
{
return in - * dot(in, n)*n;
} /*
@in: the Incident light
@n: the Surface normal
@eta: the Refractive indices
@ret: if it has a refracted light or not
*/
template<typename T>
const bool refract(const T& in, const T& n, lvgm::precision eta, T& refracted)
{
if (typeid(T) == typeid(lvgm::vec2<int>))
{
std::cerr << "the refract is adapted to float and percision-upper\n";
return false;
} T unitIn = in.ret_unitization(); //将入射光线单位化 lvgm::precision cos1 = dot(-unitIn, n);
lvgm::precision cos2 = . - eta*eta*(. - cos1*cos1);
if (cos2 > )
{
refracted = eta * unitIn + n * (eta * cos1 - std::sqrt(cos2));
return true;
}
return false;
}
}
#pragma once

#include <lvgm\type_vec\type_vec.h>
#include <random> namespace lvgm
{ //@brief: create a random number that from 0 to 1 completely
template<typename T = lvgm::precision>
const T rand01()
{
if (typeid(T) == typeid(int))
{
std::cerr << "integer doesn't have a random number from 0 to 1\n";
throw "integer doesn't have a random number from 0 to 1\n";
} static std::mt19937 mt;
static std::uniform_real_distribution<T> r;
return r(mt);
} //@brief: find a random point in unit_sphere
template<typename T = lvgm::precision>
const lvgm::vec3<T> random_unit_sphere()
{
if (typeid(T) == typeid(int))
{
std::cerr << "integer doesn't have a random number from 0 to 1\n";
throw "integer doesn't have a random number from 0 to 1\n";
} lvgm::vec3<T> p;
do
{
p = 2.0*lvgm::vec3<T>(rand01(), rand01(), rand01()) - lvgm::vec3<T>(, , );
} while (dot(p, p) >= 1.0);
return p;
} //@brief: find a random point on unit_sphere
template<typename T = lvgm::precision>
const lvgm::vec3<T> random_on_sphere()
{
if (typeid(T) == typeid(int))
{
std::cerr << "integer doesn't have a random number from 0 to 1\n";
throw "integer doesn't have a random number from 0 to 1\n";
} double r1{ rand01() }, r2{ rand01() };
return lvgm::vec3<T>
{
cos( * π * r1) * * sqrt(r2 * ( - r2)),
sin( * π * r1) * * sqrt(r2 * ( - r2)),
- * r2
};
} //@brief: find a random point in unit_plane
template<typename T = lvgm::precision>
const lvgm::vec2<T> random_unit_plane()
{
if (typeid(T) == typeid(int))
{
std::cerr << "integer doesn't have a random number from 0 to 1\n";
throw "integer doesn't have a random number from 0 to 1\n";
} lvgm::vec2<T> p;
do
{
p = 2.0*lvgm::vec2<T>(rand01(), rand01()) - lvgm::vec2<T>(, );
} while (dot(p, p) >= 1.0);
return p;
} }//lvgm namespace

感谢您的阅读,生活愉快~

<泛> C++3D数学库设计详解 简单光学几何 && 随机向量生成的更多相关文章

  1. <泛> C++3D数学库设计详解 向量篇

    // 注:本内容为作者原创,禁止在其他网站复述内容以及用于商业盈利,如需引用,请标明出处:http://www.cnblogs.com/lv_anchoret/ Preface 为了支持光线追踪的学习 ...

  2. Dubbo架构设计详解-转

    Dubbo架构设计详解  2013-09-03 21:26:59    Yanjun Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解 ...

  3. Java生鲜电商平台-Java后端生成Token架构与设计详解

    Java生鲜电商平台-Java后端生成Token架构与设计详解 目的:Java开源生鲜电商平台-Java后端生成Token目的是为了用于校验客户端,防止重复提交. 技术选型:用开源的JWT架构. 1. ...

  4. Python爬虫之selenium库使用详解

    Python爬虫之selenium库使用详解 本章内容如下: 什么是Selenium selenium基本使用 声明浏览器对象 访问页面 查找元素 多个元素查找 元素交互操作 交互动作 执行JavaS ...

  5. STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解)

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) 前面 ...

  6. 深入探讨Linux静态库与动态库的详解(转)

    2.生成动态库并使用 linux下编译时通过 -shared 参数可以生成动态库(.so)文件,如下 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静 ...

  7. dubbo初识(一)Dubbo架构设计详解

    参见http://shiyanjun.cn/archives/325.html Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合( ...

  8. Dubbo架构设计详解

    from:http://shiyanjun.cn/archives/325.html Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解 ...

  9. Dubbo架构设计详解(转自shiyanjun.cn)

    Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看,Dubbo采用的是一种非常简单的模 ...

随机推荐

  1. RabbitMQ 客户端开发向导

    准备工作:composer 引入 php-amqplib 说明:本文说明基于 Java(主要说明原理),实现使用 php RabbitMQ Java 客户端使用 com.rabbitmq.client ...

  2. sking

    #include #include #include typedef struct SKI{ int data; int x; int y; char flag; int len; }STSKI; i ...

  3. php 访问错误日志

    /usr/local/php/var/log/php-fpm.log」—————————

  4. 20181108 Apache Commons Lang

    工具类 org.apache.commons.lang3 AnnotationUtils ArchUtils ArrayUtils BooleanUtils CharSetUtils CharUtil ...

  5. mybatis+sqlserver中返回非自增主键

    首先把实体类贴出来(这里只贴出属性,其它的就是getter和setter方法): public class Around {     private String xccd;  //对应主键      ...

  6. angularJs的继承

    为什么要继承,本来是后端的概念,但是同样适用于前端开发.继承,无疑是将通用的东西抽取出来. 下面介绍的是angular的伪继承,就是说是通过继承scope这个变量来实现的.代码很简单,一行代码就可以. ...

  7. bzoj千题计划247:bzoj4903: [Ctsc2017]吉夫特

    http://uoj.ac/problem/300 预备知识: C(n,m)是奇数的充要条件是 n&m==m 由卢卡斯定理可以推出 选出的任意相邻两个数a,b 的组合数计算C(a,b)必须是奇 ...

  8. 关于MYSQL group by 分组按时间取最大值的实现方法

    类如 有一个帖子的回复表,posts( id , tid , subject , message ,  dateline ) , id 为 自动增长字段, tid为该回复的主题帖子的id(外键关联), ...

  9. CS229 笔记06

    CS229 笔记06 朴素贝叶斯 事件模型 事件模型与普通的朴素贝叶斯算法不同的是,在事件模型中,假设文本词典一共有 \(k\) 个词,训练集一共有 \(m\) 封邮件,第 \(i\) 封邮件的词的个 ...

  10. iOS 判断相册相机是否允许

    1 判断是否允许使用相机: NSString *mediaType = AVMediaTypeVideo; AVAuthorizationStatus authStatus = [AVCaptureD ...