kbi*_*irk 4 c++ algorithm math vector collision-detection
我正在尝试实现一个线段和平面相交测试,它将返回true或false,具体取决于它是否与平面相交.它还将返回线相交的平面上的接触点,如果线不相交,则如果线段已经是光线,则该函数仍应返回交点.我使用了Christer Ericson的实时碰撞检测中的信息和代码,但我认为我没有正确实现它.
使用的平面是从三角形的法线和顶点导出的.找到平面上交点的位置是我想要的,无论它是否位于我用来导出平面的三角形上.
该功能的参数如下:
contact = the contact point on the plane, this is what i want calculated
ray = B - A, simply the line from A to B
rayOrigin = A, the origin of the line segement
normal = normal of the plane (normal of a triangle)
coord = a point on the plane (vertice of a triangle)
Run Code Online (Sandbox Code Playgroud)
这是我使用的代码:
bool linePlaneIntersection(Vector& contact, Vector ray, Vector rayOrigin, Vector normal, Vector coord) {
// calculate plane
float d = Dot(normal, coord);
if (Dot(normal, ray)) {
return false; // avoid divide by zero
}
// Compute the t value for the directed line ray intersecting the plane
float t = (d - Dot(normal, rayOrigin)) / Dot(normal, ray);
// scale the ray by t
Vector newRay = ray * t;
// calc contact point
contact = rayOrigin + newRay;
if (t >= 0.0f && t <= 1.0f) {
return true; // line intersects plane
}
return false; // line does not
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中,它永远不会真实......任何想法?
小智 7
我正在回答这个问题,因为它被要求提供射线交集的c ++示例时首先出现在Google上:)
代码总是返回false,因为您输入if here:
if (Dot(normal, ray)) {
return false; // avoid divide by zero
}
Run Code Online (Sandbox Code Playgroud)
如果向量是垂直的,那么点积只有零,这是你想要避免的情况(没有交点),而非零数字在C中是真的.
因此解决方案是否定(!)或做Dot(. ..)== 0.
在所有其他情况下,将有一个交叉点.
在交点计算上:平面的所有点X都遵循等式
点(N,X)= d
其中N是法线,d可以通过将平面的已知点放在等式中找到.
float d = Dot(normal, coord);
Run Code Online (Sandbox Code Playgroud)
在光线上,线的所有点s可以表示为点p和给出方向D的矢量:
s = p + x*D.
因此,如果我们搜索飞机中的xs,我们就有了
点(N,s)= d
点(N,p + x*D)= d
点积ab是转置(a)*b.
设置转置(N)为Nt.
Nt*(p + x*D)= d
Nt*p + Nt*D*x = d (x标量)
x =(d-Nt*p)/(Nt*D)
x =(d-Dot(N, p))/点(N,D)
这给了我们:
float x = (d - Dot(normal, rayOrigin)) / Dot(normal, ray);
我们现在可以通过将x放在线方程中来获得交点
s = p + x*D.
Vector intersection = rayOrigin + x*ray;
bool linePlaneIntersection(Vector& contact, Vector ray, Vector rayOrigin,
Vector normal, Vector coord) {
// get d value
float d = Dot(normal, coord);
if (Dot(normal, ray) == 0) {
return false; // No intersection, the line is parallel to the plane
}
// Compute the X value for the directed line ray intersecting the plane
float x = (d - Dot(normal, rayOrigin)) / Dot(normal, ray);
// output contact point
*contact = rayOrigin + normalize(ray)*x; //Make sure your ray vector is normalized
return true;
}
我的想法可能是错的,但代码中有一些地方看起来非常可疑。首先,考虑这一行:
// calculate plane
float d = Dot(normal, coord);
Run Code Online (Sandbox Code Playgroud)
在这里,您的值d
对应于平面法线(向量)和空间中的点(平面上的点)之间的点积。这似乎是错误的。特别是,如果有任何平面经过原点并使用原点作为坐标点,您最终将计算
d = Dot(normal, (0, 0, 0)) = 0
Run Code Online (Sandbox Code Playgroud)
并立即返回 false。我不确定你在这里打算做什么,但我很确定这不是你的意思。
代码中另一个看起来可疑的地方是这一行:
// Compute the t value for the directed line ray intersecting the plane
float t = (d - Dot(normal, rayOrigin)) / Dot(normal, ray);
Run Code Online (Sandbox Code Playgroud)
请注意,您正在计算平面法线矢量(矢量)和光线原点(空间中的点)之间的点积。这看起来很奇怪,因为这意味着根据光线在空间中的起源位置,用于光线的缩放因子会发生变化。我建议再看一遍这段代码,看看这是否真的是你的意思。
希望这可以帮助!
归档时间: |
|
查看次数: |
20280 次 |
最近记录: |