static void CreateBoneJointIfNeed(
     InsideEdgeLine insideEdge,
     GlyphTriangle first_p_tri,
     GlyphBoneJoint firstJoint,
     List <GlyphBone> newlyCreatedBones,
     List <GlyphBone> glyphBones)
 {
     if (insideEdge != null &&
         insideEdge.inside_joint == null)
     {
         InsideEdgeLine mainEdge = insideEdge;
         EdgeLine       nbEdge   = null;
         if (FindSameCoordEdgeLine(first_p_tri.N0, mainEdge, out nbEdge) ||
             FindSameCoordEdgeLine(first_p_tri.N1, mainEdge, out nbEdge) ||
             FindSameCoordEdgeLine(first_p_tri.N2, mainEdge, out nbEdge))
         {
             //confirm that nbEdge is INSIDE edge
             if (nbEdge.IsInside)
             {
                 GlyphBoneJoint joint = new GlyphBoneJoint((InsideEdgeLine)nbEdge, mainEdge);
                 GlyphBone      bone  = new GlyphBone(mainEdge.inside_joint, firstJoint);
                 newlyCreatedBones.Add(bone);
                 glyphBones.Add(bone);
             }
             else
             {
                 //?
             }
         }
         else
         {
             //?
         }
     }
 }
예제 #2
0
        static bool FindCommonInsideEdges(GlyphTriangle a, GlyphTriangle b, out InsideEdgeLine a_edge, out InsideEdgeLine b_edge)
        {
            //2 contact triangles share GlyphBoneJoint.


            EdgeLine       find_b_edge = b.e0;
            InsideEdgeLine matching_inside_edge_of_a = null;

            if ((matching_inside_edge_of_a = FindCommonInsideEdge(a, find_b_edge)) != null)
            {
                //found
                a_edge = matching_inside_edge_of_a;
                b_edge = (InsideEdgeLine)find_b_edge;
                return(true);
            }
            //--------------
            find_b_edge = b.e1;
            if ((matching_inside_edge_of_a = FindCommonInsideEdge(a, find_b_edge)) != null)
            {
                //found
                a_edge = matching_inside_edge_of_a;
                b_edge = (InsideEdgeLine)find_b_edge;
                return(true);
            }
            find_b_edge = b.e2;
            if ((matching_inside_edge_of_a = FindCommonInsideEdge(a, find_b_edge)) != null)
            {
                //found
                a_edge = matching_inside_edge_of_a;
                b_edge = (InsideEdgeLine)find_b_edge;
                return(true);
            }
            a_edge = b_edge = null;
            return(false);
        }
예제 #3
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);
 }
예제 #4
0
        internal GlyphCentroidPair(GlyphTriangle p, GlyphTriangle q)
        {
            //each triangle has 1 centroid point
            //a centroid line connects between 2 adjacent triangles via centroid

            //p triangle=> (x0,y0)  (centroid of p)
            //q triangle=> (x1,y1)  (centroid of q)
            //a centroid line  move from p to q
            this.p = p;
            this.q = q;
        }
