Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        public static IntersectionResult ArcCircle(GCircle circle, GLine line)
        {
            var result = new IntersectionResult();

            return(result);
        }