<泛> C++3D数学库设计详解 简单光学几何 && 随机向量生成
// 注:本内容为作者原创,禁止在其他网站复述内容以及用于商业盈利,如需引用,请标明出处: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数学库设计详解 简单光学几何 && 随机向量生成的更多相关文章
- <泛> C++3D数学库设计详解 向量篇
// 注:本内容为作者原创,禁止在其他网站复述内容以及用于商业盈利,如需引用,请标明出处:http://www.cnblogs.com/lv_anchoret/ Preface 为了支持光线追踪的学习 ...
- Dubbo架构设计详解-转
Dubbo架构设计详解 2013-09-03 21:26:59 Yanjun Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解 ...
- Java生鲜电商平台-Java后端生成Token架构与设计详解
Java生鲜电商平台-Java后端生成Token架构与设计详解 目的:Java开源生鲜电商平台-Java后端生成Token目的是为了用于校验客户端,防止重复提交. 技术选型:用开源的JWT架构. 1. ...
- Python爬虫之selenium库使用详解
Python爬虫之selenium库使用详解 本章内容如下: 什么是Selenium selenium基本使用 声明浏览器对象 访问页面 查找元素 多个元素查找 元素交互操作 交互动作 执行JavaS ...
- STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解)
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) 前面 ...
- 深入探讨Linux静态库与动态库的详解(转)
2.生成动态库并使用 linux下编译时通过 -shared 参数可以生成动态库(.so)文件,如下 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静 ...
- dubbo初识(一)Dubbo架构设计详解
参见http://shiyanjun.cn/archives/325.html Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合( ...
- Dubbo架构设计详解
from:http://shiyanjun.cn/archives/325.html Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解 ...
- Dubbo架构设计详解(转自shiyanjun.cn)
Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看,Dubbo采用的是一种非常简单的模 ...
随机推荐
- C++并发编程实战---阅读笔记
1. 当把函数对象传入到线程构造函数中时,需要避免“最令人头痛的语法解析”.如果传递了一个临时变量,而不是一个命名的变量:C++编译器会将其解析为函数声明,而不是类型对象的定义. 例如: class ...
- Linux掉电处理
在嵌入式设备中,掉电处理一直是一项比较麻烦的工作,在具有Linux系统的设备中,系统的种种数据的处理更是增加掉电处理的难度.现在做以下几点总结,再遇到类似问题可以做个参考. 1,系统启动的处理 在系统 ...
- yearProgress.vue
<template> <div class="progressbar"> <el-progress :text-inside="true&q ...
- vue之props父子组件之间的谈话
眨眼就来杭州两年了,时间真快. 我们今天来说说vue的一个api---->props 首先我们先看看一个例子,是我一个项目中写的. 看到这个:有木有一点懂了.要是没懂,继续往下看 这里我们用到了 ...
- bzoj千题计划294:bzoj3139: [Hnoi2013]比赛
http://www.lydsy.com/JudgeOnline/problem.php?id=3139 队伍的顺序不会影响结果 将队伍的得分情况作为状态,记忆化搜索 就是先搜索第一只队伍的得分情况, ...
- bzoj千题计划199:bzoj1055: [HAOI2008]玩具取名
http://www.lydsy.com/JudgeOnline/problem.php?id=1055 区间DP dp[i][j][k] 表示区间[i,j]能否合成k #include<cst ...
- TrID文件类型识别linux版
读取文件头根据特征码进行文件类型匹配. 官方:http://mark0.net/soft-trid-e.html windows版本小工具:FileAnalysis 以下是linux版本 wget h ...
- 2017/05/17 java 基础 随笔
- 记一次HashMap面试
记一次HashMap面试 从网上已经身边同事朋友的面试情况来看,面试HashMap几乎是必问的,网上也很多类似的文章,但是真面起来,发现还是有很多点可以深抠的.本篇就结合一次面试经历说一下之前没有注意 ...
- 排序算法的JS实现
排序算法是基础算法,虽然关键在于算法的思想而不是语言,但还是决定借助算法可视化工具结合自己常用的语言实现一下 1.冒泡排序 基本思路:依次比较两两相邻的两个数,前面数比后面数小,不变.前面数比后面数大 ...