<泛> 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.单位圆盘内的随机向量

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

 

 实现

 

/// 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 - 2 * 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 = 1. - eta*eta*(1. - cos1*cos1);
        if (cos2 > 0)
            {
            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>(1, 1, 1);
            } while (dot(p, p) >= 1.0);
        return p;
        }


//@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>(1, 1);
            } while (dot(p, p) >= 1.0);
        return p;
        }

}

 

 

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

 

转载于:https://www.cnblogs.com/lv-anchoret/p/10241904.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
㈠ 点的基本运算 1. 平面上两点之间距离 1 2. 判断两点是否重合 1 3. 矢量叉乘 1 4. 矢量点乘 2 5. 判断点是否在线段上 2 6. 求一点饶某点旋转后的坐标 2 7. 求矢量夹角 2 ㈡ 线段及直线的基本运算 1. 点与线段的关系 3 2. 求点到线段所在直线垂线的垂足 4 3. 点到线段的最近点 4 4. 点到线段所在直线的距离 4 5. 点到折线集的最近距离 4 6. 判断圆是否在多边形内 5 7. 求矢量夹角余弦 5 8. 求线段之间的夹角 5 9. 判断线段是否相交 6 10.判断线段是否相交但不交在端点处 6 11.求线段所在直线的方程 6 12.求直线的斜率 7 13.求直线的倾斜角 7 14.求点关于某直线的对称点 7 15.判断两条直线是否相交及求直线交点 7 16.判断线段是否相交,如果相交返回交点 7 ㈢ 多边形常用算法模块 1. 判断多边形是否简单多边形 8 2. 检查多边形顶点的凸凹性 9 3. 判断多边形是否凸多边形 9 4. 求多边形面积 9 5. 判断多边形顶点的排列方向,方法一 10 6. 判断多边形顶点的排列方向,方法二 10 7. 射线法判断点是否在多边形内 10 8. 判断点是否在凸多边形内 11 9. 寻找点集的graham算法 12 10.寻找点集凸包的卷包裹法 13 11.判断线段是否在多边形内 14 12.求简单多边形的重心 15 13.求凸多边形的重心 17 14.求肯定在给定多边形内的一个点 17 15.求从多边形外一点出发到该多边形的切线 18 16.判断多边形的核是否存在 19 ㈣ 圆的基本运算 1 .点是否在圆内 20 2 .求不共线的三点所确定的圆 21 ㈤ 矩形的基本运算 1.已知矩形三点坐标,求第4点坐标 22 ㈥ 常用算法的描述 22 ㈦ 补充 1.两圆关系: 24 2.判断圆是否在矩形内: 24 3.点到平面的距离: 25 4.点是否在直线同侧: 25 5.镜面反射线: 25 6.矩形包含: 26 7.两圆交点: 27 8.两圆公共面积: 28 9. 圆和直线关系: 29 10. 内切圆: 30 11. 求切点: 31 12. 线段的左右旋: 31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值