Example #1
0
 /// <summary>
 /// Gets hypotenuse from a known side and the angle adjacent to that side.
 /// </summary>
 /// <param name="side">Length of the known side.</param>
 /// <param name="angleAdjacentToSide">The angle adjacent to the known side in degrees.</param>
 public static decimal GetHypFromSideAdjAngle(decimal side, decimal angleAdjacentToSide)
 {
     // cos(a) = s / h
     // h * cos(a) = s
     // h = s / cos(a)
     return(side / DecimalEx.Cos(DecimalEx.ToRad(angleAdjacentToSide)));
 }
Example #2
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);
        }
Example #3
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
                });
            }
        }
Example #4
0
        /// <summary>
        /// Gets the coordinates of the point on the circle at the given angle.
        /// </summary>
        /// <param name="degrees">The angle in degrees.</param>
        public Point2D PointAt(decimal degrees)
        {
            decimal rad = DecimalEx.ToRad(degrees);

            return(new Point2D(_center.X + _radius * DecimalEx.Cos(rad), _center.Y + _radius * DecimalEx.Sin(rad)));
        }
Example #5
0
 /// <summary>
 /// Gets a side from the adjacent angle and the length of the hypotenuse.
 /// </summary>
 /// <param name="adjacentAngle">Angle adjacent to the side to calculate in degrees.</param>
 /// <param name="hypotenuse">Length of the hypotenuse.</param>
 public static decimal GetSideFromAdjAngleHyp(decimal adjacentAngle, decimal hypotenuse)
 {
     // cos(adjacentAngle) = x / hypotenuse
     // x = hypotenuse * cos(adjacentAngle)
     return(hypotenuse * Convert.ToDecimal(DecimalEx.Cos(DecimalEx.ToRad(adjacentAngle))));
 }