Проверка того, пересекает ли линейный сегмент сферу

Я пытаюсь определить, пересекает ли линейный сегмент (т.е. между двумя точками) сферу. Меня не интересует положение пересечения, просто пересекает ли сегмент поверхность сферы. Есть ли у кого-нибудь предложения относительно того, какой алгоритм для этого будет наиболее эффективным? (Мне интересно, есть ли какие-либо алгоритмы, которые проще, чем обычные алгоритмы пересечения лучевой сферы, поскольку меня не интересует положение пересечения)


person astrofrog    schedule 14.01.2010    source источник
comment
Вы действительно имеете в виду отрезок линии или бесконечную линию? Все ответы относятся к бесконечным линиям.   -  person letmaik    schedule 20.08.2014


Ответы (4)


Я не знаю, что это за стандартный способ, но если вы хотите знать, пересекается ли оно, вот что я бы сделал.

Общее правило ... избегайте выполнения sqrt () или других дорогостоящих операций. По возможности работайте с квадратом радиуса.

  1. Определите, находится ли начальная точка внутри радиуса сферы. Если вы знаете, что это не так, пропустите этот шаг. Если вы внутри, ваш луч пересечет сферу.

С этого момента ваша отправная точка находится за пределами сферы.

  1. Теперь представьте себе маленькую коробку, которая уместится в сфере. Если вы находитесь за пределами этого поля, проверьте направление x, y и z луча, чтобы увидеть, будет ли он пересекать сторону прямоугольника, с которой начинается ваш луч. Это должна быть простая проверка знаков или сравнение с нулем. Если вы находитесь вне и удаляетесь от него, вы никогда не пересечете его.

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

Суть того, что вы хотите сделать, это определить, меньше ли кратчайшее расстояние между вашим лучом и сферой, чем радиус сферы.

Пусть ваш луч представлен в виде (x0 + i t, y0 + j t, z0 + k t), а центр вашей сферы находится в точке (xS, yS, zS). Итак, мы хотим найти t такое, чтобы получить наименьшее из (xS - x0 - i t, yS - y0 - j t, zS - z0 - k t).

Пусть x = xS - x0, y = yX - y0, z = zS - z0, D = величина вектора в квадрате

D = x^2 -2*xit + (i*t)^2 + y^2 - 2*yjt + (j*t)^2 + z^2 - 2*zkt + (k*t)^2

D = (i^2 + j^2 + k^2)t^2 - (xi + yj + zk)*2*t + (x^2 + y^2 + z^2)

dD/dt = 0 = 2*t*(i^2 + j^2 + k^2) - 2*(xi + yj + z*k)

t = (xi + yj + z*k) / (i^2 + j^2 + k^2)

Подставьте t обратно в уравнение для D = .... Если результат меньше или равен квадрату радиуса сферы, у вас есть пересечение. Если больше, то пересечения нет.

person Sparky    schedule 14.01.2010

Если вас интересует только знание того, пересекается ли он или нет, тогда ваш основной алгоритм будет выглядеть так ...

Предположим, у вас есть вектор лучевой линии, A -> B.

Вы знаете, что кратчайшее расстояние между этим вектором и центром сферы находится на пересечении вашего вектора луча и вектора, который находится под углом 90 градусов к этому вектору, который проходит через центр сферы.

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

person Cruachan    schedule 14.01.2010
comment
Это единственный правильный ответ на этот пост. Все остальные слишком сложны. - person FeepingCreature; 08.11.2011
comment
Спасибо за это. Некоторое время я качал головой над другими ответами с более высоким рейтингом на этой странице. Особенно те, которые начинаются со слов «Я не знаю стандартного способа сделать это», когда ответ, который я даю, является стандартным способом сделать это :-) - person Cruachan; 08.11.2011
comment
Этот ответ дает вам момент ага, который вы, вероятно, ищете. - person allen1; 07.08.2018
comment
Нет, это неправильный ответ, это действительно только для строки. Вопрос явно требует отрезка прямой между двумя точками. - person credondo; 17.08.2020

На этой странице есть точное решение этой проблемы. По сути, вы подставляете уравнение для линии в уравнение для сферы, а затем вычисляете дискриминант полученной квадратичной кривой. Значения дискриминанта указывают на пересечение.

person plinth    schedule 14.01.2010
comment
Спасибо, я нашел это уравнение где-то еще без особого или какого-либо объяснения того, что оно делает, приятно получить небольшое объяснение. - person David; 16.04.2010
comment
Обновился до живой ссылки. - person plinth; 24.01.2014

вы все равно должны работать с этой позицией, если хотите точности. Единственный способ алгоритмически улучшить скорость - это переключиться с пересечения лучевой сферы на пересечение лучевого ограничивающего прямоугольника.

Или вы можете пойти глубже и попытаться улучшить sqrt и другие внутренние вызовы функций.

http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection

person CVertex    schedule 14.01.2010