// 注:本内容为作者原创,禁止在其他网站复述内容以及用于商业盈利,如需引用,请标明出处: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. 在Linux中以普通用户开机自动运行脚本程序

    测试环境:CentOS6.5 管理员:root 普通用户:test1 实现目标:在Linux启动时,以普通用户test1自动运行位于根目录下的脚本程序test.py,该程序会在每次执行时自动向本地日志 ...

  2. android 系统开发板挂载U盘

    cat /proc/partitions 查看有u盘设备 df 查看挂载情况 iTOP4416开发板插入u盘,自动挂载到 /mnt/udisk1

  3. 20181111 Quartz(慕课网)

    Quartz体系结构 三个核心概念 调度器 任务 触发器 重要组成 Job JobBuilder JobDetail JobStore Trigger TriggerBuilder ThreadPoo ...

  4. Java基础-爬虫实战之爬去校花网网站内容

    Java基础-爬虫实战之爬去校花网网站内容 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 爬虫这个实现点我压根就没有把它当做重点,也没打算做网络爬虫工程师,说起爬虫我更喜欢用Pyt ...

  5. Spark记录-Scala类和对象

    本章将介绍如何在Scala编程中使用类和对象.类是对象的蓝图(或叫模板).定义一个类后,可以使用关键字new来创建一个类的对象. 通过对象可以使用定义的类的所有功能. 下面的图通过一个包含成员变量(n ...

  6. bzoj千题计划263:bzoj4870: [六省联考2017]组合数问题

    http://www.lydsy.com/JudgeOnline/problem.php?id=4870 80分暴力打的好爽 \(^o^)/~ 预处理杨辉三角 令m=n*k 要求满足m&x== ...

  7. python AjaxSpider 代码演示

    import re # 引入正则表达式 import json # 引入 json import pymongo # 引入mongo数据库 import requests # 引入HTTP请求协议 f ...

  8. html之div始终停留在屏幕中间部分

    需求: 使得某一个div始终停留在屏幕中间 实现: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...

  9. 20155236 2016-2017-2 《Java程序设计》第八周学习总结

    20155236 2016-2017-2 <Java程序设计>第八周学习总结 教材学习内容总结 通用API 日志 1.日志API简介:java.util.logging包中提供了日志功能相 ...

  10. Spark笔记之使用UDF(User Define Function)

    一.UDF介绍 UDF(User Define Function),即用户自定义函数,Spark的官方文档中没有对UDF做过多介绍,猜想可能是认为比较简单吧. 几乎所有sql数据库的实现都为用户提供了 ...