I have a point inside a circle and another point outside a circle. I want find the point where the line intersects the circle. How can i do that in windows phone 8. Please give me any idea.
This is both a simple and complex problem and a lot depends on what you mean. I'm taking from your opening post that you are talking about a Line Segment and not a true (infinite) line.
In this case you have several cases to work out. The intersection only happens when one point is inside the circle and one point is outside the circle. The algorithm below does not catch cases where
These are lumped into the "no intersection" result. This only handles the case of strictly one point inside and one point outside the circle.
First you need a few auxiliary functions. These use basic geometry to determine whether or not a point is inside or outside the circle (points on the circle are counted as "outside"), and whether or not two points form a line segment that intersects a circle.
private bool IsInsideCircle(Point CirclePos, float CircleRad, Point checkPoint)
{
if (Math.Sqrt(Math.Pow((CirclePos.X - checkPoint.X), 2) +
Math.Pow((CirclePos.Y - checkPoint.Y), 2)) < CircleRad)
{ return true; } else return false;
}
private bool IsIntersecting(Point CirclePos, float CircleRad, Point LineStart,
Point LineEnd)
{
if (IsInsideCircle(CirclePos, CircleRad, LineStart) ^
IsInsideCircle(CirclePos, CircleRad, LineEnd))
{ return true; } else return false;
}
Note the use of ^
(Exclusive OR) - we want one point inside and one point outside exactly.
With this, we can work into the bigger function :
private int Intersect (Point CirclePos, float CircleRad,
Point LineStart, Point LineEnd, ref Point Intersection)
{
if (IsIntersecting(CirclePos, CircleRad, LineStart, LineEnd))
{
//Calculate terms of the linear and quadratic equations
var M = (LineEnd.Y - LineStart.Y) / (LineEnd.X - LineStart.X);
var B = LineStart.Y - M * LineStart.X;
var a = 1 + M*M;
var b = 2 * (M*B - M*CirclePos.Y - CirclePos.X);
var c = CirclePos.X * CirclePos.X + B * B + CirclePos.Y * CirclePos.Y -
CircleRad * CircleRad - 2 * B * CirclePos.Y;
// solve quadratic equation
var sqRtTerm = Math.Sqrt(b * b - 4 * a * c);
var x = ((-b) + sqRtTerm)/(2*a);
// make sure we have the correct root for our line segment
if ((x < Math.Min(LineStart.X, LineEnd.X) ||
(x > Math.Max(LineStart.X, LineEnd.X))))
{ x = ((-b) - sqRtTerm) / (2 * a); }
//solve for the y-component
var y = M * x + B;
// Intersection Calculated
Intersection = new Point(x, y);
return 0;
} else {
// Line segment does not intersect at one point. It is either
// fully outside, fully inside, intersects at two points, is
// tangential to, or one or more points is exactly on the
// circle radius.
Intersection = new Point(0, 0);
return -1;
}
}
This function takes the intersection point as a ref
parameter and returns either -1
(no intersection) or 0
(intersection found). I used an int
return value in case you want to extend this to differentiate the edge cases. The intersection is calculated from elementary geometry - remember that a line is expressed as (see : Slope Intercept and Point Slope Form )
and a circle (centered at (C.x, C.y)
with radius r
) is
You solve this system of equations by substitution :
Expanding and collecting terms you get :
This is a standard quadratic equation of the form
Which can be solved by the quadratic formula (see : Quadratic Formula ):
This gives two roots for the infinite line on which our line segment lies - we do a final check above to make sure that we choose the solution for our specific line segment.
This is why paying attention in math class is important!
Now... depending on what you are doing, there are LOTS of ways to optimize this. The above solution outlines the basic method but there is room, certainly, to do this more quickly if you need to. Obviously, also, the parameters can be adjusted to whatever type of points or objects you are using. I tried to make it as general as possible.
Also, to show an example of how this would be called :
Point iPt = new Point();
var rslt = Intersect(new Point(2,3), 5.0f, new Point(2,2),
new Point(8,6), ref iPt);
if (rslt == 0) {
MessageBox.Show(String.Format("Intersection at: x = {0}, y = {1}",
iPt.X, iPt.Y));
}
else {
MessageBox.Show("No Intersection");
}