コード例 #1
0
ファイル: Polygon.cs プロジェクト: remuladgryta/MagicTile
        /// <summary>
        /// Apply a transform to us.
        /// </summary>
        private void TransformInternal <T>(T transform) where T : ITransform
        {
            // NOTES:
            // Arcs can go to lines, and lines to arcs.
            // Rotations may reverse arc directions as well.
            // Arc centers can't be transformed directly.

            // NOTE: We must calc this before altering the endpoints.
            Vector3D mid = Midpoint;

            if (Infinity.IsInfinite(mid))
            {
                mid = Infinity.IsInfinite(P1) ? P2 * Infinity.FiniteScale : P1 * Infinity.FiniteScale;
            }

            P1  = transform.Apply(P1);
            P2  = transform.Apply(P2);
            mid = transform.Apply(mid);

            // Can we make a circle out of the transformed points?
            Circle temp = new Circle();

            if (!Infinity.IsInfinite(P1) && !Infinity.IsInfinite(P2) && !Infinity.IsInfinite(mid) &&
                temp.From3Points(P1, mid, P2))
            {
                Type   = SegmentType.Arc;
                Center = temp.Center;

                // Work out the orientation of the arc.
                Vector3D t1 = P1 - Center;
                Vector3D t2 = mid - Center;
                Vector3D t3 = P2 - Center;
                double   a1 = Euclidean2D.AngleToCounterClock(t2, t1);
                double   a2 = Euclidean2D.AngleToCounterClock(t3, t1);
                Clockwise = a2 > a1;
            }
            else
            {
                // The circle construction fails if the points
                // are colinear (if the arc has been transformed into a line).
                Type = SegmentType.Line;

                // XXX - need to do something about this.
                // Turn into 2 segments?
                //if( isInfinite( mid ) )
                // Actually the check should just be whether mid is between p1 and p2.
            }
        }
コード例 #2
0
ファイル: Polygon.cs プロジェクト: remuladgryta/MagicTile
        public static Segment Arc(Vector3D start, Vector3D mid, Vector3D end)
        {
            Segment newSeg = new Segment();

            newSeg.Type = SegmentType.Arc;
            newSeg.P1   = start;
            newSeg.P2   = end;

            Circle c = new Circle();

            c.From3Points(start, mid, end);
            newSeg.Center = c.Center;

            // Obtain vectors from center point of circle (as if at the origin)
            Vector3D startOrigin = start - c.Center;
            Vector3D midOrigin   = mid - c.Center;
            Vector3D endOrigin   = end - c.Center;

            // Calculate the normal vector and angle to traverse.
            // ZZZ - worry about failure of cross product here.
            Vector3D normalVector = startOrigin.Cross(endOrigin);

            newSeg.Clockwise = normalVector.Z < 0;
            double angleToTraverse = startOrigin.AngleTo(endOrigin);

            // The normal vector might need to be reversed and the angleToTraverse adjusted.
            // This happens depending on the location of the midpoint relative to the start and end points.
            double compareAngle = startOrigin.AngleTo(midOrigin) + midOrigin.AngleTo(endOrigin);
            bool   reverse      = !Tolerance.Equal(angleToTraverse, compareAngle);

            if (reverse)
            {
                newSeg.Clockwise = !newSeg.Clockwise;
            }

            return(newSeg);
        }