Сначала давайте взглянем на диаграмму для справки:
Процедура расчета H1
и H2
выглядит следующим образом:
- Вычислить пересечение, если оно есть, между лучом
R
и отрезком линии P1P2
.Нас интересуют только пересечения, которые лежат внутри P1P2
.Аналогично для P3P4
.Точки от P1
до P4
могут быть легко вычислены из центров окружностей, C1
и C2
и некоторой векторной математики.Например, P1 = C1 + r*nC
, где nC
- нормаль (CCW) единичного вектора от C1
до C2
.Этот ответ о SO обеспечивает необходимую математику для определения, существует ли пересечение между двумя отрезками линии, и, если это так, вычисляет параметр h
, такой, что H=R1+h(R2-R1)
, где H
- точка пересечения,На этом шаге можно получить 0, 1 или 2 действительных значения h
, в зависимости от того, пересекает ли луч ни один, ни один, или оба из P1P2
, P3P4
. - Вычислить точки пересечения, если таковые имеютсямежду лучом и каждым из двух кругов.Опять же, SO ответ предоставляет необходимую математику для пересечения луча с окружностью.Каждый круг может иметь пересечения 0, 1 или 2, которые снова представлены параметрически.
- Если на этапах 1 и 2 не было сгенерировано действительных значений
h
, то луч не пересекает капсулу.В противном случае вычислите hMin
и hMax
, минимальные и максимальные значения параметров всех действительных пересечений, определенных в шагах 1 и 2. Обратите внимание, что возможно, что hMin==hMax
, в случае, когда луч касается одной из окружностейи не пересекается P1P2
или P3P4
.Требуемая точка (точки) пересечения теперь может быть вычислена как H1=R1+hMin(R2-R1)
и H2=R1+hMax(R2-R1)
.
Боюсь, что мой язык выбора - Java, а не C ++, но, надеюсь, вы найдетеКод ( IDEOne ) Я собрал полезные в качестве ссылки.Обратите внимание, что не было предпринято никаких усилий для решения проблем надежности, возникающих в результате округления значений double
во время вычислений.