• 14
• 14
• 9
• 10
• 9

# How do I pick the correct ring when ray casting?

This topic is 2438 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have 3 rings (red, green, blue) around my object in the GUI:

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?

##### Share on other sites
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.

##### Share on other sites

[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?

##### Share on other sites
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" Edited by rdragon1

##### Share on other sites
Well you should be choosing the minimum projection ;)

##### Share on other sites

[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"]

[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"]

##### Share on other sites
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

##### Share on other sites

[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?

##### Share on other sites

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

##### Share on other sites

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