public static IntersectionResult CircleLine(GCircle circle, GLine line) { var result = new IntersectionResult(); float a, b, c, d, sqrt_d, t1, t2; PointF v; v = line.EndPoint.Sub(line.StartPoint); a = v.Dot(v); b = 2 * v.Dot(line.StartPoint.Sub(circle.Center)); c = line.StartPoint.Dot(line.StartPoint) + circle.Center.Dot(circle.Center) - 2 * line.StartPoint.Dot(circle.Center) - circle.Radius * circle.Radius; d = b * b - 4 * a * c; // no intersection if (d < 0) { return(result); } // the line tangent to the circle else if (d <= .0000001) { t1 = -b / (2 * a); result.IntersectionType = IntersectionType.Tangent; var p1 = new PointF(line.StartPoint.X + t1 * v.X, line.StartPoint.Y + t1 * v.Y); result.IntersectionPoints.Add(p1); return(result); } else { result.IntersectionType = IntersectionType.Collide; // there is possible 2 solutions sqrt_d = (float)Math.Sqrt(d); t1 = (-b + sqrt_d) / (2 * a); t2 = (-b - sqrt_d) / (2 * a); //check if the 2 intersection point contained in the line if ((0 <= t1 && t1 <= 1)) { var p1 = new PointF(line.StartPoint.X + t1 * v.X, line.StartPoint.Y + t1 * v.Y); result.IntersectionPoints.Add(p1); } if (0 <= t2 && t2 <= 1) { var p2 = new PointF(line.StartPoint.X + t2 * v.X, line.StartPoint.Y + t2 * v.Y); result.IntersectionPoints.Add(p2); } return(result); } }
public static IntersectionResult CirclePolyLine(GCircle circle, GPolyLine pl) { var result = new IntersectionResult(); foreach (var line in pl.Lines) { var intersect = CircleLine(circle, line); if (intersect.IntersectionPoints.Count > 0) { result.IntersectionPoints. AddRange(intersect.IntersectionPoints); } } return(result); }
public static IntersectionResult CircleCircle(GCircle c1, GCircle c2) { IntersectionResult result = new IntersectionResult(); // the distance between 2 circles var d = c1.Center.Distance(c2.Center); if (d > c1.Radius + c2.Radius) { // return mo intersection return(result); } else if (d < Math.Abs(c1.Radius - c2.Radius)) { //Circle inside each other // no intersections return(result); } else if (d == 0 && c1.Radius == c2.Radius) { //then the circles are coincident return(result); } else { result.IntersectionType = IntersectionType.Collide; //calculate intersection points double a, h; a = (c1.Radius * c1.Radius - c2.Radius * c2.Radius + d * d) / (2 * d); h = Math.Sqrt(Math.Abs(c1.Radius * c1.Radius - a * a)); var P0 = c1.Center; var P1 = c2.Center; PointF P2 = P0.Add(P1.Sub(P0).Scale((float)(a / d))); float x3, y3, x4, y4; x3 = (float)(P2.X + h * (P1.Y - P0.Y) / d); y3 = (float)(P2.Y - h * (P1.X - P0.X) / d); x4 = (float)(P2.X - h * (P1.Y - P0.Y) / d); y4 = (float)(P2.Y + h * (P1.X - P0.X) / d); result.IntersectionPoints.Add(new PointF(x3, y3)); result.IntersectionPoints.Add(new PointF(x4, y4)); return(result); } }
public static IntersectionResult ParabolaCircle(GParabola parabola, GCircle circle) { IntersectionResult result = new IntersectionResult(); // https://en.wikipedia.org/wiki/Quartic_function#Nature_of_the_roots var h = circle.Center.X; var k = circle.Center.Y; var r = circle.Radius; var poly = parabola.Polynomial; var a = poly.A * poly.A; var b = 2 * poly.A * poly.B; var c = (2 * poly.A * poly.C) - (2 * poly.A * k) + (b * b) + 1; var d = (2 * b * c) - (2 * b * k) - (2 * h); var e = (c * c - 2 * c * k + h * h + k * k - r * r); var p = (8 * a * c - 3 * b * b) / (8 * a * a); var q = (b * b * b - 4 * a * b * c + 8 * a * a * d) / (8 * Pow(a, 3)); var delta_0 = c * c - 3 * b * d + 12 * a * e; var delta_1 = 2 * c * c * c - 9 * b * c * d + 27 * b * b * e + 27 * a * d * d - 72 * a * c * e; var delta = 256 * Pow(a, 3) * Pow(e, 3) - 192 * (a * a * b * d * e * e) - 128 * (a * a * c * c * e * e) + 144 * (a * a * c * d * d * e) - 27 * (a * a * Pow(d, 4)) + 144 * (a * b * b * c * e * e) - 6 * (a * b * b * d * d * e) - 80 * (a * b * c * c * d * e) + 18 * (a * b * c * Pow(d, 3)) + 16 * (a * Pow(c, 4) * e) - 4 * (a * Pow(c, 3) * d * d) - 27 * (Pow(b, 4) * e * e) + 18 * (Pow(b, 3) * c * d * e) - 4 * (Pow(b, 3) * Pow(d, 3)) - 4 * (b * b * Pow(c, 3) * e) + (b * b * c * c * d * d); var delta_diff = -27 * delta; double Q, S; if (delta > 0) { var phy = Math.Acos(delta_1 / (2 * Sqrt(Pow(delta_0, 3)) )); S = .5 * Sqrt(-(2 / 3) * p + (2 / 3 * a) * Sqrt(delta_0) * Cos(phy / 3)); } else { Q = Pow( (delta_1 + Sqrt(delta_diff)) / 2 , 1 / 3); S = .5 * Sqrt( -(2 / 3) * p + (1 / ((3 * a)) * (Q + delta_0 / Q)) ); } if (delta != 0 && delta == 0) { } float t1, t2, t3, t4; //check for roots var d1 = -4 * S * S - 2 * p + q / S; if (d1 <= Setup.Tolerance) { t1 = (float)(-b / 4 * a - S + .5 * Sqrt(d1)); t2 = (float)(-b / 4 * a - S - .5 * Sqrt(d1)); } var d2 = -4 * S * S - 2 * p - q / S; if (d2 <= Setup.Tolerance) { t3 = (float)(-b / 4 * a - S + .5 * Sqrt(d2)); t4 = (float)(-b / 4 * a - S - .5 * Sqrt(d2)); } return(result); }
public static IntersectionResult ArcCircle(GCircle circle, GLine line) { var result = new IntersectionResult(); return(result); }