Sign in to follow this  
PranKe01

[SOLVED] Point collision with cylinder

Recommended Posts

PranKe01    122
Hi guys,

I want to check, if a 3D-Point lies in a cylinder. I don't need any more information than true, or false :) But that isn't as easy, as I thought.
The Point got 3 coordinates: X, Y and Z. The Cylinder got following informations: startpoint, endpoint and the radius.

Right now I am calculating that for a rectangle in 2D space with following function:

[source lang="cpp"]

public static bool isBetweenPoints(Point3D point, Point3D lineStart, Point3D lineEnd) {
float deltaX = lineEnd.X - lineStart.X;
float deltaY = lineEnd.Y - lineStart.Y;
float deltaZ = lineEnd.Z - lineStart.Z;

float diagonalStartY = ((lineStart.X - point.X) * (deltaX / deltaY)) + lineStart.Y;
float diagonalEndY = ((lineEnd.X - point.X) * (deltaX / deltaY)) + lineEnd.Y;

if(deltaX / deltaY > 0) {
if(point.Y > diagonalEndY || point.Y < diagonalStartY) {
return false;
}
} else if(deltaX / deltaY < 0) {
if(point.Y < diagonalEndY || point.Y > diagonalStartY) {
return false;
}
} else {

}

return true;
}
[/source]


Here is a picture, which explains what I am doing above (I think you don't need to check the code).
[img]http://i.imgur.com/qzFWF.png[/img]


I don't think that friggling that code into 3D space would make much sense...
One idea I had ist to transform the 3D problem into a 2D problem, by rotating the point and cylinder, so that the point got the Z-value 0. But I don't know how I can manage this.

So any hints about (hopefully performant) check if a point lies in a cylinder OR how to rotate the cylinder and point, so that a 2D problem remains, would be great! :)

Thanks in advance!

Share this post


Link to post
Share on other sites
PranKe01    122
Code makes use of the Vector3D from namespace "System.Windows.Media.Media3D".

[code]
double radius = 10;


Vector3D m = Vector3D.substract(point, start);
Vector3D n = Vector3D.substract(end, start);
double s = Vector3D.DotProduct(m, n) / (n.Length * n.Length);
double t = Vector3D.CrossProduct(n, m).Length / n.Length;

if(0 <= s && s <= 1 && t <= radius){
return true;
}

return false;[/code]

Thanks luca :)

Share this post


Link to post
Share on other sites
PranKe01    122
That does not seem to work.

For example, I created following test case:

point: 10, 5, 0
start: 2, 2, 0
end: 10, 6, 0

With a radius of 10 this should return TRUE.
But with the above code, it returns FALSE.

The value of s in this case is 1.25! Note that n dot point returns 100 and the Length of n is 8.944. The value of t is 0.

The values of n are: x=8, y=4, z=0.<

Any hints, whats wrong?

Thanks :)

Share this post


Link to post
Share on other sites
PranKe01    122
It looks like it makes a defference, which of both points (start and end) are the start and the end.
So when calculating n, it is a different result, when calculating end-start and start-end!
I think the result should be independent from the two points!?

Share this post


Link to post
Share on other sites
that is because it should be

s = ((point - start) dot n) / ||n||^2
t = ||n cross (point - start)|| / ||n||

>.> i need to stop rushing things


(Fixed this in first response to avoid anyone trying out the wrong answer if they're looking for it too)

Share this post


Link to post
Share on other sites
PranKe01    122
Thank you!

Now it works. Changed the code in previous post, too ;)

[quote name='luca-deltodesco' timestamp='1307441954' post='4820458']
that is because it should be

s = ((point - start) dot n) / ||n||^2
t = ||n cross (point - start)|| / ||n||

>.> i need to stop rushing things


(Fixed this in first response to avoid anyone trying out the wrong answer if they're looking for it too)
[/quote]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this