在三维空间中,圆上最接近的点。有什么缺失的吗?
2011-7-4 12:3:39
收藏:0
阅读:128
评论:1
我希望我能够清楚地解释这个。我正在尝试计算三维圆上的最近点。我找到了以下解决方案: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)
--为了正确计算,我需要对它进行修正
--例如仅对circleNormal {0,1,0}有效
--在Q的投影中添加圆心位置的y分量
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
--以下计算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)
--作为|X-p|返回距离以及点X
return vec3.mag(vec3.sub(X,p)),X
end
function projectVectorOntoPlane(v,normal)
--U = V -(V点N)N
local vProjected = vec3.sub(v,vec3.scale(normal,vec3.dot(v,normal)))
return vProjected
end
原文链接 https://stackoverflow.com/questions/6571202
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
你提供的那篇论文在这个运算上有点夸张了,我认为。
你的问题在于
projectVectorOntoPlane
实际上并没有将向量投影到你想要的平面上。它将向量投影到另一个平面上,这个平面与你想要的平行,但是它通过原点。(你试图用Q[2] = C[2]
来解决这个问题,但这只会让事情变得更糟。)一个平面可以由法向量和平面上的某个点共同定义,所以你可以将
projectVectorOntoPlane
函数写成这样:-- 将点 P 投影到法向量为 n、经过点 O 的平面上。 function projectVectorOntoPlane(P, n, O) return vec3.sub(P, vec3.scale(n, vec3.dot(vec3.sub(P, O), n))) end
然而,对于这个问题,最简单的方法是在以圆心为基础的坐标系中全部工作,所以我建议这样做:
-- 返回圆心为 C、法向量为 n、半径为 r 且距离 P 最近的圆上的点。(如果所有的点到 P 的距离都相等,返回任何一个。) function pointCircleClosest(P, C, n, r) -- 将问题转化到以 C 为中心的坐标系中。 local P = vec3.sub(P, C) -- 将 P 投影到包含圆的平面上。 local Q = vec3.sub(P, vec3.scale(n, vec3.dot(n, P))) -- 如果 Q 在圆心,所有点都与 P 最近。 if vec3.equal(Q, {0,0,0}) then Q = perpendicular(n) end -- 接下来,最近的点在原点和 Q 通过的线上。 local R = vec3.sub(P, vec3.scale(Q, r / vec3.mag(Q))) -- 返回到原始的坐标系中。 return vec3.add(R, C) end -- 返回与 n 垂直的任意向量。 function perpendicular(n) if math.abs(n[1]) < math.abs(n[2]) then return vec3.cross(n, {1,0,0}) else return vec3.cross(n, {0,1,0}) end end
哦,你可能会觉得使用一个更好的
vec3
类更方便,就像这个,这样你可以写P - C
而不是繁琐的vec3.sub(P, C)
等等。