Exemplo n.º 1
0
 /// <summary>
 /// Returns the sagitta (the distance between the highest point of
 /// an arc and the center of the chord) for a circle with the
 /// supplied radius the chord length.
 /// </summary>
 /// <param name="radius">The radius of the circle.</param>
 /// <param name="chordLength">
 /// The distance between the two endpoints of the chord.
 /// </param>
 public static decimal GetSagitta(decimal radius, decimal chordLength)
 {
     // s = r - sqrt(r^2 - l^2)
     // where r = radius
     //       l = 1/2 chord length
     return(radius - RightTriangle.GetSideFromSideHyp(chordLength / 2, radius));
 }
Exemplo n.º 2
0
        /// <summary>
        /// Returns a line segment with the coordinates of a chord centered on
        /// the given angle with the given length.
        /// </summary>
        /// <param name="angleThroughCenter">The angle that passes through the
        /// center of the chord, in degrees.</param>
        /// <param name="chordLength">The length of the chord.</param>
        public LineSeg2D GetChord(decimal angleThroughCenter, decimal chordLength)
        {
            LineSeg2D l = default(LineSeg2D);
            decimal   a = 0m;

            // Create a right triangle where one side is half the chord length,
            // the other side is from the center of the circle to the midpoint
            // of the chord, and the hypotenuse is from the center of the circle
            // to the chord start point
            a = RightTriangle.GetAngleFromOppSideHyp(0.5m * chordLength, _radius);

            l.Pt1 = PointAt(angleThroughCenter - a);
            l.Pt2 = PointAt(angleThroughCenter + a);

            return(l);
        }
