在3D笛卡尔空间中,我在半径为240(主球体)的XYZ处有一个球体,在该球体内有许多其他半径为100的球体(其他物体)。我需要能够沿着边界球体的边界找到不与其中任何其他物体相交的点。
为简单起见,我们可以说主球为0 0 0,半径为240,内部有~33个物体,每个物体在不同坐标处的半径为100。
主要用Lua写作,但C / C ++也很好。 任何帮助都是值得赞赏的,甚至只是指导我如何以数学方式解决它。
编辑:使用下面David Eisenstat提供的链接和信息,这是我正在使用的代码。 它/似乎/工作,但没有机会完全测试它。
function randomSpherePoint(x, y, z, r)
local acos, sin, cos = math.acos, math.sin, math.cos
local u, v = math.random(), math.random()
local theta = 2 * PI * u
local phi = acos(2 * v - 1)
local px = x + (r * sin(phi) * cos(theta))
local py = y + (r * sin(phi) * sin(theta))
local pz = z + (r * cos(phi))
return px, py, pz
end
function fun_bordercheck()
local results = { }
local bx, by, bz, radius = -9197.944, 0, 0, 240 -- Border location and radius
for i = 1, 1000 do -- 1000 random points
local px, py, pz = randomSpherePoint(bx, by, bz, radius)
local n = 0
while (n < #space_objs) do
n = n + 1
if (xyz2range(space_objs[n].x, space_objs[n].y, space_objs[n].z, px, py, pz) <=100) then
break -- It hits, no point in checking any other objects. Skip to next random point
end
if (n == #space_objs) then -- We reached the end of the list. If we got this far, this is a possible location. Store it
results[#results+1] = { x = px, y = py, z = pz }
end
end -- while()
end -- for()
if (#results < 1) then
print("No points found.")
return
end
print(string.format("BorderCheck(): Found %d results.", #results))
for i = 1, #results do
Note(string.format("Point %d: %.3f %.3f %.3f", i, results[i].x, results[i].y, results[i].z))
end
end -- function()
答案 0 :(得分:0)
最简单的方法可能是generate points at random on the boundary of the main sphere和test them for intersections with the excluded balls。邻近结构(例如,kd树)将有助于渐近地进行交叉测试,但对于33个对象而言似乎不值得。计算Voronoi diagram也可能是一种解决方案,但球体上圆形有界区域的Voronoi图表将是一个不寻常的设置,可能需要相当数量的新的复杂代码。
答案 1 :(得分:0)
创建主球面的地图
const int na=128;
const int nb=256;
int map[na][nb];
测试所有小球体是否与主球体相交
(0,0,0)
半径R
P (x,y,z)
处的球体,半径为r
if ((|P|<=R+r)&&(|P|>=R-r))
在测试完所有球体之后,您在表面上有非交叉区域的地图