Ejemplo n.º 1
0
        /// <summary>
        /// Gets the angle in degrees for a ray that extends from the center
        /// of the circle through the given point. An exception will occur,
        /// however, if the point specified is the same point as the center
        /// of the circle.
        /// </summary>
        /// <param name="pt">The point.</param>
        public decimal AngleThroughPoint(Point2D pt)
        {
            decimal a = 0m;

            // Shift point so it's relative to the origin.
            pt += new Vector2D(-Center.X, -Center.Y);

            // Do check here after we've translated the point
            // to account for small precision rounding.
            if (pt == Point2D.Origin)
            {
                throw new Exception("No angle through given point since point is at center of circle!");
            }

            // Special case for 0 and 180 where we would get
            // a divide by zero below.
            if (pt.Y == 0)
            {
                if (pt.X > 0)
                {
                    return(0);
                }
                else
                {
                    return(180);
                }
            }

            // Special case for 90 and 270 where we can't
            // determine quadrant below.
            if (pt.X == 0)
            {
                if (pt.Y > 0)
                {
                    return(90);
                }
                else
                {
                    return(270);
                }
            }

            a = DecimalEx.ToDeg(DecimalEx.ATan(pt.X / pt.Y));
            switch (pt.Quadrant)
            {
            case 1:
            case 2:
                a = 90 - a;
                break;

            case 3:
            case 4:
                a = 270 - a;
                break;
            }

            return(a);
        }
Ejemplo n.º 2
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
                });
            }
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Gets angle in degrees from the two known sides.
 /// </summary>
 /// <param name="oppositeSide">Length of the known side opposite the angle.</param>
 /// <param name="adjacentSide">Length of the known side adjacent to the angle.</param>
 public static decimal GetAngleFromSides(decimal oppositeSide, decimal adjacentSide)
 {
     // tan(a) = opposideSide / adjacentSide
     // a = atan(opposideSide / adjacentSide)
     return(DecimalEx.ToDeg(DecimalEx.ATan(oppositeSide / adjacentSide)));
 }