예제 #5
0
 static int FindLatestConnectedTri(List <GlyphTriangle> usedTriList, GlyphTriangle tri)
 {
     //search back ***
     for (int i = usedTriList.Count - 1; i >= 0; --i)
     {
         if (usedTriList[i].IsConnectedTo(tri))
         {
             return(i);
         }
     }
     return(-1);
 }
 public bool IsConnectedTo(GlyphTriangle anotherTri)
 {
     DelaunayTriangle t2 = anotherTri._tri;
     if (t2 == this._tri)
     {
         throw new NotSupportedException();
     }
     //compare each neighbor 
     return this._tri.N0 == t2 ||
            this._tri.N1 == t2 ||
            this._tri.N2 == t2;
 }
 public void CreateBoneLinkBetweenCentroidLine(List <GlyphBone> newlyCreatedBones)
 {
     foreach (CentroidLine line in _lines.Values)
     {
         List <GlyphBone> glyphBones  = line.bones;
         GlyphBoneJoint   firstJoint  = line._joints[0];
         GlyphTriangle    first_p_tri = firstJoint.P_Tri;
         //
         CreateBoneJointIfNeed(first_p_tri.e0 as InsideEdgeLine, first_p_tri, firstJoint, newlyCreatedBones, glyphBones);
         CreateBoneJointIfNeed(first_p_tri.e1 as InsideEdgeLine, first_p_tri, firstJoint, newlyCreatedBones, glyphBones);
         CreateBoneJointIfNeed(first_p_tri.e2 as InsideEdgeLine, first_p_tri, firstJoint, newlyCreatedBones, glyphBones);
     }
 }
 /// <summary>
 /// find nearest joint that contains tri
 /// </summary>
 /// <param name="tri"></param>
 /// <returns></returns>
 public GlyphBoneJoint FindNearestJoint(GlyphTriangle tri)
 {
     for (int i = _joints.Count - 1; i >= 0; --i)
     {
         GlyphBoneJoint joint = _joints[i];
         //each pair has 1 bone joint
         //once we have 1 candidate
         if (joint.ComposeOf(tri))
         {
             //found another joint
             return(joint);
         }
     }
     return(null);
 }
 public bool FindBoneJoint(GlyphTriangle tri,
                           out CentroidLine foundOnBranch,
                           out GlyphBoneJoint foundOnJoint)
 {
     foreach (CentroidLine line in _lines.Values)
     {
         if ((foundOnJoint = line.FindNearestJoint(tri)) != null)
         {
             foundOnBranch = line;
             return(true);
         }
     }
     foundOnBranch = null;
     foundOnJoint  = null;
     return(false);
 }
예제 #10
0
 static EdgeLine FindAnotherOutsideEdge(GlyphTriangle tri, EdgeLine knownOutsideEdge)
 {
     if (tri.e0.IsOutside && tri.e0 != knownOutsideEdge)
     {
         return(tri.e0);
     }
     if (tri.e1.IsOutside && tri.e1 != knownOutsideEdge)
     {
         return(tri.e1);
     }
     if (tri.e2.IsOutside && tri.e2 != knownOutsideEdge)
     {
         return(tri.e2);
     }
     return(null);
 }
        /// <summary>
        /// find nb triangle that has the same edgeLine
        /// </summary>
        /// <param name="tri"></param>
        /// <returns></returns>
        static bool FindSameCoordEdgeLine(GlyphTriangle tri, EdgeLine edgeLine, out EdgeLine foundEdge)
        {
            foundEdge = null;
            if (tri == null)
            {
                return(false);
            }

            if (SameCoord(foundEdge = tri.e0, edgeLine) ||
                SameCoord(foundEdge = tri.e1, edgeLine) ||
                SameCoord(foundEdge = tri.e2, edgeLine))
            {
                return(true);
            }
            foundEdge = null; //not found
            return(false);
        }
        /// <summary>
        /// set current centroid line to a centroid line that starts with triangle of centroid-line-head
        /// </summary>
        /// <param name="triOfCentroidLineHead"></param>
        public void SetCurrentCentroidLine(GlyphTriangle triOfCentroidLineHead)
        {
            //this method is used during centroid line hub creation
            if (currentBranchTri != triOfCentroidLineHead)
            {
                //check if we have already create it
                if (!_lines.TryGetValue(triOfCentroidLineHead, out currentLine))
                {
                    //if not found then create new
                    currentLine = new CentroidLine();
#if  DEBUG
                    currentLine.dbugStartTri = triOfCentroidLineHead;
#endif
                    _lines.Add(triOfCentroidLineHead, currentLine);
                }
                currentBranchTri = triOfCentroidLineHead;
            }
        }
예제 #13
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;
                }
            }
        }
