public void Analyze() { //we analyze each triangle here int j = _triangles.Count; bones = new List <GlyphBone>(); List <GlyphTriangle> usedTriList = new List <GlyphTriangle>(); for (int i = 0; i < j; ++i) { GlyphTriangle tri = _triangles[i]; if (i > 0) { //check the new tri is connected with latest tri or not? int foundIndex = FindLatestConnectedTri(usedTriList, tri); if (foundIndex > -1) { usedTriList.Add(tri); bones.Add(new GlyphBone(usedTriList[foundIndex], tri)); } else { //not found //? } } else { usedTriList.Add(tri); } } if (j > 1) { //connect the last tri to the first tri //if it is connected GlyphTriangle firstTri = _triangles[0]; GlyphTriangle lastTri = _triangles[j - 1]; if (firstTri.IsConnectedWith(lastTri)) { bones.Add(new GlyphBone(lastTri, firstTri)); } } //---------------------------------------- int boneCount = bones.Count; for (int i = 0; i < boneCount; ++i) { //each bone has 2 triangles at its ends //we analyze both triangles' roles //eg... //left -right //top-bottom GlyphBone bone = bones[i]; bone.Analyze(); } //---------------------------------------- }
static int OutSideCount(GlyphTriangle t) { int n = 0; n += t.e0.IsOutside ? 1 : 0; n += t.e1.IsOutside ? 1 : 0; n += t.e2.IsOutside ? 1 : 0; return(n); }
int FindLatestConnectedTri(List <GlyphTriangle> usedTriList, GlyphTriangle tri) { //search back *** for (int i = usedTriList.Count - 1; i >= 0; --i) { GlyphTriangle t = usedTriList[i]; if (t.IsConnectedWith(tri)) { return(i); } } return(-1); }
public bool IsConnectedWith(GlyphTriangle anotherTri) { DelaunayTriangle t2 = anotherTri._tri; if (t2 == this._tri) { throw new NotSupportedException(); } //else return(this._tri.N0 == t2 || this._tri.N1 == t2 || this._tri.N2 == t2); }
static GlyphFitOutline TessWithPolyTri(List <GlyphContour> contours) { List <Poly2Tri.TriangulationPoint> points = new List <Poly2Tri.TriangulationPoint>(); int cntCount = contours.Count; GlyphContour cnt = contours[0]; Poly2Tri.Polygon polygon = CreatePolygon2(contours[0]);//first contour bool isHoleIf = !cnt.IsClockwise; //if (cntCount > 0) //{ // //debug only for (int n = 1; n < cntCount; ++n) { cnt = contours[n]; //IsHole is correct after we Analyze() the glyph contour polygon.AddHole(CreatePolygon2(cnt)); //if (cnt.IsClockwise == isHoleIf) //{ // polygon.AddHole(CreatePolygon2(cnt)); //} //else //{ // //eg i // //the is a complete separate dot (i head) over i body //} } //} //------------------------------------------ Poly2Tri.P2T.Triangulate(polygon); //that poly is triangulated GlyphFitOutline glyphFitOutline = new GlyphFitOutline(polygon, contours); glyphFitOutline.Analyze(); //------------------------------------------ #if DEBUG List <GlyphTriangle> triAngles = glyphFitOutline.dbugGetTriangles(); int triangleCount = triAngles.Count; for (int i = 0; i < triangleCount; ++i) { //--------------- GlyphTriangle tri = triAngles[i]; AssignPointEdgeInvolvement(tri.e0); AssignPointEdgeInvolvement(tri.e1); AssignPointEdgeInvolvement(tri.e2); } #endif return(glyphFitOutline); }
static bool FindMatchingOuterSide(EdgeLine compareEdge, GlyphTriangle another, out EdgeLine result, out int edgeIndex) { //compare by radian of edge line double compareSlope = Math.Abs(compareEdge.SlopAngle); double diff0 = double.MaxValue; double diff1 = double.MaxValue; double diff2 = double.MaxValue; diff0 = Math.Abs(Math.Abs(another.e0.SlopAngle) - compareSlope); diff1 = Math.Abs(Math.Abs(another.e1.SlopAngle) - compareSlope); diff2 = Math.Abs(Math.Abs(another.e2.SlopAngle) - compareSlope); //find min int minDiffSide = FindMinIndex(diff0, diff1, diff2); if (minDiffSide > -1) { edgeIndex = minDiffSide; switch (minDiffSide) { default: throw new NotSupportedException(); case 0: result = another.e0; break; case 1: result = another.e1; break; case 2: result = another.e2; break; } return(true); } else { edgeIndex = -1; result = null; return(false); } }
static void MarkMatchingEdge(EdgeLine targetEdge, GlyphTriangle q) { EdgeLine matchingEdgeLine; int matchingEdgeSideNo; if (FindMatchingOuterSide(targetEdge, q, out matchingEdgeLine, out matchingEdgeSideNo)) { //assign matching edge line //mid point of each edge //p-triangle's edge midX,midY double pe_midX, pe_midY; CalculateMidPoint(targetEdge, out pe_midX, out pe_midY); //q-triangle's edge midX,midY double qe_midX, qe_midY; CalculateMidPoint(matchingEdgeLine, out qe_midX, out qe_midY); if (targetEdge.SlopKind == LineSlopeKind.Vertical) { //TODO: review same side edge (Fan shape) if (pe_midX < qe_midX) { targetEdge.IsLeftSide = true; if (matchingEdgeLine.IsOutside && matchingEdgeLine.SlopKind == LineSlopeKind.Vertical) { targetEdge.AddMatchingOutsideEdge(matchingEdgeLine); } } else { //matchingEdgeLine.IsLeftSide = true; if (matchingEdgeLine.IsOutside && matchingEdgeLine.SlopKind == LineSlopeKind.Vertical) { targetEdge.AddMatchingOutsideEdge(matchingEdgeLine); } } } else if (targetEdge.SlopKind == LineSlopeKind.Horizontal) { //TODO: review same side edge (Fan shape) if (pe_midY > qe_midY) { //p side is upper , q side is lower if (targetEdge.SlopKind == LineSlopeKind.Horizontal) { targetEdge.IsUpper = true; if (matchingEdgeLine.IsOutside && matchingEdgeLine.SlopKind == LineSlopeKind.Horizontal) { targetEdge.AddMatchingOutsideEdge(matchingEdgeLine); } } } else { if (matchingEdgeLine.SlopKind == LineSlopeKind.Horizontal) { // matchingEdgeLine.IsUpper = true; if (matchingEdgeLine.IsOutside && matchingEdgeLine.SlopKind == LineSlopeKind.Horizontal) { targetEdge.AddMatchingOutsideEdge(matchingEdgeLine); } } } } } }
public GlyphBone(GlyphTriangle p, GlyphTriangle q) { this.p = p; this.q = q; }