Пример #1
0
        // ReSharper disable once MethodTooLong
        private Tuple <Point, Point> CalculateIntersectionPoints([NotNull] ICirclePair circlePair)
        {
            double r0       = circlePair.Zero.Radius;
            double r1       = circlePair.One.Radius;
            double distance = circlePair.Distance;

            // Find a and h
            double aTop    = r0 * r0 - r1 * r1 + distance * distance;
            double aBottom = 2.0 * distance;
            double a       = aTop / aBottom;
            double h       = Math.Sqrt(r0 * r0 - a * a);

            double cx0 = circlePair.Zero.X;
            double cy0 = circlePair.Zero.Y;
            double cx1 = circlePair.One.X;
            double cy1 = circlePair.One.Y;

            if (Math.Abs(h) > SelkieConstants.EpsilonRadians)
            {
                return(CalculatePointsForHBiggerThanEpsilon(h,
                                                            cy0,
                                                            cy1,
                                                            cx1,
                                                            cx0,
                                                            distance,
                                                            a));
            }

            return(CalculatePointsForSpecialCases(circlePair));
        }
        public InnerTangentLinesIntersectionPointCalculator([NotNull] ICirclePair pair)
        {
            double x = CalculateX(pair);
            double y = CalculateY(pair);

            m_Point = new Point(x,
                                y);
        }
Пример #3
0
        public CirclePairTangentLinesCalculator([NotNull] ICirclePair circlePair)
        {
            m_CirclePair = circlePair;

            m_OuterTangentsCalculator             = new OuterTangentsCalculator(m_CirclePair);
            m_InnerTangentsCalculator             = new InnerTangentsCalculator(m_CirclePair);
            m_CirclesIntersectionPointsCalculator = new CirclesIntersectionPointsCalculator(m_CirclePair);
        }
Пример #4
0
 private static bool IsSameCircles([NotNull] ICirclePair circlePair,
                                   double d,
                                   double r0MinusR1Abs)
 {
     return((Math.Abs(d) < SelkieConstants.EpsilonDistance) &&
            (r0MinusR1Abs < SelkieConstants.EpsilonDistance) &&
            (Math.Abs(circlePair.Zero.X - circlePair.One.X) < SelkieConstants.EpsilonDistance) &&
            (Math.Abs(circlePair.Zero.Y - circlePair.One.Y) < SelkieConstants.EpsilonDistance));
 }
Пример #5
0
        private Point CalculateOuterTangentLinesIntersectionPoint([NotNull] ICirclePair circlePair)
        {
            if (circlePair.NumberOfTangents < 2)
            {
                return(Point.Unknown);
            }

            var calculator = new OuterTangentLinesIntersectionPointCalculator(circlePair);

            return(calculator.IntersectionPoint);
        }
        private double CalculateX([NotNull] ICirclePair pair)
        {
            double a = pair.Zero.X;
            double c = pair.One.X;

            double top    = c * pair.RadiusZero + a * pair.RadiusOne;
            double bottom = pair.RadiusZero + pair.RadiusOne;

            double x = top / bottom;

            return(x);
        }
        private double CalculateY([NotNull] ICirclePair pair)
        {
            double b = pair.Zero.Y;
            double d = pair.One.Y;

            double top    = d * pair.RadiusZero + b * pair.RadiusOne;
            double bottom = pair.RadiusZero + pair.RadiusOne;

            double x = top / bottom;

            return(x);
        }
Пример #8
0
        internal Tuple <Point, Point> CalculateTangenPointsForZeroBothSameRadius([NotNull] ICirclePair circlePair)
        {
            var line = new Line(circlePair.Zero.CentrePoint,
                                circlePair.One.CentrePoint);

            Angle angle1 = line.AngleToXAxis - Angle.For90Degrees;
            Angle angle2 = line.AngleToXAxis + Angle.For90Degrees;

            Point point1 = circlePair.Zero.PointOnCircle(angle1);
            Point point2 = circlePair.Zero.PointOnCircle(angle2);

            return(new Tuple <Point, Point>(point1,
                                            point2));
        }
