射线和三角面求交
一、平面射线与线段是否相交
1.1 相交检测
步骤
1、判断射线方向(单位向量)是否与线段所在方向是否平行,如果平行则不相交
2、假设射线与线段交点为,则计算与的比例
3、如果或者则不相交
4、计算出的长度 ,由即可计算出交点坐标
关键过程
1、是否与平行
判断是否和平行可以采用向量叉乘,如果叉乘结果为零,则表示两向量平行
2、计算和
设交点为,其坐标可以表示为:
所以:
即有:
依据克莱姆法则可知:
其中:
1.2 几何意义
如下图向量与构成成平行四边形,向量与构成平行四边形(为平移到与重合),由于底边长都是且高度相同,所以这两个平行四边形面积相等。
另外平面向量叉乘可以表示两向量组成平行四边形的有向面积,所以可以表示为与的叉乘除以与单位方向向量的叉乘,即上面的中在该例中表示,表示。
1.3 代码实现
bool RayIntersection(const Point2 & ori, const Vector2& dir, const Point2& A, const Point2& B, double& t)
{
Vector2 AB = B - A;
// 1. 判断是否平行
if (std::abs(dir.Cross(AB)) < std::numeric_limits<double>::epsilon() ){
return false;
}
dir.Normalize(); // 归一化向量
Vector2 AO = ori - A;
double D = AB.Cross(-dir);
double D1 = AO.Cross(-dir);
if(D1 < 0 || D1 > D){ // 减少一次除法运算,即 0 <= u <= 1。超出线段AB范围
return false;
}
double D2 = AB.Cross(AO);
t = D2 / D;
return true;
}
二、空间射线与三角面是否相交
2.1 相交检测
步骤
1、判断射线方向(单位向量)与三角面所在平面是否共面,如果不共面则进行后续步骤,否则需要退回二维情况进行判断
2、假设射线与三角面交点为,则计算在向量方向的比例和在向量方向的比例
3、如果或者则不相交
4、如果或者则不相交(如果,则交点落在三角面内)
4、计算出的长度 ,由即可计算出交点坐标
关键过程
1、是否与面共面
可以采用和的向量叉乘计算出法线,法线满足右手法则,其长度表示平行四边行的面积;
然后判断法线和方向向量的点乘是否为零,点乘为零则表示共面
2、计算,和
设交点为,其坐标可以表示为:
所以:
即有:
依据克莱姆法则可知:
其中:
2.2 几何意义
如下图向量与以及构成成平行六面体(红色),向量与以及构成平行六面体 (绿色)(为平移到与重合,为平移到与重合),由于底面都是且高度相同,所以这两个平行六面体体积相等。
另外三维向量叉乘可以结果长度表示两向量组成平行四边形的面积,方向为两个组成平面的法线方向,三个三维向量的混合积(先叉乘(底面积)再点乘(高))表示其有向体积。所以可以表示为与以及的混合积除以单位方向与以及向量的混合积,即上面的中在该例中表示蓝色平行六面体的有向体积,表示红色平行六面体有向体积。
2.3 代码实现
bool RayIntersection(const Point3 & ori, const Vector3& dir, const Point3& A, const Point3& B, double& t)
{
Vector3 AB = B - A;
Vector3 AC = C - A;
Vector3 n = AB.Cross(AC);
// 1. 判断是否共面
if (std::abs(dir.Dot(n)) < std::numeric_limits<double>::epsilon() ){
// 共面,需要转换到平面判断是否相交,这里直接认为不相交
return false;
}
dir.Normalize(); // 归一化向量
Vector3 AO = ori - A;
double D = n.Dot(-dir);
double D1 = AO.Cross(AC).Dot(-dir);
if(D1 < 0 || D1 > D){ // 减少一次除法运算,即 0 <= u <= 1。超出线段AB范围
return false;
}
double D2 = AB.Cross(AO).Dot(-dir);
// 减少一次除法运算,即0 <= v <= 1, 其他情况超出线段AC的范围, 这里u+v<1限制落在三角面ABC中,u+v>1可能会落在BCD或四边形ABDC外部
if(D2 < 0 || D1 + D2 > D){
return false;
}
double D3 = n.Dot(AO)
t = D3 / D;
return true;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
2021-03-03 pyinstall 打包 python代码为可执行文件(pytorch)