Скажите, принадлежит ли точка лучу в трехмерном пространстве

У меня есть эта проблема: проверьте, принадлежит ли точка лучу в 3D. После некоторых математических исследований я закодировал решение, но, похоже, оно просто не работает. Вот иллюстрация. P — это точка. E - конечная точка луча. V - вектор направления луча.

double x, y, z, e1, e2, e3, v1, v2, v3, d, xVectorFromEToP, 
dirVectorMagnitude,  vectorEPMagnitude, yVectorFromEToP, zVectorFromEToP, 
cpX, cpY, cpZ;
cin >> x >> y >> z >> e1 >> e2 >> e3 >> v1 >> v2 >> v3;

// HERE I'M FORMING THE EP vector - from point P to end-point E

xVectorFromEToP = x - e1;
yVectorFromEToP = y - e2;
zVectorFromEToP = z - e3; 

//HERE I'M CALCULATING CROSS-PRODUCT of THE VECTORS: EP and V

cpX = ((v2 * zVectorFromEToP) - (v3 * yVectorFromEToP));
cpY = ((v1 * zVectorFromEToP) - (v3 * xVectorFromEToP)) * -1;
cpZ = ((v1 * yVectorFromEToP) - (v2 * xVectorFromEToP)); 

// HERE I'M CALCULATING MAGNITUDES OF THOSE VECTORS AND DEBUGGING IN COUT

vectorsEpVMagnitude = sqrt(pow(cpX, 2) + pow(cpY, 2) + pow(cpZ, 2));
dirVectorMagnitude = sqrt(pow(v1, 2) + pow(v2, 2) + pow(v3, 2));

cout << "EP: " << vectorsEpVMagnitude << endl;
cout << "dir: " << dirVectorMagnitude << endl;

// final formula for calculating distance

d = vectorsEpVMagnitude / dirVectorMagnitude;

// precision is 1e-8: 1 means belong, otherwise - 0;

if (d < 1e-8) {
    cout << "distance: " << d << endl;
    cout << 1;
} else {
    cout << "distance: " << d << endl;
    cout << 0;
}

У меня есть образцы входных данных: 1) P (2,0 1,0 0,0), E (2,0 1,0 1,0), V (0,0 0,0 1,0) должно быть 0;

2) P(2.0 1.0 0.0), E(2.0 1.0 1.0), V(0.0 0.0 -1.0) должны быть равны 1!

Однако оба они имеют расстояние, равное 0, в то время как, как указано, они должны иметь разное расстояние. Буду признателен за любую помощь, разъяснения и т.


person Monstryyy    schedule 03.08.2017    source источник
comment
так как я понимаю ваше описание, вы хотите сказать, находится ли точка P на линии, образованной точкой E и вектором V, это правильно? Ваш результат всегда равен 0, потому что выбранная вами буква E находится на линии. Таким образом, перекрестное произведение, которое вы вычисляете, всегда равно нулю, потому что векторы имеют одинаковое направление.   -  person Amir Schnell    schedule 03.08.2017
comment
Я предлагаю вам узнать, что означает каждая переменная. Затем выполните расчеты на бумаге и сверьтесь со значениями из алгоритма.   -  person Sergei    schedule 03.08.2017
comment
@AmirKrasnic Я рассчитываю расстояние: если оно равно 0, то точка находится на луче (линия от точки E до вечности в направлении вектора V). На самом деле я сначала сделал это на бумаге, но, думаю, мне просто не хватает концепции. Так или иначе..   -  person Monstryyy    schedule 03.08.2017
comment
ваш второй пример также должен быть 0, потому что он полностью такой же, как и первый, только вектор имеет противоположное направление. но точка по-прежнему лежит на луче, поэтому расстояние равно 0.   -  person Amir Schnell    schedule 03.08.2017


Ответы (1)


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

Редактировать: обратите внимание, что точка лежит на луче во втором случае, а не в первом случае, как заметил Амир Красник в комментариях.

Чтобы проверить, лежит ли проекция P на луче, вычислите скалярное (точечное) произведение EP и V и посмотрите на его знак.

Если он положительный, то проекция P лежит на луче, и d = vectorsEpVMagnitude / dirVectorMagnitude; является действительным результатом.

Если отрицательное - точка лежит в стороне от луча (позади?), в этом случае просто вычисляем длину EP

person MBo    schedule 03.08.2017
comment
большое спасибо, очень полезно, немного прояснил для меня! К сожалению, только 4 из 10 тестовых случаев прошли успешно. Это моя измененная версия, основанная на вашем совете по поводу точечного продукта. - person Monstryyy; 03.08.2017
comment
Кажется, вы выводите 0 только тогда, когда точка отрицательна, но ничего для случая d >= 1e-8 - person MBo; 03.08.2017
comment
Омг, я действительно проглядел это. К сожалению, ха, сейчас 9/10. Извините за беспокойство, вы на самом деле очень помогли, но один случай не работает, и я даже не могу понять, в чем здесь пограничный случай.. О, dotProductEpV >= 0 действительно прав? Потому что каким-то образом я представил dotProductEpV > 0 вместо этого. - person Monstryyy; 03.08.2017
comment
dotProductEpV=0 означает, что P лежит в плоскости, содержащей точку P и перпендикулярной V. Как рассматривать этот случай - on ray или off ray - зависит от ваших потребностей. Вам больше подходит dotProductEpV > 0 - person MBo; 04.08.2017