Unity中计算线和面交点的三维数学应用
创作时间:
作者:
@小白创作中心
Unity中计算线和面交点的三维数学应用
引用
CSDN
1.
https://m.blog.csdn.net/dxs1990/article/details/138125760
在Unity引擎中,计算线和面的交点是一个常见的三维数学问题。本文将介绍一种基于向量运算和相似三角形原理的计算方法,并提供具体的实现代码。
实现方法有多种,下面介绍一种简单的方法。利用一个点指向面上任意点的向量,到该面法线的投影长度相同的基本原理,结合相似三角形既可以求出交点。
原理
如下图:
GD组成的线段和ABC组成的三角形相交与E点,ABCDG的坐标已知求E点坐标。
首先用叉乘求出ABC面的法线N;(D点分别到ABC各点的向量在法线N上投影的模长是相同的,同样等于D点到E点的向量在N投影的模长)
分别用点乘的方法求出,DA到N的投影模长a和DG到N的投影模长b;
∵DE到N的投影模长同样等于a
∴由相似三角形可得
a/b = |DE|/|DG|
由次可得E点的坐标
实现代码
Vector3 GetIntersectPoint(Vector3 C1, Vector3 C2, Vector3 C3, Vector3 L1, Vector3 L2)
{
//求面的法线
Vector3 n0 = (C2 - C1).normalized;
Vector3 n1 = (C2 - C3).normalized;
Vector3 N = Vector3.Cross(n0, n1);
//线段的向量和到面上点的向量
Vector3 line1 = L2 - L1;
Vector3 line2 = C1 - L1;
//与面法线点成比,得到线段点到面的模长
float dis1 = Vector3.Dot(N, line1);
float dis2 = Vector3.Dot(N, line2);
float magnitude = (dis2 / dis1)*line1.magnitude;
//用线段的单位向量乘模长求出交点
Vector3 direction = line1.normalized * magnitude;
return L1 + direction;
}
同样的方法也可以计算两条线段的交点
Vector3 GetIntersectPoint(Vector3 C1, Vector3 C2, Vector3 P1, Vector3 P2)
{
// 分别求出两个线段的单位向量
Vector3 L0=(C2 - C1).normalized;
Vector3 L1=( P2 - P1).normalized;
//俩次差乘建立 L0为一个坐标轴的的坐标系
Vector3 H = Vector3.Cross(L0, L1);
Vector3 N = Vector3.Cross( L0, H);
float dis1 = Vector3.Dot(N, L1);
float dis2 = Vector3.Dot(N, (P1-C1));
float magnitude = dis2 / dis1;
return L1 * magnitude + P1;
}
叉乘判断线段和面是否相交
//判断面和线段是否相相交
bool isCut(Vector3 C1, Vector3 C2, Vector3 L1, Vector3 L2)
{
Vector3 V0 = squeeze( C2 - C1);
Vector3 V1 = squeeze( L1 - C1);
Vector3 V2 = squeeze( L2 - C1);
Vector3 Cross1 = Vector3.Cross(V0, V1).normalized;
Vector3 Cross2 = Vector3.Cross(V0, V2).normalized;
float Dot = Vector3.Dot(Cross1, Cross2);
if (Dot>0)
{
//同边不相交
return false;
}
else
{
//同异边相交
return true;
}
}
//坐标平面化,去除y值
Vector3 squeeze(Vector3 vector)
{
return new Vector3(vector.x, 0, vector.z);
}
判断两条线段是否相交
bool isCut(Vector3 C1, Vector3 C2, Vector3 L1, Vector3 L2)
{
Vector3 V0 =C2 - C1;
Vector3 V1 =L1 - C1;
Vector3 V2 = L2 - C1;
Vector3 Cross1 = Vector3.Cross(V0, V1).normalized;
Vector3 Cross2 = Vector3.Cross(V0, V2).normalized;
float Dot = Vector3.Dot(Cross1, Cross2);
if (Dot>0)
{
//同边不相交
return false;
}
else
{
//同异边相交
return true;
}
}
热门推荐
社区特大暴雨应急预案,你get了吗?
从饮食到中药:中医调理痰湿体质的四种方法
一周减糖餐单,糖尿病患者福音
豆腐肉丸青菜汤:集齐动植物蛋白与膳食纤维
西安高新VS雁塔:谁才是最佳居住区?
“融为了一体”:纳菲兹的感恩之道与非暴力沟通
老子与欧阳修教你领悟“上善若水”
银行卡被误伤冻结怎么办?律师教你这样处理
每秒716圈!银河系中心发现最快旋转中子星
盘点9个低成本创业项目,适合普通人单干的赚钱项目
职场PUA的本质:黑暗三角人格与应对指南
语音助手背后的黑科技:自然语言处理
宝宝受惊夜哭不止?宝妈实战安抚秘籍
夸张手法的艺术魅力:文学创作与阅读中的独特修辞
乌龙茶+玫瑰花:减肥美容的黄金搭档
解码梦境:提升睡眠质量的科学指南
职场借钱有讲究:四种方法既保关系又护利益
国家流感中心:流感病毒诊断先锋
千岛湖:绝美自然风光打卡地
从选鱼到炖煮:制作一碗奶白无腥黑鱼豆腐汤的完整指南
68分钟无语言表演,<山海奇幻梦>让传统文化“活”起来
高铁安检新规:打火机还能带吗?
一文掌握和平精英福利碎片:获取途径与兑换攻略
高铁禁带打火机,背后竟然是这个原因?
珠海旅游攻略:从世界最大海洋公园到浪漫情侣路
房地产开发投资:海南由负转正,全国正增长省份增至4个
专家解析:黄褐斑的发病机制与科学治疗方案
宋元林医生揭秘:感冒咳嗽为何夜间加重?
交易费用理论:从企业决策到市场制度创新
自家菜园种紫甘蓝:从选地到收获的全程实操指南