Exemplo n.º 1
0
        public static PrimitiveEllipse Project(PrimitiveEllipse ellipse, Matrix4 transform)
        {
            // brute-force the endpoints
            var fromUnit    = Matrix4.CreateScale(1.0, 1.0, 0.0) * transform * ellipse.FromUnitCircle;
            var center      = transform.Transform(ellipse.Center);
            var minPoint    = fromUnit.Transform(new Point(MathHelper.COS[0], MathHelper.SIN[0], 0));
            var maxPoint    = minPoint;
            var minDistance = (minPoint - center).LengthSquared;
            var maxDistance = minDistance;

            for (int i = 1; i < 360; i++)
            {
                var next = fromUnit.Transform(new Point(MathHelper.COS[i], MathHelper.SIN[i], 0));
                var dist = (next - center).LengthSquared;
                if (dist < minDistance)
                {
                    minPoint    = next;
                    minDistance = dist;
                }

                if (dist > maxDistance)
                {
                    maxPoint    = next;
                    maxDistance = dist;
                }
            }

            var majorAxis      = maxPoint - center;
            var minorAxisRatio = Math.Sqrt(minDistance) / Math.Sqrt(maxDistance);
            var startAngle     = ellipse.StartAngle;
            var endAngle       = ellipse.EndAngle;

            // projection looks like a circle
            if (Math.Abs(maxDistance - minDistance) < MathHelper.Epsilon * 1000) // TODO: need a better way to do this
            {
                majorAxis      = new Vector(majorAxis.Length, 0.0, 0.0);         // right vector
                minorAxisRatio = 1.0;
            }

            // correct start/end angles
            if (!ellipse.IsClosed)
            {
                var tempEllipse = new PrimitiveEllipse(center, majorAxis, Vector.ZAxis, minorAxisRatio, 0.0, MathHelper.ThreeSixty, ellipse.Color);
                var majorAngle  = majorAxis.ToAngle();
                var startPoint  = transform.Transform(ellipse.StartPoint());
                var endPoint    = transform.Transform(ellipse.EndPoint());
                var toUnit      = tempEllipse.FromUnitCircle.Inverse();
                var startUnit   = (Vector)toUnit.Transform(startPoint);
                var endUnit     = (Vector)toUnit.Transform(endPoint);
                startAngle = (startUnit.ToAngle() - majorAngle).CorrectAngleDegrees();
                endAngle   = (endUnit.ToAngle() - majorAngle).CorrectAngleDegrees();
            }

            return(new PrimitiveEllipse(center, majorAxis, Vector.ZAxis, minorAxisRatio, startAngle, endAngle, ellipse.Color));
        }
Exemplo n.º 2
0
        public void EllipseGetPointTest()
        {
            var el = new PrimitiveEllipse(Point.Origin, 1.0, 0.0, 180.0, Vector.ZAxis);

            Assert.True(el.StartPoint().CloseTo(new Point(1.0, 0.0, 0.0)));
            Assert.True(el.EndPoint().CloseTo(new Point(-1.0, 0.0, 0.0)));
            Assert.True(el.GetPoint(90.0).CloseTo(new Point(0.0, 1.0, 0.0)));

            el = new PrimitiveEllipse(new Point(1.0, 1.0, 0.0), 1.0, 0.0, 180.0, Vector.ZAxis);
            Assert.True(el.StartPoint().CloseTo(new Point(2.0, 1.0, 0.0)));
            Assert.True(el.EndPoint().CloseTo(new Point(0.0, 1.0, 0.0)));
            Assert.True(el.GetPoint(90.0).CloseTo(new Point(1.0, 2.0, 0.0)));
        }