static void CreateBoneJointIfNeed( InsideEdgeLine insideEdge, AnalyzedTriangle first_p_tri, Joint firstJoint, List <Bone> newlyCreatedBones, List <Bone> 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) { Joint joint = new Joint((InsideEdgeLine)nbEdge, mainEdge); Bone bone = new Bone(mainEdge._inside_joint, firstJoint); newlyCreatedBones.Add(bone); glyphBones.Add(bone); } else { //? } } else { //? } } }
static bool FindCommonInsideEdges(AnalyzedTriangle a, AnalyzedTriangle 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); }
internal OutsideEdgeLine(AnalyzedTriangle ownerTriangle, Vertex p, Vertex q) : base(ownerTriangle, p, q) { //set back p.SetOutsideEdgeUnconfirmEdgeDirection(this); q.SetOutsideEdgeUnconfirmEdgeDirection(this); _newDynamicMidPoint = new Vector2f((p.OX + q.OX) / 2, (p.OY + q.OY) / 2); }
internal CentroidPair(AnalyzedTriangle p, AnalyzedTriangle 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; }
static int FindLatestConnectedTri(List <AnalyzedTriangle> usedTriList, AnalyzedTriangle tri) { //search back *** for (int i = usedTriList.Count - 1; i >= 0; --i) { if (usedTriList[i].IsConnectedTo(tri)) { return(i); } } return(-1); }
public bool IsConnectedTo(AnalyzedTriangle anotherTri) { DelaunayTriangle t2 = anotherTri._tri; if (t2 == _tri) { throw new NotSupportedException(); } //compare each neighbor return(_tri.N0 == t2 || _tri.N1 == t2 || _tri.N2 == t2); }
public void CreateBoneLinkBetweenCentroidLine(List <Bone> newlyCreatedBones) { foreach (CentroidLine line in _lines.Values) { List <Bone> glyphBones = line.bones; Joint firstJoint = line._joints[0]; AnalyzedTriangle 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 Joint FindNearestJoint(AnalyzedTriangle tri) { for (int i = _joints.Count - 1; i >= 0; --i) { Joint 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); }
static EdgeLine FindAnotherOutsideEdge(AnalyzedTriangle 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); }
public bool FindBoneJoint(AnalyzedTriangle tri, out CentroidLine foundOnBranch, out Joint foundOnJoint) { foreach (CentroidLine line in _lines.Values) { if ((foundOnJoint = line.FindNearestJoint(tri)) != null) { foundOnBranch = line; return(true); } } foundOnBranch = null; foundOnJoint = null; return(false); }
/// <summary> /// find nb triangle that has the same edgeLine /// </summary> /// <param name="tri"></param> /// <returns></returns> static bool FindSameCoordEdgeLine(AnalyzedTriangle 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(AnalyzedTriangle 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; } }
internal EdgeLine(AnalyzedTriangle ownerTriangle, Vertex p, Vertex q) { //this canbe inside edge or outside edge _ownerTriangle = ownerTriangle; //------------------------------------ //an edge line connects 2 glyph points. //it is created from triangulation process. // //some edge line is either 'INSIDE' edge OR 'OUTSIDE'. // //------------------------------------ _glyphPoint_P = p; _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; } } }
/// <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, AnalyzedTriangle triangle, EdgeLine knownInsideEdge) { ClassifyTriangleEdges( triangle, knownInsideEdge, out EdgeLine anotherInsideEdge, out EdgeLine outside0, out EdgeLine outside1, out EdgeLine outside2, out int 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); }
static InsideEdgeLine FindCommonInsideEdge(AnalyzedTriangle 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); }
/// <summary> /// find all outside edge a /// </summary> /// <param name="bone"></param> /// <param name="outsideEdges"></param> /// <returns></returns> public static void CollectOutsideEdge(this Bone bone, System.Collections.Generic.List <EdgeLine> outsideEdges) { if (bone.JointB != null) { AnalyzedTriangle 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 InsideEdgeLine(AnalyzedTriangle ownerTriangle, Vertex p, Vertex q) : base(ownerTriangle, p, q) { }
internal static bool ContainsTriangle(this EdgeLine edge, AnalyzedTriangle p) { return(p.e0 == edge || p.e1 == edge || p.e2 == edge); }
protected abstract void OnTriangle(AnalyzedTriangle tri);
static bool ContainsEdge(AnalyzedTriangle tri, EdgeLine edge) { return(tri.e0 == edge || tri.e1 == edge || tri.e2 == edge); }
static void CreateCentroidLineHubs(Polygon polygon, List <AnalyzedTriangle> triangles, List <CentroidLineHub> outputLineHubs) { int id = 0; foreach (DelaunayTriangle delnTri in polygon.Triangles) { delnTri.MarkAsActualTriangle(); triangles.Add(new AnalyzedTriangle(id, delnTri)); //all triangles are created from Triangulation process id++; } //---------------------------- //create centroid line hub //---------------------------- //1. var centroidLineHubs = new Dictionary <AnalyzedTriangle, CentroidLineHub>(); CentroidLineHub currentCentroidLineHub = null; //2. temporary list of used triangles List <AnalyzedTriangle> usedTriList = new List <AnalyzedTriangle>(); AnalyzedTriangle 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) { AnalyzedTriangle 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); AnalyzedTriangle 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 CentroidPair(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 CentroidPair(connectWithPrevTri, tri)); } latestTri = tri; } } } //-------------------------------------------------------------- //copy to list, we not use the centroidLineHubs anymore outputLineHubs.AddRange(centroidLineHubs.Values); }
// internal bool ComposeOf(AnalyzedTriangle tri) { return(this.P_Tri == tri || this.Q_Tri == tri); }
public CentroidLineHub(AnalyzedTriangle startTriangle) { _startTriangle = startTriangle; }
static void ClassifyTriangleEdges( AnalyzedTriangle 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; } } }
/// <summary> /// create a set of GlyphBone /// </summary> /// <param name="newlyCreatedBones"></param> public void CreateBones(List <Bone> newlyCreatedBones) { foreach (CentroidLine line in _lines.Values) { List <Joint> jointlist = line._joints; //start with empty bone list List <Bone> glyphBones = line.bones; int j = jointlist.Count; if (j == 0) { continue; } // Joint joint = jointlist[0]; //first { AnalyzedTriangle 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) { Bone tipBone = new Bone(joint, joint.TipEdgeP); newlyCreatedBones.Add(tipBone); glyphBones.Add(tipBone); } //----------------------------------------------------- if (i < j - 1) { //not the last one Joint nextJoint = jointlist[i + 1]; Bone bone = new Bone(joint, nextJoint); newlyCreatedBones.Add(bone); glyphBones.Add(bone); } if (joint.TipEdgeQ != null) { Bone tipBone = new Bone(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); // } //} } }