예제 #14
0
        /// <summary>
        /// add information about each edge of a triangle, compare to the contactEdge of a ownerEdgeJoint
        /// </summary>
        /// <param name="triangle"></param>
        /// <param name="boneJoint"></param>
        /// <param name="knownInsideEdge"></param>
        static EdgeLine CreateTipEdgeIfNeed(
            double cent_slopAngle,
            GlyphTriangle triangle,
            EdgeLine knownInsideEdge)
        {
            int      outsideCount;
            EdgeLine outside0, outside1, outside2, anotherInsideEdge;

            ClassifyTriangleEdges(
                triangle,
                knownInsideEdge,
                out anotherInsideEdge,
                out outside0,
                out outside1,
                out outside2,
                out outsideCount);

            switch (outsideCount)
            {
            default: throw new NotSupportedException();

            case 0:
            case 1: break;

            case 3: throw new NotImplementedException();    //TODO: implement this

            case 2:

                //tip end
                //find which edge should be 'tip edge'
                //in this version we compare each edge slope to centroid line slope.
                //the most diff angle should be opposite edge (to the centroid) => tip edge
                //-------------------------------------------------------------------------
                EdgeLine tipEdge, notTipEdge;
                SelectMostProperTipEdge(cent_slopAngle,
                                        outside0,
                                        outside1,
                                        out tipEdge,
                                        out notTipEdge);
                return(tipEdge);
            }
            return(null);
        }
예제 #15
0
 static InsideEdgeLine FindCommonInsideEdge(GlyphTriangle a, EdgeLine b_edge)
 {
     //2 contact triangles share GlyphBoneJoint.
     //compare 3 side of a's edge to b_edge
     if (b_edge.IsOutside)
     {
         return(null);
     }
     //
     if (IsMatchingEdge(a.e0, b_edge))
     {
         return((InsideEdgeLine)a.e0);
     }
     if (IsMatchingEdge(a.e1, b_edge))
     {
         return((InsideEdgeLine)a.e1);
     }
     if (IsMatchingEdge(a.e2, b_edge))
     {
         return((InsideEdgeLine)a.e2);
     }
     return(null);
 }
예제 #16
0
 /// <summary>
 /// find all outside edge a
 /// </summary>
 /// <param name="bone"></param>
 /// <param name="outsideEdges"></param>
 /// <returns></returns>
 public static void CollectOutsideEdge(this GlyphBone bone, System.Collections.Generic.List <EdgeLine> outsideEdges)
 {
     if (bone.JointB != null)
     {
         GlyphTriangle commonTri = FindCommonTriangle(bone.JointA, bone.JointB);
         if (commonTri != null)
         {
             if (commonTri.e0.IsOutside)
             {
                 outsideEdges.Add(commonTri.e0);
             }
             if (commonTri.e1.IsOutside)
             {
                 outsideEdges.Add(commonTri.e1);
             }
             if (commonTri.e2.IsOutside)
             {
                 outsideEdges.Add(commonTri.e2);
             }
         }
     }
     else if (bone.TipEdge != null)
     {
         outsideEdges.Add(bone.TipEdge);
         EdgeLine found;
         if (ContainsEdge(bone.JointA.P_Tri, bone.TipEdge) &&
             (found = FindAnotherOutsideEdge(bone.JointA.P_Tri, bone.TipEdge)) != null)
         {
             outsideEdges.Add(found);
         }
         else if (ContainsEdge(bone.JointA.Q_Tri, bone.TipEdge) &&
                  (found = FindAnotherOutsideEdge(bone.JointA.Q_Tri, bone.TipEdge)) != null)
         {
             outsideEdges.Add(found);
         }
     }
 }
 internal bool ComposeOf(GlyphTriangle tri)
 {
     return(this.P_Tri == tri || this.Q_Tri == tri);
 }
