Пример #1
0
 internal OutsideEdgeLine(GlyphTriangle ownerTriangle, GlyphPoint p, GlyphPoint q)
     : base(ownerTriangle, p, q)
 {
     //set back
     p.SetOutsideEdgeUnconfirmEdgeDirection(this);
     q.SetOutsideEdgeUnconfirmEdgeDirection(this);
     _newDynamicMidPoint = new Vector2((p.OX + q.OX) / 2, (p.OY + q.OY) / 2);
 }
Пример #2
0
        void AddPoint(float x, float y, PointKind kind)
        {
            var p = new GlyphPoint(x, y, kind);

#if DEBUG
            p.dbugOwnerPart = dbug_ownerPart;
#endif
            points.Add(p);
        }
Пример #3
0
 /// <summary>
 /// find bounds of new fit glyph
 /// </summary>
 /// <param name="minX"></param>
 /// <param name="minY"></param>
 /// <param name="maxX"></param>
 /// <param name="maxY"></param>
 internal void FindBounds(ref float minX, ref float minY, ref float maxX, ref float maxY)
 {
     for (int i = flattenPoints.Count - 1; i >= 0; --i)
     {
         GlyphPoint p = flattenPoints[i];
         MyMath.FindMinMax(ref minX, ref maxX, p.X);
         MyMath.FindMinMax(ref minY, ref maxY, p.Y);
     }
 }
Пример #4
0
        public bool IsClockwise()
        {
            //after flatten
            if (_analyzedClockDirection)
            {
                return(_isClockwise);
            }

            List <GlyphPoint> f_points = this.flattenPoints;

            if (f_points == null)
            {
                throw new NotSupportedException();
            }
            _analyzedClockDirection = true;


            //TODO: review here again***
            //---------------
            //http://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order
            //check if hole or not
            //clockwise or counter-clockwise
            {
                //Some of the suggested methods will fail in the case of a non-convex polygon, such as a crescent.
                //Here's a simple one that will work with non-convex polygons (it'll even work with a self-intersecting polygon like a figure-eight, telling you whether it's mostly clockwise).

                //Sum over the edges, (x2 − x1)(y2 + y1).
                //If the result is positive the curve is clockwise,
                //if it's negative the curve is counter-clockwise. (The result is twice the enclosed area, with a +/- convention.)
                int    j     = flattenPoints.Count;
                double total = 0;


                for (int i = 1; i < j; ++i)
                {
                    GlyphPoint p0 = f_points[i - 1];
                    GlyphPoint p1 = f_points[i];
                    total += (p1.OX - p0.OX) * (p1.OY + p0.OY);
                }
                //the last one
                {
                    GlyphPoint p0 = f_points[j - 1];
                    GlyphPoint p1 = f_points[0];

                    total += (p1.OX - p0.OX) * (p1.OY + p0.OY);
                }
                _isClockwise = total >= 0;
            }
            return(_isClockwise);
        }
Пример #5
0
 /// <summary>
 /// find common edge of 2 glyph points
 /// </summary>
 /// <param name="p"></param>
 /// <param name="q"></param>
 /// <returns></returns>
 internal static OutsideEdgeLine FindCommonOutsideEdge(GlyphPoint p, GlyphPoint q)
 {
     if (p.E0 == q.E0 ||
         p.E0 == q.E1)
     {
         return(p.E0);
     }
     else if (p.E1 == q.E0 ||
              p.E1 == q.E1)
     {
         return(p.E1);
     }
     else
     {
         return(null);
     }
 }
Пример #6
0
        internal void CreateGlyphEdges()
        {
            int             lim = flattenPoints.Count - 1;
            GlyphPoint      p = null, q = null;
            OutsideEdgeLine edgeLine = null;

            _edges = new List <OutsideEdgeLine>();
            //
            for (int i = 0; i < lim; ++i)
            {
                //in order ...
                p = flattenPoints[i];
                q = flattenPoints[i + 1];
                if ((edgeLine = EdgeLine.FindCommonOutsideEdge(p, q)) != null)
                {
                    //from p point to q
                    //so ...
                    //edgeLine is outwardEdge for p.
                    //edgeLine is inwardEdge for q.
                    //p.OutwardEdge = q.InwardEdge = edgeLine;
                    _edges.Add(edgeLine);
                }
                else
                {
                    //?
                }
            }
            //close
            p = flattenPoints[lim];
            q = flattenPoints[0];

            if ((edgeLine = EdgeLine.FindCommonOutsideEdge(p, q)) != null)
            {
                //from p point to q
                //so ...
                //edgeLine is outwardEdge for p.
                //edgeLine is inwardEdge for q.
                //p.OutwardEdge = q.InwardEdge = edgeLine;
                _edges.Add(edgeLine);
            }
            else
            {
                //not found
            }
        }
