В декартовом трехмерном пространстве у меня есть сфера в XYZ с радиусом 240 (основная сфера), внутри этой сферы находится множество других сфер с радиусом 100 (другие объекты). Мне нужно найти точки вдоль границы пограничной сферы, которые не пересекаются НИКАКИМИ другими объектами внутри нее.
Для простоты мы можем сказать, что основная сфера находится в 0 0 0 с радиусом 240, а внутри находится ~ 33 объекта, каждый с радиусом 100 в разных координатах.
В основном пишу на Lua, но C / C ++ тоже подойдет. Любая помощь приветствуется, даже если она просто указывает мне правильное направление математического решения.
Изменить: используя ссылки и информацию, предоставленные Дэвидом Эйзенстатом ниже, это код, который я использую. Он / кажется / работает, но у меня не было возможности полностью его протестировать.
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()
2 ответа
Вероятно, самый простой подход - произвольно генерировать точки на границе основной сферы и проверить их на пересечение с исключенными шарами а>. Структуры близости (например, kd-деревья) помогли бы асимптотически проверять пересечение, но вряд ли это стоит того для 33 объектов. Вычисление диаграммы Вороного также может быть решением, но диаграмма Вороного круговых ограниченных областей на сфера будет необычной настройкой и, вероятно, потребует изрядного количества нового сложного кода.
создать карту поверхности основной сферы
- например:
const int na=128;
const int nb=256;
int map[na][nb];
- поэтому map[a][b] представляет собой площадь поверхности вокруг a (широта), b (долгота)
проверьте все свои маленькие сферы, если они пересекают основную сферу
- если главная сфера находится в
(0,0,0)
радиусеR
- затем сфера в
P (x,y,z)
радиусомr
- пересекать основную сферу, если
if ((|P|<=R+r)&&(|P|>=R-r))
- в этом случае вычислить широту и долготу по точке P (см. сферическую систему координат)
- переназначить его на a,b из радианов в размеры na,nb
- и пометить карту[a][b] (плюс ее окружение до радиуса r) как пересеченную
- если главная сфера находится в
после тестирования всех сфер у вас есть карта непересекающихся областей на поверхности
Похожие вопросы
Связанные вопросы
Новые вопросы
c++
C++ — это язык программирования общего назначения. Изначально он разрабатывался как расширение C и имел аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде, который будет скомпилирован с помощью компилятора C++. Используйте тег версии для вопросов, связанных с конкретной стандартной версией [C++11], [C++14], [C++17], [C++20] или [C++23]. и т.д.