예제 #18
0
        static void CreateCentroidLineHubs(Polygon polygon, List <GlyphTriangle> triangles, List <CentroidLineHub> outputLineHubs)
        {
            //create triangle list from given DelaunayTriangle polygon.
            // Generate GlyphTriangle triangle from DelaunayTriangle
            foreach (DelaunayTriangle delnTri in polygon.Triangles)
            {
                delnTri.MarkAsActualTriangle();
                triangles.Add(new GlyphTriangle(delnTri)); //all triangles are created from Triangulation process
            }

            //----------------------------
            //create centroid line hub
            //----------------------------
            //1.
            var             centroidLineHubs       = new Dictionary <GlyphTriangle, CentroidLineHub>();
            CentroidLineHub currentCentroidLineHub = null;
            //2. temporary list of used triangles
            List <GlyphTriangle> usedTriList = new List <GlyphTriangle>();
            GlyphTriangle        latestTri   = null;

            //we may walk forward and backward on each tri
            //so we record the used triangle into a usedTriList.
            int triCount = triangles.Count;

            for (int i = 0; i < triCount; ++i)
            {
                GlyphTriangle tri = triangles[i];
                if (i == 0)
                {
                    centroidLineHubs[tri]     = currentCentroidLineHub = new CentroidLineHub(tri);
                    usedTriList.Add(latestTri = tri);
                }
                else
                {
                    //at a branch
                    //one tri may connect with 3 NB triangle
                    int foundIndex = FindLatestConnectedTri(usedTriList, tri);
                    if (foundIndex < 0)
                    {
                        //?
                        throw new NotSupportedException();
                    }
                    else
                    {
                        //record used triangle
                        usedTriList.Add(tri);

                        GlyphTriangle connectWithPrevTri = usedTriList[foundIndex];
                        if (connectWithPrevTri != latestTri)
                        {
                            //branch
                            CentroidLineHub lineHub;
                            if (!centroidLineHubs.TryGetValue(connectWithPrevTri, out lineHub))
                            {
                                //if not found then=> //start new CentroidLineHub
                                centroidLineHubs[connectWithPrevTri] = lineHub = new CentroidLineHub(connectWithPrevTri);
                                //create linehub to line hub connection
                                //TODO: review here
                                //create centroid pair at link point
                            }
                            else
                            {
                                //this is multiple facets triangle for  CentroidLineHub
                            }

                            currentCentroidLineHub = lineHub;
                            //ensure start triangle of the branch
                            lineHub.SetCurrentCentroidLine(tri);
                            //create centroid line and add to currrent hub
                            currentCentroidLineHub.AddCentroidPair(new GlyphCentroidPair(connectWithPrevTri, tri));
                        }
                        else
                        {
                            //add centroid line to current multifacet joint
                            if (currentCentroidLineHub.LineCount == 0)
                            {
                                //ensure start triangle of the branch
                                currentCentroidLineHub.SetCurrentCentroidLine(tri);
                            }
                            //create centroid line and add to currrent hub
                            currentCentroidLineHub.AddCentroidPair(new GlyphCentroidPair(connectWithPrevTri, tri));
                        }
                        latestTri = tri;
                    }
                }
            }

            //--------------------------------------------------------------
            //copy to list, we not use the centroidLineHubs anymore
            outputLineHubs.AddRange(centroidLineHubs.Values);
        }
예제 #19
0
 static bool ContainsEdge(GlyphTriangle tri, EdgeLine edge)
 {
     return(tri.e0 == edge || tri.e1 == edge || tri.e2 == edge);
 }
 public CentroidLineHub(GlyphTriangle startTriangle)
 {
     this.startTriangle = startTriangle;
 }
예제 #21
0
 internal InsideEdgeLine(GlyphTriangle ownerTriangle, GlyphPoint p, GlyphPoint q)
     : base(ownerTriangle, p, q)
 {
 }
