Sign in to follow this  

line circle

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

What would a function in C++ to pick the two points on a circle that a line intersects with look like? I've had some trouble converting this from maths speak into C++. I've got something like this: bool line_vs_circle(vec2 & contact_point, circle * c, line * l); The function needs to return true if a collision occured and false if not, and the variable contact_point needs to be the closest point of contact, if there was any collision. Can anybody show me some psudocode to do this? Thanks.

Share this post


Link to post
Share on other sites

#define FLT_EPSILON ( 0.000001f )

//-----------------------------------------------------------------------------
// Input : circle origin and radius, line start and end...
// Output: circle hit point, parameter t at line segment
// Returns : true if collision occured, false if not...
//-----------------------------------------------------------------------------
static bool SegmentCircleIntersect( Vector &origin, float radius, Vector vSrc, Vector vEnd, Vector &vHit, float &t )
{
t = 1.0f;

Vector delta = vEnd - vSrc;
Vector dist = vSrc - origin;
// LenSqr = dist.x^2 * dist.y^2
if ( dist.LenSqr() <= square(radius+1.0f) )
{
return false; // line seg start point is inside a circle
}

//Compute A, B and C coefficients
float a = Dot(delta, delta); // dotproduct
float b = 2.0f * Dot( delta, dist );
float c = Dot(dist, dist) - square(radius);

//Find discriminant
float disc = b * b - 4.0f * a * c;

// if discriminant is negative there are no real roots, so return
// false as line seg misses sphere
if ( fabsf(disc) < FLT_EPSILON )
return false;

// compute q as described above
float distSqrt = sqrtf(disc);
float q;
if ( fabsf(b) < FLT_EPSILON )
q = (-b - distSqrt)/2.0f;
else
q = (-b + distSqrt)/2.0f;

// compute t0 and t1
float t0 = q / a;
float t1 = c / q;

// make sure t0 is smaller than t1
if (t0 > t1)
{
// if t0 is bigger than t1 swap them around
swap(t0,t1);
}

// if t1 is less than zero, the object is in the line negative direction
// and consequently the line misses the sphere
if (t1 < 0.0f)
return false;

// if t0 is less than zero, the intersection point is at t1
if (t0 < 0){ t = t1; }
// else the intersection point is at t0
else { t = t0; }

vHit = vSrc + delta * t;

return true;
}

Share this post


Link to post
Share on other sites
vHit is a intersection point.
t represents a parameter for line segment.

if vSrc is (0,0) and vEnd is (5,10) so then, if you receive t from funtion and then see that t is 0.5, so it mean that intersection point is lying in center of line segment. t computes in range [0,1]

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

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