3d 中圆上的最近点。缺少什么?
我希望我能够清楚地解释这一点。我正在尝试计算 3D 圆上最近的点。我找到了以下解决方案: http://www.geometrictools.com/Documentation/DistancePoint3Circle3.pdf
我的代码如下(用 Lua 编写)。主要问题是投影Q似乎不正确,或者我不明白如何正确计算它。正如您在论文中所读到的那样,Q 应该是点在圆平面上的投影。
例如,圆的法线为{0,1,0},圆心位于{3,3,3}。我试图计算到圆的最近距离的点 (p) 位于 {6, 3, 2}。那么,在我的计算中,Q在圆平面上的投影是{6,0,2}。
为了使算法工作,我似乎必须用平面的位置(例如法线方向上的圆心分量)来偏移 Q。在这种情况下,y 方向的值为 3。
我可以将其破解为正常的 {0,1,0},因为它很容易,但是一旦圆将面向任意位置,我不知道如何计算它。
我错过了什么以及哪里出错了?
function calculatePointCircleDistance(p, circleCenter, circleNormal, circleRadius)
local C = circleCenter
local R = circleRadius
local Q = projectVectorOntoPlane(p, circleNormal)
-- I need to do a fix like this in order to get the calculations right
-- This for example only works with circleNormal {0,1,0}
-- Adding the y component of the circle position to the projection Q
Q[2] = C[2]
if vec3.equal(Q, C) == 1 then
print("point exacly aligned with center circle")
return vec3.mag(vec3.sub(C, p)), C
end
-- the following is calculating X=C+R (Q−C / |Q−C|)
local QminC = vec3.sub(Q, C)
local tmp = vec3.scale(vec3.div(QminC, vec3.mag(QminC)), R)
local X = vec3.add(C, tmp)
-- return distance as |X-p| as well as point X
return vec3.mag(vec3.sub(X, p)), X
end
function projectVectorOntoPlane(v, normal)
-- U = V - (V dot N)N
local vProjected = vec3.sub(v, vec3.scale(normal, vec3.dot(v, normal)))
return vProjected
end
I hope I manage to explain this clearly. I am trying to calculate the closest point on a circle in 3D. I found the following solution:
http://www.geometrictools.com/Documentation/DistancePoint3Circle3.pdf
My code is below (written in Lua). The main problem is that the projection Q seems to be incorrect, or I don't understand how to calculate it correctly. As you can read in the paper Q should be the projection of the point on the plane of the circle.
For example the normal of the circle is {0,1,0} and its center is located at {3, 3, 3}. My point (p) for which I'm trying to calculate the closest distance to the circle is located at {6, 3, 2}. Then, in my calculation, the projection Q onto the plane of the circle is {6, 0, 2}.
In order to make the algorithm work I seem to have to offset Q with the position of the plane eg the circle center component in the direction of its normal. In this case the y direction so value 3.
I can hack this for normal {0,1,0} because its easy, but once the circle will face any arbitrary position I don't know how to calculate this.
What am I missing and where am I going wrong?
function calculatePointCircleDistance(p, circleCenter, circleNormal, circleRadius)
local C = circleCenter
local R = circleRadius
local Q = projectVectorOntoPlane(p, circleNormal)
-- I need to do a fix like this in order to get the calculations right
-- This for example only works with circleNormal {0,1,0}
-- Adding the y component of the circle position to the projection Q
Q[2] = C[2]
if vec3.equal(Q, C) == 1 then
print("point exacly aligned with center circle")
return vec3.mag(vec3.sub(C, p)), C
end
-- the following is calculating X=C+R (Q−C / |Q−C|)
local QminC = vec3.sub(Q, C)
local tmp = vec3.scale(vec3.div(QminC, vec3.mag(QminC)), R)
local X = vec3.add(C, tmp)
-- return distance as |X-p| as well as point X
return vec3.mag(vec3.sub(X, p)), X
end
function projectVectorOntoPlane(v, normal)
-- U = V - (V dot N)N
local vProjected = vec3.sub(v, vec3.scale(normal, vec3.dot(v, normal)))
return vProjected
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为,你链接到的那篇论文对这次行动起到了一定的推动作用。
您的问题是
projectVectorOntoPlane
实际上并未将矢量投影到您想要的平面上。它将矢量投影到与所需平面平行但穿过原点的另一个平面上。 (然后您尝试使用Q[2] = C[2]
解决此问题,但这只会让事情变得更糟。)平面可以由法线向量一起定义 平面上的某个点,因此您可以像这样编写
projectVectorOntoPlane
函数:但是,对于这个问题,最简单的方法是在基于圆圈,所以我建议类似这个:
哦,您可能会发现使用更好的
vec3
类会更方便,也许是这个,这样你就可以写P - C
而不是挑剔的vec3.sub(P, C)
等等。That paper you linked to makes a bit of a meal of this operation, I think.
Your problem is that
projectVectorOntoPlane
does not actually project the vector onto the plane you want. It projects the vector onto another plane that's parallel to the plane you want, but which passes through the origin. (You're then trying to fix this problem with yourQ[2] = C[2]
, but this just makes things worse.)A plane can be defined by a normal vector together with some point on the plane, so you could write the
projectVectorOntoPlane
function like this:However, for this problem it's simplest to work all the way through in a coordinate system based on the centre of the circle, so I suggest something like this:
Oh, and you might find it more convenient to use a nicer
vec3
class, perhaps this one, so that you can writeP - C
instead of the fussyvec3.sub(P, C)
and so on.