Пример #9
0
        internal Tuple <Point, Point> CalculatePointsForSpecialCases([NotNull] ICirclePair circlePair)
        {
            double deltaX       = circlePair.Zero.X - circlePair.One.X;
            double doubleRadius = circlePair.Zero.Radius * 2.0;

            if (Math.Abs(Math.Abs(deltaX) - doubleRadius) < SelkieConstants.EpsilonDistance)
            {
                return(CalculatePointsForSameY(circlePair));
            }

            double deltaY = circlePair.Zero.Y - circlePair.One.Y;

            if (Math.Abs(Math.Abs(deltaY) - doubleRadius) < SelkieConstants.EpsilonDistance)
            {
                return(CalculatePointsSameX(circlePair));
            }

            return(new Tuple <Point, Point>(Point.Unknown,
                                            Point.Unknown));
        }
        public InnerTangentsCalculator([NotNull] ICirclePair circlePair)
        {
            if (circlePair.NumberOfTangents < 3)
            {
                m_IntersectionPoint         = Point.Unknown;
                m_CircleZeroTangentPointOne = Point.Unknown;
                m_CircleZeroTangentPointTwo = Point.Unknown;
                m_CircleOneTangentPointOne  = Point.Unknown;
                m_CircleOneTangentPointTwo  = Point.Unknown;

                m_HasTangentPoints = false;
            }
            else if (circlePair.NumberOfTangents == 3)
            {
                m_IntersectionPoint = CalculateInnerTangentLinesIntersectionPoint(circlePair);

                m_CircleZeroTangentPointOne = m_IntersectionPoint;
                m_CircleZeroTangentPointTwo = m_IntersectionPoint;

                m_CircleOneTangentPointOne = m_IntersectionPoint;
                m_CircleOneTangentPointTwo = m_IntersectionPoint;

                m_HasTangentPoints = true;
            }
            else
            {
                m_IntersectionPoint = CalculateInnerTangentLinesIntersectionPoint(circlePair);

                Tuple <Point, Point> pairZero = CalculateTangentPointsForCircleOne(circlePair.Zero);
                Tuple <Point, Point> pairOne  = CalculateTangentPointsForCircleOne(circlePair.One);

                m_CircleZeroTangentPointOne = pairZero.Item1;
                m_CircleZeroTangentPointTwo = pairZero.Item2;

                m_CircleOneTangentPointOne = pairOne.Item1;
                m_CircleOneTangentPointTwo = pairOne.Item2;

                m_HasTangentPoints = true;
            }
        }
Пример #11
0
        public OuterTangentsCalculator([NotNull] ICirclePair circlePair)
        {
            ICircle circleZero = circlePair.Zero;
            ICircle circleOne  = circlePair.One;

            m_IntersectionPoint = CalculateOuterTangentLinesIntersectionPoint(circlePair);

            Tuple <Point, Point> pairZero;
            Tuple <Point, Point> pairOne;

            if (m_IntersectionPoint.IsUnknown ||
                double.IsInfinity(m_IntersectionPoint.X) ||
                double.IsInfinity(m_IntersectionPoint.Y))
            {
                if (circlePair.NumberOfTangents > 1)
                {
                    pairZero = CalculateTangenPointsForZeroBothSameRadius(circlePair);
                    pairOne  = CalculateTangenPointsForOneBothSameRadius(circlePair);
                }
                else
                {
                    pairZero = new Tuple <Point, Point>(Point.Unknown,
                                                        Point.Unknown);
                    pairOne = new Tuple <Point, Point>(Point.Unknown,
                                                       Point.Unknown);
                }
            }
            else
            {
                pairZero = CalculateTangentPointsForCircle(circleZero);
                pairOne  = CalculateTangentPointsForCircle(circleOne);
            }

            m_CircleZeroTangentPointOne = pairZero.Item1;
            m_CircleZeroTangentPointTwo = pairZero.Item2;

            m_CircleOneTangentPointOne = pairOne.Item1;
            m_CircleOneTangentPointTwo = pairOne.Item2;
        }