Exemplo n.º 3
0
 /// <summary>
 /// Gets the total angle on a circle of the given radius from one side of the chord to the other.
 /// </summary>
 /// <param name="chordLength">The length of the chord.</param>
 /// <param name="circleRadius">The radius of the circle.</param>
 public static decimal GetChordTotalAngle(decimal chordLength, decimal circleRadius)
 {
     if (chordLength == 0)
     {
         return(0m);
     }
     else if (chordLength > circleRadius * 2m)
     {
         throw new Exception("Chord can't fit inside a circle with the specified radius!");
     }
     else if (chordLength == circleRadius * 2m)
     {
         return(180m);
     }
     else
     {
         return(RightTriangle.GetAngleFromOppSideHyp(0.5m * chordLength, circleRadius) * 2m);
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Gets a line segment of length 1 starting at the point on the circle
        /// and extending either clockwise or counterclockwise.
        /// </summary>
        /// <param name="degrees">An angle.</param>
        public LineSeg2D TangentAt(decimal degrees, decimal length, bool clockwise)
        {
            var       r   = RightTriangleAbstract.FromTwoSides(_radius, length);
            decimal   rad = DecimalEx.ToRad(degrees + r.AngleA);
            LineSeg2D ret = default(LineSeg2D);

            Debug.Assert(r.AngleA == RightTriangle.GetAngleFromSides(length, _radius));
            Debug.Assert(r.Hypotenuse == RightTriangle.GetHypFromSides(length, _radius));

            ret.Pt1 = PointAt(degrees);
            if (!clockwise)
            {
                ret.Pt2 = new Point2D(_center.X + r.Hypotenuse * DecimalEx.Cos(rad), _center.Y + r.Hypotenuse * DecimalEx.Sin(rad));
            }
            else
            {
                ret.Pt2 = new Point2D(ret.Pt1.X - (_center.X + r.Hypotenuse * DecimalEx.Cos(rad) - ret.Pt1.X), ret.Pt1.Y - (_center.Y + r.Hypotenuse * DecimalEx.Sin(rad) - ret.Pt1.Y));
            }

            return(ret);
        }
Exemplo n.º 5
0
        public static  Circle2D[] FromTwoPointsAndRadius(decimal x1, decimal y1, decimal x2, decimal y2, decimal radius)
        {
            LineSeg2D pointToPoint  = default(LineSeg2D);
            Point2D   midPoint      = default(Point2D);
            Vector2D  vPerpBisector = default(Vector2D);

            if (x1 == x2 && y1 == y2)
            {
                return new Circle2D[] { }
            }
            ;

            pointToPoint            = new LineSeg2D(x1, y1, x2, y2);
            midPoint                = pointToPoint.MidPoint;
            vPerpBisector           = pointToPoint.PerpendicularBisector().GetVectorP1toP2();
            vPerpBisector.Magnitude = RightTriangle.GetSideFromSideHyp(pointToPoint.Length / 2, radius);

            return(new Circle2D[] {
                new Circle2D(midPoint + vPerpBisector, radius),
                new Circle2D(midPoint - vPerpBisector, radius)
            });
        }
Exemplo n.º 6
0
 /// <summary>
 /// Gets the chamfer drop along a given angle for a given distance.
 /// </summary>
 /// <param name="chamferDistance">The length of the chamfer.</param>
 /// <param name="chamferAngle">The angle of the chamfer in degrees.</param>
 public static decimal GetChamferDrop(decimal chamferDistance, decimal chamferAngle)
 {
     return(RightTriangle.GetSideFromOppAngleOppSide(chamferAngle, chamferDistance));
 }
Exemplo n.º 7
0
        /// <summary>
        /// Gets the points of intersection between this circle and the line which
        /// contains the given line segment.
        /// </summary>
        /// <param name="l">Line segment used to determine line equation.</param>
        /// <param name="decimals">Determines rounding that should be performed when determining
        /// if line intersection happens on zero, one, or two points. Default is -1 for
        /// no rounding.</param>
        public Point2D[] GetIntersect(LineSeg2D l, int decimals = -1)
        {
            LineSeg2D centToLine              = default(LineSeg2D);
            decimal   centToLineLength        = 0m;
            decimal   centToLineLengthForComp = 0m;
            decimal   radiusForComp           = 0m;

            if (l.IsHorizontal)
            {
                // The center to any horizontal line is a vertical line through
                // the center of the circle.
                centToLine = new LineSeg2D(this.Center, this.Center + new Vector2D(0, 1));
            }
            else
            {
                centToLine = LineSeg2D.FromPointSlope(this.Center, l.PerpendicularSlope);
            }
            centToLine.Pt2   = l.GetIntersect(centToLine, true).Value;
            centToLineLength = centToLine.Length;

            // Get numbers for comparison, rounding if necessary
            centToLineLengthForComp = centToLineLength;
            radiusForComp           = _radius;
            if (decimals >= 0)
            {
                centToLineLengthForComp = centToLineLengthForComp.RoundFromZero(decimals);
                radiusForComp           = radiusForComp.RoundFromZero(decimals);
            }

            // See if line is outside of circle
            if (centToLineLengthForComp > radiusForComp)
            {
                return(new Point2D[] { });
            }

            // See if line is tangent to circle
            if (centToLineLengthForComp == radiusForComp)
            {
                return(new Point2D[] { centToLine.Pt2 });
            }

            // Line must intersect in two places
            Vector2D vCentToChord = default(Vector2D);
            decimal  halfChord    = 0m;

            // Get a vector from the center to the intersecting chord
            vCentToChord = centToLine.GetVectorP1toP2();


            if (vCentToChord.Magnitude == 0)
            {
                Vector2D offsetVector = default(Vector2D);

                // Line goes through circle center


                if (l.IsVertical)
                {
                    // Slope undefined so just go up the length of the radius
                    offsetVector = new Vector2D(0, _radius);
                }
                else
                {
                    offsetVector = new Vector2D(_radius * DecimalEx.Cos(DecimalEx.ATan(l.Slope)), _radius * DecimalEx.Sin(DecimalEx.ATan(l.Slope)));
                }

                return(new Point2D[] {
                    this.Center + offsetVector,
                    this.Center - offsetVector
                });
            }
            else
            {
                Vector2D vChord = default(Vector2D);

                // Get a vector along the chord
                vChord = vCentToChord.GetPerpendicular();

                // Determine the length of half the chord
                halfChord = RightTriangle.GetSideFromSideHyp(centToLineLength, _radius);

                // Set the magnitude of the vector along the chord
                // to be half the chord length
                vChord.Magnitude = halfChord;

                // The two intersecting points are points translated
                // from the center of the circle to the chord (+vCentToChord)
                // and then translated to the ends of the chord (+-vChord)
                return(new Point2D[] {
                    this.Center + vCentToChord + vChord,
                    this.Center + vCentToChord - vChord
                });
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Gets the chord length for the sagitta and radius.
 /// </summary>
 public static decimal GetChordLengthFromRadiusSagitta(decimal radius, decimal sagitta)
 {
     return(2 * RightTriangle.GetSideFromSideHyp(radius - sagitta, radius));
 }