// 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); }
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); }
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)); }
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); }
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)); }
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; } }
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; }
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; } }
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)); }
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)); }
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); }
public void ZeroIsUnknownForUnknownTest() { ICirclePair pair = CirclePair.Unknown; Assert.True(pair.Zero.IsUnknown); }
public void IsUnknownReturnsTrueForUnknownTest() { ICirclePair pair = CirclePair.Unknown; Assert.True(pair.IsUnknown); }