В декартовом трехмерном пространстве у меня есть сфера в 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()
0
Mike Taylor 21 Авг 2014 в 21:52

2 ответа

Лучший ответ

Вероятно, самый простой подход - произвольно генерировать точки на границе основной сферы и проверить их на пересечение с исключенными шарами . Структуры близости (например, kd-деревья) помогли бы асимптотически проверять пересечение, но вряд ли это стоит того для 33 объектов. Вычисление диаграммы Вороного также может быть решением, но диаграмма Вороного круговых ограниченных областей на сфера будет необычной настройкой и, вероятно, потребует изрядного количества нового сложного кода.

0
Community 23 Май 2017 в 14:57
 – 
lhf
21 Авг 2014 в 23:07
Итак, используя вашу идею и предоставленные ссылки, я написал код для генерации (до) 1000 случайных точек вдоль поверхности основной сферы, а затем проверки расстояния между каждой точкой и каждым объектом, если какие-либо объекты находятся в пределах диапазона ( 100), он пропускает эту точку и пробует новую. Будет ли это работать?
 – 
Mike Taylor
22 Авг 2014 в 05:13
После выбора случайной точки и нахождения пересечения одним из вариантов было бы найти круг, обозначающий границу пересечения, и выбрать в качестве следующей случайной точки где-то сразу за этой границей. Я не знаю, является ли это лучшей стратегией, поэтому я мог бы перейти сразу за границу с вероятностью одна половина и выбрать совершенно случайную точку, как и раньше, с вероятностью одна половина.
 – 
mcdowella
22 Авг 2014 в 08:55
  1. создать карту поверхности основной сферы

    • например:
    • const int na=128;
    • const int nb=256;
    • int map[na][nb];
    • поэтому map[a][b] представляет собой площадь поверхности вокруг a (широта), b (долгота)
  2. проверьте все свои маленькие сферы, если они пересекают основную сферу

    • если главная сфера находится в (0,0,0) радиусе R
    • затем сфера в P (x,y,z) радиусом r
    • пересекать основную сферу, если
    • if ((|P|<=R+r)&&(|P|>=R-r))
    • в этом случае вычислить широту и долготу по точке P (см. сферическую систему координат)
    • переназначить его на a,b из радианов в размеры na,nb
    • и пометить карту[a][b] (плюс ее окружение до радиуса r) как пересеченную
  3. после тестирования всех сфер у вас есть карта непересекающихся областей на поверхности

0
Spektre 21 Авг 2014 в 22:20