How do I pick the correct ring when ray casting?

Started by
22 comments, last by Spa8nky 12 years, 9 months ago
I have 3 rings (red, green, blue) around my object in the GUI:

Rings.png


I am currently performing a ray cast from the mouse onto a sphere and obtaining the collision point.

How can I then determine which of the 3 rings the collision point is closest to in order to select that ring?

Or would this be better approached as a ray cast against 3 separate circles?
Advertisement
I don't think you'd want to intersect the circles themselves, imagine you were looking straight on so that one of the circles was completely perpendicular to the screen making it impossible to reliably select it with mouse (corresponding to say spinning it around) that'd be a bit counter-intuitive

You could just subtract the centre of the object from the intersection point, and project onto each circle axis to choose the nearest i guess.

[color="#1C2837"]I don't think you'd want to intersect the circles themselves, imagine you were looking straight on so that one of the circles was completely perpendicular to the screen making it impossible to reliably select it with mouse (corresponding to say spinning it around) that'd be a bit counter-intuitive


I didn't think of that, thank you for pointing that out.

You could just subtract the centre of the object from the intersection point, and project onto each circle axis to choose the nearest i guess.


That doesn't work as intended unfortunately:



public bool TestRayAgainst(CollisionDetection.Ray ray, ref Contact3D contact)
{
int index = -1;
Contact3D c = new Contact3D();

if (TestStaticRaySphere(ray, boundingSphere, ref c))
{
contact.isColliding = c.isColliding;
contact.isIntersecting = c.isIntersecting;
contact.nEnter = c.nEnter;
contact.nExit = c.nExit;
contact.objects = c.objects;
contact.penetration = c.penetration;
contact.point = c.point;
contact.tEnter = c.tEnter;
contact.tExit = c.tExit;

// Subtract the sphere centre from the intersection point
Vector3 p = c.point - boundingSphere.Position;

index = MathTools.Max3Index(
Math.Abs(Vector3.Dot(p, Vector3.UnitX)), // 0
Math.Abs(Vector3.Dot(p, Vector3.UnitY)), // 1
Math.Abs(Vector3.Dot(p, Vector3.UnitZ)) // 2
);
}

switch (index)
{
case -1:
{
SetGrabStateNone();
return false;
}
case 0:
{
SetGrabStateX();
return true;
}
case 1:
{
SetGrabStateY();
return true;
}
case 2:
{
SetGrabStateZ();
return true;
}
default:
return false;
}
}


The correct ring isn't selected when projecting the contact point onto each axis. The contact point and collision detection is correct as I can draw where the contact point is, on the surface of the sphere, each time I perform a mouse cursor ray cast.

Any ideas?
I think you want to find the distance from your contact point to each of the 3 axis planes, and select the minimum, not the maximum.

For example, if you take the "x axis (green) control" in your picture - the point on the sphere is closest to that circle when dot( point-center, normal ) == 0, where the normal for the x plane is the y axis

EDIT: changed "point" to "point-center"
Well you should be choosing the minimum projection ;)

[color=#1C2837][size=2]Well you should be choosing the minimum projection ;)
[color=#1C2837][size=2][/quote]
[color="#1c2837"]

[color=#1C2837][size=2][color=#000000] index [color=#666600]=[color=#000000] [color=#660066]MathTools[color=#666600].[color=#660066]Min3Index[color=#666600]([color=#000000]
[color=#660066]Math[color=#666600].[color=#660066]Abs[color=#666600]([color=#660066]Vector3[color=#666600].[color=#660066]Dot[color=#666600]([color=#000000]p[color=#666600],[color=#000000] [color=#660066]Vector3[color=#666600].[color=#660066]UnitX[color=#666600])),[color=#000000] [color=#880000]// 0[color=#000000]
[color=#660066]Math[color=#666600].[color=#660066]Abs[color=#666600]([color=#660066]Vector3[color=#666600].[color=#660066]Dot[color=#666600]([color=#000000]p[color=#666600],[color=#000000] [color=#660066]Vector3[color=#666600].[color=#660066]UnitY[color=#666600])),[color=#000000] [color=#880000]// 1[color=#000000]
[color=#660066]Math[color=#666600].[color=#660066]Abs[color=#666600]([color=#660066]Vector3[color=#666600].[color=#660066]Dot[color=#666600]([color=#000000]p[color=#666600],[color=#000000] [color=#660066]Vector3[color=#666600].[color=#660066]UnitZ[color=#666600]))[color=#000000] [color=#880000]// 2[color=#000000]
[color=#666600]);
[color=#1C2837][size=2]

[color="#1c2837"]That works better, thank you. :)
[color="#1c2837"]

[color="#1c2837"]There are still situations where the incorrect axis is chosen:
[color="#1c2837"]

[color="#1c2837"]IncorrectAxisChosen.png

[color="#1c2837"]

[color="#1c2837"]The mouse is clicking on the blue ring (normal = (0,0,1) but the red ring is selected (normal = (1, 0, 0).
[color="#1c2837"]

[color="#1c2837"]What might be going on here?
[color="#1c2837"]
you might be clicking the blue ring, but the intersection with the sphere which you test is closer to the other, which also seems clear from your picture.

--edit: perhaps you should instead be looking for the closest circle based on their 2d projections instead?

This would be equivalent to finding the distance from the point to the border of each ellipse; or in 3d, the distance between the unprojected mouse coordinate ray, to each circle


[color="#1c2837"]The mouse is clicking on the blue ring (normal = (0,0,1) but the red ring is selected (normal = (1, 0, 0).

[color="#1c2837"]What might be going on here?




What is the coordinate for the point, and the value of each projection?

you might be clicking the blue ring, but the intersection with the sphere which you test is closer to the other, which also seems clear from your picture.

--edit: perhaps you should instead be looking for the closest circle based on their 2d projections instead?

This would be equivalent to finding the distance from the point to the border of each ellipse; or in 3d, the distance between the unprojected mouse coordinate ray, to each circle


Indeed. Intersect the mouse ray with each plane instead of the sphere

What is the coordinate for the point, and the value of each projection?
[/quote]

Point = {X:-1.884914 Y:3.893975 Z:8.819122}
Sphere Position = {X:-1.1665 Y:2.148515 Z:7.9195}

Point - Sphere Position = {X:-0.7184134 Y:1.74546 Z:0.899622}

Projection onto X axis (Absolute value) = 0.718413353
Projection onto Y axis (Absolute value) = 1.74545956
Projection onto Z axis (Absolute value) = 0.899621964

This topic is closed to new replies.

Advertisement