Issues with finding a point on a ray

Started by
2 comments, last by robert_porter 14 years, 1 month ago
Hi, I will say first, im using this code in an arcball style camera. I have a function that does a ray/sphere intersection test, which works fine. If the ray misses, I needed to map the position to the closest point on the sphere from the ray. It works to an extent, but the issue is that it seems 'slightly' off. If I am moving the mouse outside of the sphere is seems to rotate a tiny bit towards the camera as i move the mouse further out. It seems like the intersect direction is slightly wrong? The code im using is below, if anyone had any advice I would be very greatful. Thanks.

...
        // if this 'if' check succeeds that means the ray missed and I need to find the closest point on the sphere to map 'loc' to
        // 'direction' is the direction of the ray
        // '-a' is the direciton of the cam to the centre of the sphere
        // 'radius' is the radius of the sphere
        if (det < 0)
	{
		NiPoint3 a = CamPos; a.Unitize();
		double t = (-a).Dot(direction) / direction.SqrLength();
		NiPoint3 intersectVec = -a - (direction * t);
		intersectVec.Unitize();
		loc = -a - intersectVec * radius;

		return false;
	}
...
Advertisement


Wouldn't it be

loc = -CamPos - intersectVec * radius;

because a is normalized
Ahh, oops, thanks, yes thats fixes a different issue I had with it (not rotating the correct amount while moving around outside). The intersect vec still seems to be slightly off though.

I know its because I am not calculating t correctly. The ray (direction * t) part needs to produce a vector with a length that would be slightly larger (?) than -a's length. So that when the vectors are subtracted it would give a vector orthogonal to -a, but going in the direction of the ray.

Any tips on a correct way to get this value?

Thanks.
I'm sort of confused why you are defining your rays as origin - t*direction
rather than origin + t*direction, but as long as your consistant I guess it doesn't matter.

Well I think same problem as before with this line

NiPoint3 intersectVec = -a - (direction * t);

I believe it should be

CamPos - direction * t

This would be the point on the ray closest to the circle, I going to rename it because the name confuses me.

pointOnRay = CamPos - direction * t

Then you want the direction from the center of the sphere to the ray
(I'm assuming you circle is at (0,0,0)), but if the center of the sphere is (0,0,0) you allready have it.

So the point on the surface of the sphere is

sphereCenter + radius * pointOnRay / |pointOnRay|

or since sphereCenter = (0,0,0)

radius * pointOnRay / |pointOnRay|



This topic is closed to new replies.

Advertisement