Пример #7
0
        internal EdgeLine(GlyphTriangle ownerTriangle, GlyphPoint p, GlyphPoint q)
        {
            //this canbe inside edge or outside edge

            this._ownerTriangle = ownerTriangle;
            //------------------------------------
            //an edge line connects 2 glyph points.
            //it is created from triangulation process.
            //
            //some edge line is either 'INSIDE' edge  OR 'OUTSIDE'.
            //
            //------------------------------------
            this._glyphPoint_P = p;
            this._glyphPoint_Q = q;

            //new dynamic mid point is calculate from original X,Y
            //-------------------------------
            //analyze angle and slope kind
            //-------------------------------

            //slope kind is evaluated

            SlopeAngleNoDirection = this.GetSlopeAngleNoDirection();
            if (QX == PX)
            {
                this.SlopeKind = LineSlopeKind.Vertical;
            }
            else
            {
                if (SlopeAngleNoDirection > _85degreeToRad)
                {
                    SlopeKind = LineSlopeKind.Vertical;
                }
                else if (SlopeAngleNoDirection < _01degreeToRad)
                {
                    SlopeKind = LineSlopeKind.Horizontal;
                    p.IsPartOfHorizontalEdge = q.IsPartOfHorizontalEdge = true;
                }
                else
                {
                    SlopeKind = LineSlopeKind.Other;
                }
            }
        }
Пример #8
0
        /// <summary>
        /// create polygon from GlyphContour
        /// </summary>
        /// <param name="cnt"></param>
        /// <returns></returns>
        static Poly2Tri.Polygon CreatePolygon(List <GlyphPoint> flattenPoints)
        {
            List <Poly2Tri.TriangulationPoint> points = new List <Poly2Tri.TriangulationPoint>();

            //limitation: poly tri not accept duplicated points! ***
            double prevX = 0;
            double prevY = 0;

#if DEBUG
            //dbug check if all point is unique
            dbugCheckAllGlyphsAreUnique(flattenPoints);
#endif


            int j = flattenPoints.Count;
            //pass
            for (int i = 0; i < j; ++i)
            {
                GlyphPoint p = flattenPoints[i];
                double     x = p.OX; //start from original X***
                double     y = p.OY; //start from original Y***

                if (x == prevX && y == prevY)
                {
                    if (i > 0)
                    {
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    var triPoint = new Poly2Tri.TriangulationPoint(prevX = x, prevY = y)
                    {
                        userData = p
                    };
#if DEBUG
                    p.dbugTriangulationPoint = triPoint;
#endif
                    points.Add(triPoint);
                }
            }

            return(new Poly2Tri.Polygon(points.ToArray()));
        }
Пример #9
0
        /// <summary>
        /// update dynamic cutpoint of 2 adjacent edges
        /// </summary>
        /// <param name="p"></param>
        static void UpdateNewEdgeCut(GlyphPoint p)
        {
            OutsideEdgeLine e0 = p.E0;
            OutsideEdgeLine e1 = p.E1;

            Vector2 tmp_e0_q = e0._newDynamicMidPoint + e0.GetOriginalEdgeVector();
            Vector2 tmp_e1_p = e1._newDynamicMidPoint - e1.GetOriginalEdgeVector();

            Vector2 cutpoint;

            if (MyMath.FindCutPoint(e0._newDynamicMidPoint, tmp_e0_q, e1._newDynamicMidPoint, tmp_e1_p, out cutpoint))
            {
                p.SetNewXY(cutpoint.X, cutpoint.Y);
            }
            else
            {
                //pararell edges
            }
        }
Пример #10
0
        internal void Flatten(GlyphPartFlattener flattener)
        {
            //flatten once
            if (_analyzed)
            {
                return;
            }
            //flatten each part ...
            //-------------------------------
            int j = parts.Count;
            //---------------
            List <GlyphPoint> prevResult       = flattener.Result;
            List <GlyphPoint> tmpFlattenPoints = flattenPoints = flattener.Result = new List <GlyphPoint>();

            //start ...
            for (int i = 0; i < j; ++i)
            {
                //flatten each part
                parts[i].Flatten(flattener);
            }

            //check duplicated the first point and last point
            int pointCount = tmpFlattenPoints.Count;

            if (GlyphPoint.SameCoordAs(tmpFlattenPoints[pointCount - 1], tmpFlattenPoints[0]))
            {
                //check if the last point is the same value as the first
                //if yes => remove the last one
                tmpFlattenPoints.RemoveAt(pointCount - 1);
                pointCount--;
            }

            //assign number for all glyph point in this contour
            for (int i = 0; i < pointCount; ++i)
            {
                tmpFlattenPoints[i].SeqNo = i;
            }

            flattener.Result = prevResult;
            _analyzed        = true;
        }
Пример #11
0
        static void dbugCheckAllGlyphsAreUnique(List <GlyphPoint> flattenPoints)
        {
            double prevX = 0;
            double prevY = 0;

            s_debugTmpPoints = new Dictionary <dbugTmpPoint, bool>();
            int lim = flattenPoints.Count - 1;

            for (int i = 0; i < lim; ++i)
            {
                GlyphPoint p = flattenPoints[i];
                double     x = p.OX; //start from original X***
                double     y = p.OY; //start from original Y***

                if (x == prevX && y == prevY)
                {
                    if (i > 0)
                    {
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    dbugTmpPoint tmp_point = new dbugTmpPoint(x, y);
                    if (!s_debugTmpPoints.ContainsKey(tmp_point))
                    {
                        //ensure no duplicated point
                        s_debugTmpPoints.Add(tmp_point, true);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                    prevX = x;
                    prevY = y;
                }
            }
        }
Пример #12
0
 internal InsideEdgeLine(GlyphTriangle ownerTriangle, GlyphPoint p, GlyphPoint q)
     : base(ownerTriangle, p, q)
 {
 }
Пример #13
0
 internal bool ContainsGlyphPoint(GlyphPoint p)
 {
     return(this._glyphPoint_P == p || this._glyphPoint_Q == p);
 }