1

I have this problem: verify if point belongs to ray in 3D. After some math research, I've coded the solution, but it seems that it just doesn't work. That's the illustration. P is the point. E - the end-point of ray. V - directional vector of the ray.

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;
}

I have sample inputs: 1) P(2.0 1.0 0.0), E(2.0 1.0 1.0), V(0.0 0.0 1.0) should be 0;

2) P(2.0 1.0 0.0), E(2.0 1.0 1.0), V(0.0 0.0 -1.0) should be 1!

However both of them have distance equal to 0, while as stated they should have different distance. I would appreciate any help, clarification, etc.

Monstryyy
  • 81
  • 9
  • so as i understand your description you want to tell if the Point P is on the line that is formed by the Point E and the vector V is that correct? Your result is always 0 because the E you choose is on the line. So The cross product you calculate is always zero because the vecors have the same direction – Amir Schnell Aug 03 '17 at 15:12
  • I'd suggest you learn what each variable means. Then do the calculations on paper and cross check with the values from the algorithm. – Sergei Aug 03 '17 at 15:14
  • @AmirKrasnic I calculate the distance: if its 0, then point is on the ray (line from point E to eternity in the direction of the vector V). I actually did it on paper firstly, but I guess I'm just missing the concept. Anyway.. – Monstryyy Aug 03 '17 at 15:23
  • 2
    your second example should also be 0 because it is completely the same as the first only the vector has the opposite direction. but the point still lies on the ray so the distance is 0. – Amir Schnell Aug 03 '17 at 15:30

1 Answers1

3

Your code calculates distance to infinite line (it looks fine), so in the both cases point lies on the line (essentially it is the same line).

Edit: Note that point lies on the ray in the second case, not in the first case, as Amir Krasnic noticed in comments.

To check whether projection of P lies on the ray, calculate scalar (dot) product of EP and V and look at its sign.

If it is positive, then projection of P lies on the ray, and d = vectorsEpVMagnitude / dirVectorMagnitude; is valid result

If negative - point lies back from the ray (behind?), in this case just calculate EP length

MBo
  • 77,366
  • 5
  • 53
  • 86
  • much thx, very helpful, clarified it a bit for me! Unfortunately, only 4/10 test cases passed good. [This](https://pastebin.com/NFCMQQ1j) is mine modified version based on your advice about dot product. – Monstryyy Aug 03 '17 at 19:18
  • Seems you output 0 only when dot is negative, but nothing for case `d >= 1e-8` – MBo Aug 03 '17 at 20:05
  • Omg, I really overlooked that. Unfortunately, hah, it's 9/10 now. Sorry for bothering you actually did help a lot, but one case is failing and I can't even figure what is the edge case here.. Oh, is `dotProductEpV >= 0` actually right? Cause somehow I've submitted `dotProductEpV > 0` instead. – Monstryyy Aug 03 '17 at 20:25
  • `dotProductEpV=0` denotes that P lies in the plane, containing point P and perpendicular to V. How to consider that case - `on ray` or `off ray` - depends on your needs. Seems that `dotProductEpV > 0` is more suitable for you – MBo Aug 04 '17 at 04:18