[英]Height of a slope at a point's position (3D collision)?
这就是你要做的:
我们定义一条垂直线并穿过您的 2D 点。
假设我们的二维点是position
。 然后:
线上的一个点是position
,在高度分量上增加了0
。 我称之为v0
:
var v0 = Vector3(position.x, position.y, 0.0)
直线的方向是垂直的,因此两个 2D 分量都为零,高度分量为1
。 我称之为dir
:
var dir = Vector3(0.0, 0.0, 1.0)
我们通过构成 3D 三角形的三个点定义一个平面。
假设我们的 3D 点是v1
、 v2
和v3
。
根据定义,它们都在平面上。
我们可以使用叉积找到平面的法线,如下所示:
var normal:= (v2 - v1).cross(v3 - v1)
对于这个用例,我们不关心是否正常翻转。
啊,但是确保它是单位长度会很方便:
var normal:= (v2 - v1).cross(v3 - v1).normalized()
我们找到直线和平面的截距。 这就是我们的解决方案。
我们想在平面上找到一个点,我称之为r
。 这是一个点,使得从平面上的一个点到它的矢量垂直于平面的法线。 意思是(r - v1).dot(normal) == 0
。
请注意,我使用的是==
,它是相等比较运算符。 我正在使用它,因为它是一个方程式,而不是一个分配。
点r
也必须属于该线。 我们可以使用该线的参数形式,如下所示: r = v0 + dir * t
。 我们必须首先找到参数t
必须是什么,所以我们可以计算r
。
所以我们在这里替换r
:
(r - v1).dot(normal) == 0
这给了我们这个:
((v0 + dir * t) - v1).dot(normal) == 0
改编:
(dir * t + v0 - v1).dot(normal) == 0
根据点积的分配性质:
(dir * t).dot(normal) + (v0 - v1).dot(normal) == 0
由于t
是一个标量,我们可以从点积中取出它:
t * dir.dot(normal) + (v0 - v1).dot(normal) == 0
两侧减去(v0 - v1).dot(normal)
:
t * dir.dot(normal) == - (v0 - v1).dot(normal)
我们可以在点积中移动负号:
t * dir.dot(normal) == (v1 - v0).dot(normal)
并将两边除以dir.dot(normal)
:
t == (v1 - v0).dot(normal) / dir.dot(normal)
因此,我们的点r
是:
var r:= v0 + dir * (v1 - v0).dot(normal) / dir.dot(normal)
然后你可以读取r
的高度分量,这就是你的答案。
顺便说一下Godot有一个方法差不多就是这个。 但它与射线相交,而不是与直线intersect_ray
: Plane
class 的 intersect_ray。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.