#algorithm #language-agnostic
#алгоритм #язык не зависит
Вопрос:
У меня есть эта проблема, которую я не могу решить, и мне нужна помощь. Проблема заключается в подсчете количества воздушных шаров, пораженных дробовиком. Позиции воздушных шаров описываются трехмерными координатами (X, Y, Z) и радиусом R. Выстрел определяется трехмерным расположением конца ствола «p» (Px, Py, Pz) и вектором «v» (Vx, Vy, Vz), описывающим направление, на которое указывает ствол.
Я попытался реализовать решение, предложенное здесь: https://math.stackexchange.com/questions/1939423/calculate-if-vector-intersects-sphere
// C = center of sphere
// r = radius of sphere
// P = point on line
// U = unit vector in direction of line
Q = P - C;
a = U*U; // should be = 1
b = 2*U*Q
c = Q*Q - r*r;
d = b*b - 4*a*c; // discriminant of quadratic
if d < 0 then solutions are complex, so no intersections
if d >= 0 then solutions are real, so there are intersections
Но проблема в том, что я получаю пересечение с воздушными шарами, которые расположены за пистолетом. Как я могу изменить этот алгоритм, чтобы получить правильный результат? Или мой подход может быть неправильным?
Комментарии:
1. Как вы представляете точки и векторы?
2. Я предлагаю вам задать свой вопрос об обмене математическим стеком, поскольку это в основном математический вопрос.
3. Кроме того, вы можете проверить, что скалярное произведение между
v
иballoon - p
больше нуля, что означает, что их угол <90 градусов.4. Точка представлена вещественными числовыми значениями x, y, z. Вектор также представлен вещественными числовыми значениями x, y, z. Все координаты выстрела находятся в диапазоне [-10,10].
Ответ №1:
Вам нужно фактически решить квадратное уравнение, определяемое вашими переменными a, b и c. Часто для этого существуют математические библиотеки, что-то вроде:
(t1,t2) = QuadraticSolve(a, b, c);
Вы также можете сделать это вручную для каждого параметра:
t1 = (-b sqrt(b*b - 4*a*c)) / (2*a)
t2 = (-b - sqrt(b*b - 4*a*c)) / (2*a)
Если t1 или t2 положительные, то это пересечение находится перед вашим пистолетом.