Пример #12
0
        public CirclesIntersectionPointsCalculator([NotNull] ICirclePair circlePair)
        {
            double d            = circlePair.Distance;
            double r0PlusR1     = circlePair.Zero.Radius + circlePair.One.Radius;
            double r0MinusR1Abs = Math.Abs(circlePair.Zero.Radius - circlePair.One.Radius);

            if (IsSameCircles(circlePair,
                              d,
                              r0MinusR1Abs))
            {
                m_IsCirclesAreSame      = true;
                m_HasIntersectionPoints = false;
            }
            else if ((r0PlusR1 >= d) &&
                     (d >= r0MinusR1Abs))
            {
                Tuple <Point, Point> points = CalculateIntersectionPoints(circlePair);

                m_IsCirclesTouchAtSinglePoint = DetermineNumberOfIntersectionPoints(points) == 1;

                if (m_IsCirclesTouchAtSinglePoint)
                {
                    var line = new Line(circlePair.Zero.CentrePoint,
                                        circlePair.One.CentrePoint);
                    Point point = circlePair.Zero.PointOnCircle(line.AngleToXAxis);

                    m_IntersectionPointOne = point;
                    m_IntersectionPointTwo = point;
                }
                else
                {
                    m_IntersectionPointOne = points.Item1;
                    m_IntersectionPointTwo = points.Item2;
                }

                m_HasIntersectionPoints = true;
            }
        }
Пример #13
0
        internal Tuple <Point, Point> CalculatePointsForSameY([NotNull] ICirclePair circlePair)
        {
            Point one;
            Point two;

            if (circlePair.Zero.X < circlePair.One.X)
            {
                one = new Point(circlePair.Zero.X + circlePair.Zero.Radius,
                                circlePair.Zero.Y);
                two = new Point(circlePair.One.X - circlePair.One.Radius,
                                circlePair.One.Y);
            }
            else
            {
                one = new Point(circlePair.Zero.X - circlePair.Zero.Radius,
                                circlePair.Zero.Y);
                two = new Point(circlePair.One.X + circlePair.One.Radius,
                                circlePair.One.Y);
            }

            return(new Tuple <Point, Point>(one,
                                            two));
        }
Пример #14
0
        internal Tuple <Point, Point> CalculatePointsSameX([NotNull] ICirclePair circlePair)
        {
            Point one;
            Point two;

            if (circlePair.Zero.Y < circlePair.One.Y)
            {
                one = new Point(circlePair.Zero.X,
                                circlePair.Zero.Y + circlePair.Zero.Radius);
                two = new Point(circlePair.One.X,
                                circlePair.One.Y - circlePair.Zero.Radius);
            }
            else
            {
                one = new Point(circlePair.Zero.X,
                                circlePair.Zero.Y - circlePair.Zero.Radius);
                two = new Point(circlePair.One.X,
                                circlePair.One.Y + circlePair.Zero.Radius);
            }

            return(new Tuple <Point, Point>(one,
                                            two));
        }
Пример #15
0
        public void OneIsUnknownForUnknownTest()
        {
            ICirclePair pair = CirclePair.Unknown;

            Assert.True(pair.One.IsUnknown);
        }
        private Point CalculateInnerTangentLinesIntersectionPoint([NotNull] ICirclePair circlePair)
        {
            var calculator = new InnerTangentLinesIntersectionPointCalculator(circlePair);

            return(calculator.IntersectionPoint);
        }
Пример #17
0
        public void ZeroIsUnknownForUnknownTest()
        {
            ICirclePair pair = CirclePair.Unknown;

            Assert.True(pair.Zero.IsUnknown);
        }
Пример #18
0
        public void IsUnknownReturnsTrueForUnknownTest()
        {
            ICirclePair pair = CirclePair.Unknown;

            Assert.True(pair.IsUnknown);
        }