示例#1
0
        public static Point SplitByNextIntersection(Point startPoint, EllipticalArcSegment segment, out SegmentBase segment1, out SegmentBase segment2)
        {
            Func <Point, EllipticalArcSegment> create = p => new EllipticalArcSegment(segment.Radii, segment.XAxisRotation, segment.IsLargeArc, segment.IsSweep, p);

            return(SplitByNextIntersection(startPoint, segment, out segment1, out segment2,
                                           new EllipticalArcEquation(startPoint, segment),
                                           (t, p) => create(p),
                                           t => create(segment.EndPoint)));
        }
示例#2
0
        public EllipticalArcEquation(Point startPoint, EllipticalArcSegment segment)
        {
            var phi = ToRadians(segment.XAxisRotation);

            _cos = Cos(phi);
            _sin = Sin(phi);
            var mid = (startPoint - segment.EndPoint) / 2;
            var x1  = _cos * mid.X + _sin * mid.Y;
            var y1  = -_sin * mid.X + _cos * mid.Y;

            _rx = segment.Radii.X;
            _ry = segment.Radii.Y;
            var lambda = Square(x1 / _rx) + Square(y1 / _ry);

            if (lambda > 1)
            {
                lambda = Sqrt(lambda);
                _rx   *= lambda;
                _ry   *= lambda;
            }

            var sqrt = Sqrt(Abs(Square(_rx * _ry) / (Square(_rx * y1) + Square(x1 * _ry)) - 1));
            var sign = segment.IsLargeArc != segment.IsSweep ? 1 : -1;
            var cx1  = sign * sqrt * _rx * y1 / _ry;
            var cy1  = -sign * sqrt * _ry * x1 / _rx;
            var avg  = (startPoint + segment.EndPoint) / 2;

            _cx     = _cos * cx1 - _sin * cy1 + avg.X;
            _cy     = _sin * cx1 + _cos * cy1 + avg.Y;
            _theta1 = ToDegrees(Atan2((y1 - cy1) / _ry, (x1 - cx1) / _rx));
            var theta2 = ToDegrees(Atan2((-y1 - cy1) / _ry, (-x1 - cx1) / _rx));

            _deltaTheta = (theta2 - _theta1) % 360;
            _isSweep    = segment.IsSweep;
            if (_isSweep)
            {
                if (_deltaTheta < 0)
                {
                    _deltaTheta += 360;
                }
            }
            else
            {
                if (_deltaTheta > 0)
                {
                    _deltaTheta -= 360;
                }
            }
            _theta1     = ToRadians(_theta1);
            _deltaTheta = ToRadians(_deltaTheta);
        }
示例#3
0
 public static List <Point> Approximate(Point startPoint, EllipticalArcSegment segment)
 {
     return(Approximate(new EllipticalArcEquation(startPoint, segment).GetPoint, startPoint, segment.EndPoint));
 }