// 注:本内容为作者原创,禁止在其他网站复述内容以及用于商业盈利,如需引用,请标明出处: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. [整理]IIS 6.0 下部署 Asp.net MVC Web Api 后 HTTP PUT and DELETE 请求失败

    http://guodong.me/?p=1560 ASP.NET MVC 4 has a new feature called WebAPI which makes it much easier t ...

  2. 第一、介绍Canvas

    canvas能做什么? canvas是HTML5中的新元素,你可以使用javascript用它来绘制图形.图标.以及其它任何视觉性图像.它也可用于创建图片特效和动画.如果你掌握了完整的命令,你可以用c ...

  3. J2EE完全手册(一)

    为了使开发者能尽快的开发企业级的应用程序,Sun在1999年推出一种基于J2SE(用于开发桌面应的Java标准版)的开发模型:J2EE,用于开发服务器应用程序与服务的Java企业版,他运行于J2EE服 ...

  4. 20155203 2016-2017-4 《Java程序设计》第6周学习总结

    20155203 2016-2017-4 <Java程序设计>第6周学习总结 教材学习内容总结 重载和覆盖:重载是将函数的名称和方法不变(名称可以有一些变动),只改变参数列表,相当于和原来 ...

  5. [译]How To Use the Linux Auditing System on CentOS 7

    本文是How To Use the Linux Auditing System on CentOS 7的中文版,翻译不到之处,还请指出和多多包涵.本文并不会完全遵从原文的一些格式,而是加入自己学习的理 ...

  6. 【配置】Spring Struts配置信息

  7. rap 部署

    Rap 安装 war包下载地址 https://github.com/thx/RAP/releases 创建数据库,并创建权限用户 mysql> create database rap_db c ...

  8. ORACLE数据库数据文件转移方法(不同于move方法)

    1) 手动拷贝要转移的数据数据文件'd:\OracleData\GWTABLE42.DBF'到新的位置'E:\OracleData\GWTABLE42.DBF'. 2) 把数据文件所属的表空间Offl ...

  9. WCF使用Net.tcp绑定时候出现错误:元数据包含无法解析的引用

    在WCF服务编程中,客户端添加引用服务时,出现如下错误: 元数据包含无法解析的引用:“net.tcp://192.168.1.105:1314/LoginService”. 套接字连接已中止.这可能是 ...

  10. 查看library的依赖树

    今天一同事问我如何解决包依赖重复的问题,我告诉他你可以用exclude,provide,compileOnly等关键字,他问我如何查找某个库依赖了什么,我说有一个插件,愣是想了好久没想起什么名字来,搜 ...