예제 #22
0
        static void ClassifyTriangleEdges(
            GlyphTriangle triangle,
            EdgeLine knownInsideEdge,
            out EdgeLine anotherInsideEdge,
            out EdgeLine outside0,
            out EdgeLine outside1,
            out EdgeLine outside2,
            out int outsideCount)
        {
            outsideCount = 0;
            outside0     = outside1 = outside2 = anotherInsideEdge = null;

            if (triangle.e0.IsOutside)
            {
                switch (outsideCount)
                {
                case 0: outside0 = triangle.e0; break;

                case 1: outside1 = triangle.e0; break;

                case 2: outside2 = triangle.e0; break;
                }
                outsideCount++;
            }
            else
            {
                //e0 is not known inside edge
                if (triangle.e0 != knownInsideEdge)
                {
                    anotherInsideEdge = triangle.e0;
                }
            }
            //
            if (triangle.e1.IsOutside)
            {
                switch (outsideCount)
                {
                case 0: outside0 = triangle.e1; break;

                case 1: outside1 = triangle.e1; break;

                case 2: outside2 = triangle.e1; break;
                }
                outsideCount++;
            }
            else
            {
                if (triangle.e1 != knownInsideEdge)
                {
                    anotherInsideEdge = triangle.e1;
                }
            }
            //
            if (triangle.e2.IsOutside)
            {
                switch (outsideCount)
                {
                case 0: outside0 = triangle.e2; break;

                case 1: outside1 = triangle.e2; break;

                case 2: outside2 = triangle.e2; break;
                }
                outsideCount++;
            }
            else
            {
                if (triangle.e2 != knownInsideEdge)
                {
                    anotherInsideEdge = triangle.e2;
                }
            }
        }
예제 #23
0
 internal static bool ContainsTriangle(this EdgeLine edge, GlyphTriangle p)
 {
     return(p.e0 == edge ||
            p.e1 == edge ||
            p.e2 == edge);
 }
        /// <summary>
        /// create a set of GlyphBone
        /// </summary>
        /// <param name="newlyCreatedBones"></param>
        public void CreateBones(List <GlyphBone> newlyCreatedBones)
        {
            foreach (CentroidLine line in _lines.Values)
            {
                List <GlyphBoneJoint> jointlist = line._joints;
                //start with empty bone list
                List <GlyphBone> glyphBones = line.bones;
                int j = jointlist.Count;

                if (j == 0)
                {
                    continue;
                }
                //
                GlyphBoneJoint joint = jointlist[0]; //first
                {
                    GlyphTriangle firstTri = joint.P_Tri;
                    //test 3 edges, find edge that is inside
                    //and the joint is not the same as first_pair.BoneJoint
                    CreateTipBoneIfNeed(firstTri.e0 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                    CreateTipBoneIfNeed(firstTri.e1 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                    CreateTipBoneIfNeed(firstTri.e2 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                }

                for (int i = 0; i < j; ++i)
                {
                    //for each GlyphCentroidPair
                    //create bone that link the GlyphBoneJoint of the pair
                    joint = jointlist[i];
                    //if (joint.dbugId > 20)
                    //{
                    //}
                    if (joint.TipEdgeP != null)
                    {
                        GlyphBone tipBone = new GlyphBone(joint, joint.TipEdgeP);
                        newlyCreatedBones.Add(tipBone);
                        glyphBones.Add(tipBone);
                    }
                    //-----------------------------------------------------
                    if (i < j - 1)
                    {
                        //not the last one
                        GlyphBoneJoint nextJoint = jointlist[i + 1];
                        GlyphBone      bone      = new GlyphBone(joint, nextJoint);
                        newlyCreatedBones.Add(bone);
                        glyphBones.Add(bone);
                    }

                    if (joint.TipEdgeQ != null)
                    {
                        GlyphBone tipBone = new GlyphBone(joint, joint.TipEdgeQ);
                        newlyCreatedBones.Add(tipBone);
                        glyphBones.Add(tipBone);
                    }
                }


                //for (int i = 1; i < j; ++i)
                //{
                //    joint = jointlist[i]; //first
                //    {
                //        GlyphTriangle tri = joint.P_Tri;
                //        //test 3 edges, find edge that is inside
                //        //and the joint is not the same as first_pair.BoneJoint
                //        CreateTipBoneIfNeed(tri.e0 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                //        CreateTipBoneIfNeed(tri.e1 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                //        CreateTipBoneIfNeed(tri.e2 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                //    }
                //}
            }
        }