예제 #1
0
        public static Rectangle2D EllipticalArc0(
            double cX, double cY,
            double r1, double r2,
            double angle,
            double startAngle, double sweepAngle)
        {
            // Get the ellipse rotation transform.
            var cosT = Cos(angle);
            var sinT = Sin(angle);

            var i = (r1 - r2) * (r1 + r2) * sinT * cosT;

            // Find the angles of the Cartesian extremes.
            var angles = new double[4] {
                Atan2(i, (r2 * r2 * sinT * sinT) + (r1 * r1 * cosT * cosT)),
                Atan2((r1 * r1 * sinT * sinT) + (r2 * r2 * cosT * cosT), i),
                Atan2(i, (r2 * r2 * sinT * sinT) + (r1 * r1 * cosT * cosT)) + PI,
                Atan2((r1 * r1 * sinT * sinT) + (r2 * r2 * cosT * cosT), i) + PI
            };

            // Sort the angles so that like sides are consistently at the same index.
            Array.Sort(angles);

            // Get the start and end angles adjusted to polar coordinates.
            var t0 = EllipticalPolarAngleTests.EllipticalPolarAngle(startAngle, r1, r2);
            var t1 = EllipticalPolarAngleTests.EllipticalPolarAngle(startAngle + sweepAngle, r1, r2);

            // Interpolate the ratios of height and width of the chord.
            var sinT0 = Sin(t0);
            var cosT0 = Cos(t0);
            var sinT1 = Sin(t1);
            var cosT1 = Cos(t1);

            // Get the end points of the chord.
            var bounds = new Rectangle2D(
                // Apply the rotation transformation and translate to new center.
                new Point2D(
                    cX + ((r1 * cosT0 * cosT) - (r2 * sinT0 * sinT)),
                    cY + ((r1 * cosT0 * sinT) + (r2 * sinT0 * cosT))),
                // Apply the rotation transformation and translate to new center.
                new Point2D(
                    cX + ((r1 * cosT1 * cosT) - (r2 * sinT1 * sinT)),
                    cY + ((r1 * cosT1 * sinT) + (r2 * sinT1 * cosT))));

            // Find the parent ellipse's horizontal and vertical radii extremes.
            var halfWidth  = Sqrt((r1 * r1 * cosT * cosT) + (r2 * r2 * sinT * sinT));
            var halfHeight = Sqrt((r1 * r1 * sinT * sinT) + (r2 * r2 * cosT * cosT));

            // Expand the elliptical boundaries if any of the extreme angles fall within the sweep angle.
            if (AngleWithinAngleTests.Within(angles[0], angle + startAngle, sweepAngle))
            {
                bounds.Right = cX + halfWidth;
            }

            if (AngleWithinAngleTests.Within(angles[1], angle + startAngle, sweepAngle))
            {
                bounds.Bottom = cY + halfHeight;
            }

            if (AngleWithinAngleTests.Within(angles[2], angle + startAngle, sweepAngle))
            {
                bounds.Left = cX - halfWidth;
            }

            if (AngleWithinAngleTests.Within(angles[3], angle + startAngle, sweepAngle))
            {
                bounds.Top = cY - halfHeight;
            }

            // Return the points of the Cartesian extremes of the rotated elliptical arc.
            return(bounds);
        }
예제 #2
0
 public static (double X, double Y) RectangleCenter(Rectangle2D rectangle)
 => Center0(rectangle);
예제 #3
0
        public static Rectangle2D EllipticalArc3(
            double cX, double cY,
            double r1, double r2,
            double angle,
            double startAngle, double sweepAngle)
        {
            // Get the ellipse rotation transform.
            var cosT = Cos(angle);
            var sinT = Sin(angle);

            // Calculate the radii of the angle of rotation.
            var a = r1 * cosT;
            var b = r2 * sinT;
            var c = r1 * sinT;
            var d = r2 * cosT;

            // Calculate the vectors of the Cartesian extremes.
            var u1 = r1 * Cos(Atan2(d, c));
            var v1 = -(r2 * Sin(Atan2(d, c)));
            var u2 = r1 * Cos(Atan2(-b, a));
            var v2 = -(r2 * Sin(Atan2(-b, a)));

            // Find the angles of the Cartesian extremes.
            var angles = new List <double>(4)
            {
                Atan2((u1 * sinT) - (v1 * cosT), (u1 * cosT) + (v1 * sinT)),
                Atan2((u2 * sinT) - (v2 * cosT), (u2 * cosT) + (v2 * sinT)),
                Atan2((u1 * sinT) - (v1 * cosT), (u1 * cosT) + (v1 * sinT)) + PI,
                Atan2((u2 * sinT) - (v2 * cosT), (u2 * cosT) + (v2 * sinT)) + PI
            };

            // Sort the angles so that like sides are consistently at the same index.
            angles.Sort();

            // Find the parent ellipse's horizontal and vertical radii extremes.
            var halfWidth  = Sqrt((a * a) + (b * b));
            var halfHeight = Sqrt((c * c) + (d * d));

            // Get the end points of the chord.
            var bounds = new Rectangle2D(
                InterpolateRotatedEllipticalArcTests.EllipticalArc(0, cX, cY, r1, r2, angle, startAngle, sweepAngle),
                InterpolateRotatedEllipticalArcTests.EllipticalArc(1, cX, cY, r1, r2, angle, startAngle, sweepAngle));

            // Expand the elliptical boundaries if any of the extreme angles fall within the sweep angle.
            if (AngleWithinAngleTests.Within(angles[0], angle + startAngle, sweepAngle))
            {
                bounds.Right = cX + halfWidth;
            }

            if (AngleWithinAngleTests.Within(angles[1], angle + startAngle, sweepAngle))
            {
                bounds.Bottom = cY + halfHeight;
            }

            if (AngleWithinAngleTests.Within(angles[2], angle + startAngle, sweepAngle))
            {
                bounds.Left = cX - halfWidth;
            }

            if (AngleWithinAngleTests.Within(angles[3], angle + startAngle, sweepAngle))
            {
                bounds.Top = cY - halfHeight;
            }

            // Return the points of the Cartesian extremes of the rotated elliptical arc.
            return(bounds);
        }