internal static double CompatibleTriangleQuality(GhostTriangle2D ghostTriangle, Polygon2D firstPolygon, Polygon2D secondPolygon) { double d1 = TriangleQuality(ghostTriangle.ToTriangle(firstPolygon)); double d2 = TriangleQuality(ghostTriangle.ToTriangle(secondPolygon)); return Math.Min(d1, d2); }
internal void Flipping(GhostTriangle2DCollection ghostTriangles) { for (int i = 0; i < ghostTriangles.Count; i++) { for (int j = i; j < ghostTriangles.Count; j++) { GhostTriangle2D t1 = ghostTriangles[i]; GhostTriangle2D t2 = ghostTriangles[j]; if (isNeighbor(t1, t2)) { Polygon2D p1 = FlipArea(t1, t2, this.FirstPolygon); Polygon2D p2 = FlipArea(t1, t2, this.SecondPolygon); if (p1.isConvex && p2.isConvex) { double d1 = QualityDeterminer.CompatibleTriangleQuality(t1, this.FirstPolygon, this.SecondPolygon); double d2 = QualityDeterminer.CompatibleTriangleQuality(t2, this.FirstPolygon, this.SecondPolygon); double d = Math.Min(d1, d2); FlipGhostTriangle(t1, t2); d1 = QualityDeterminer.CompatibleTriangleQuality(t1, this.FirstPolygon, this.SecondPolygon); d2 = QualityDeterminer.CompatibleTriangleQuality(t2, this.FirstPolygon, this.SecondPolygon); if (d > Math.Min(d1, d2)) { FlipGhostTriangle(t1, t2); } } } } } }
static internal double CompatibleTriangleQuality(GhostTriangle2D ghostTriangle, Polygon2D firstPolygon, Polygon2D secondPolygon) { double d1 = TriangleQuality(ghostTriangle.ToTriangle(firstPolygon)); double d2 = TriangleQuality(ghostTriangle.ToTriangle(secondPolygon)); return(Math.Min(d1, d2)); }
public void Union(GhostTriangle2DCollection ghostTriangle2DCollection) { Capacity += ghostTriangle2DCollection.Capacity; GhostTriangle2D[] ghostTriangles = new GhostTriangle2D[Capacity]; this.GhostTriangles.CopyTo(ghostTriangles, 0); ghostTriangle2DCollection.GhostTriangles.CopyTo(ghostTriangles, this.Count); this.GhostTriangles = ghostTriangles; CurrentCount += ghostTriangle2DCollection.Count; }
private GhostTriangle2D Split(GhostTriangle2D ghostTriangle) { if (QualityDeterminer.TriangleQuality(ghostTriangle, firstPolygon) < QualityDeterminer.TriangleQuality(ghostTriangle, secondPolygon)) { return(Split(this.firstPolygon, this.secondPolygon, ghostTriangle)); } else { return(Split(this.secondPolygon, this.firstPolygon, ghostTriangle)); } }
private void FlipGhostTriangle(GhostTriangle2D a, GhostTriangle2D b) { if (!isNeighbor(a, b)) { throw (new ArgumentException()); } Map(a, b); a.A = b.C; b.B = a.C; }
private void Divide(GhostTriangle2D ghostTriangle) { Triangle2D triangle = ghostTriangle.ToTriangle(firstPolygon); Point2D point = (triangle.A + triangle.B.ToVector() + triangle.C.ToVector()) / 3; Polygon2DEditor polygonEditor = new Polygon2DEditor(firstPolygon); polygonEditor.AddInnerPoint(point); triangle = ghostTriangle.ToTriangle(secondPolygon); point = (triangle.A + triangle.B.ToVector() + triangle.C.ToVector()) / 3; polygonEditor = new Polygon2DEditor(secondPolygon); polygonEditor.AddInnerPoint(point); }
private void Triangulation(int a, int b, int c) { Debug.Assert(a != b && b != c && c != a); Triangle2D triangle = new Triangle2D(this.polygon.GetPoint(a), this.polygon.GetPoint(b), this.polygon.GetPoint(c)); GhostTriangle2D ghost = new GhostTriangle2D(a, b, c); this.triangles.Add(triangle); this.ghostTriangles.Add(ghost); if (lineSegments.Count < polygon.VertexCount - 3) { Vector2D internalSegment = new Vector2D(a, c); LineSegment2D lineSegment = new LineSegment2D(this.polygon.GetPoint(a), this.polygon.GetPoint(c)); this.lineSegments.Add(lineSegment); this.internalSegments.Add(internalSegment); } }
private void SplitGhostTriangle(GhostTriangle2DCollection ghostTriangles, GhostTriangle2D ghostTriangle) { int Count = ghostTriangles.Count; for (int i = 0; i < Count; i++) { if (isNeighbor(ghostTriangles[i], ghostTriangle)) { Map(ghostTriangles[i], ghostTriangle); GhostTriangle2D triangle = new GhostTriangle2D(ghostTriangles[i].A, ghostTriangles[i].C, ghostTriangle.C); ghostTriangles.Add(triangle); ghostTriangles[i].A = ghostTriangle.C; } } }
private bool isNeighbor(GhostTriangle2D a, GhostTriangle2D b) { int i = 0; if (a.A == b.A || a.A == b.B || a.A == b.C) { i++; } if (a.B == b.A || a.B == b.B || a.B == b.C) { i++; } if (a.C == b.A || a.C == b.B || a.C == b.C) { i++; } return(i == 2); }
internal void Split(GhostTriangle2DCollection ghostTriangles) { int Count = ghostTriangles.Count; for (int i = 0; i < Count; i++) { Triangle2D t1 = ghostTriangles[i].ToTriangle(firstPolygon); Triangle2D t2 = ghostTriangles[i].ToTriangle(secondPolygon); double d1 = QualityDeterminer.ShapeQuality(t1); double d2 = QualityDeterminer.ShapeQuality(t2); if (d1 < TriangleDiviser.ShapeTolerance || d2 < TriangleDiviser.ShapeTolerance) { GhostTriangle2D ghostTriangle = Split(ghostTriangles[i]); SplitGhostTriangle(ghostTriangles, ghostTriangle); } } }
private Polygon2D FlipArea(GhostTriangle2D a, GhostTriangle2D b, Polygon2D poly) { if (!isNeighbor(a, b)) { throw (new ArgumentException()); } Map(a, b); Point2DCollection points = new Point2DCollection(4); points.Add(poly.GetPoint(a.C)); points.Add(poly.GetPoint(a.A)); points.Add(poly.GetPoint(b.C)); points.Add(poly.GetPoint(b.B)); Polygon2D polygon = new Polygon2D(points); return polygon; }
private GhostTriangle2D Split(Polygon2D first, Polygon2D second, GhostTriangle2D ghostTriangle) { Triangle2D triangle = ghostTriangle.ToTriangle(first); LineSegment2D splitLine = Max(triangle.AB, triangle.BC, triangle.AC); int a = first.GetPointIndex(splitLine.FirstPoint); int b = first.GetPointIndex(splitLine.LastPoint); Point2D p1 = splitLine.MidPoint; splitLine = new LineSegment2D(second.GetPoint(a), second.GetPoint(b)); Point2D p2 = splitLine.MidPoint; Polygon2DEditor polygonEditor = new Polygon2DEditor(first); polygonEditor.AddInnerPoint(p1); polygonEditor = new Polygon2DEditor(second); polygonEditor.AddInnerPoint(p2); return(new GhostTriangle2D(a, b, first.PointCount - 1)); }
/// <summary> /// Make a.A == b.A && a.B == b.B && a.C != b.C /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void Map(GhostTriangle2D a, GhostTriangle2D b) { if (!isNeighbor(a, b)) { return; } int tmp; if (a.A != b.A && a.A != b.B && a.A != b.C) { tmp = a.A; a.A = a.C; a.C = tmp; } if (b.B == a.A) { tmp = b.B; b.B = b.A; b.A = tmp; } else if (b.C == a.A) { tmp = b.C; b.C = b.A; b.A = tmp; } if (a.B != b.A && a.B != b.B && a.B != b.C) { tmp = a.B; a.B = a.C; a.C = tmp; } if (b.C == a.B) { tmp = b.C; b.C = b.B; b.B = tmp; } }
private Polygon2D FlipArea(GhostTriangle2D a, GhostTriangle2D b, Polygon2D poly) { if (!isNeighbor(a, b)) { throw (new ArgumentException()); } Map(a, b); Point2DCollection points = new Point2DCollection(4); points.Add(poly.GetPoint(a.C)); points.Add(poly.GetPoint(a.A)); points.Add(poly.GetPoint(b.C)); points.Add(poly.GetPoint(b.B)); Polygon2D polygon = new Polygon2D(points); return(polygon); }
public void Add(GhostTriangle2D ghostTriangle) { try { base.Add(); } catch (CollectionCapacityException e) { string emsg = e.Message; this.Capacity *= 2; GhostTriangle2D[] ghostTriangles = new GhostTriangle2D[Capacity]; this.GhostTriangles.CopyTo(ghostTriangles, 0); this.GhostTriangles = ghostTriangles; base.Add(); } GhostTriangles[CurrentCount - 1] = ghostTriangle; }
internal void Divide(GhostTriangle2DCollection ghostTriangles) { int Count = ghostTriangles.Count; for (int i = 0; i < Count; i++) { if (QualityDeterminer.AreaQuality(ghostTriangles[i], firstPolygon) < AreaTolerance || QualityDeterminer.AreaQuality(ghostTriangles[i], secondPolygon) < AreaTolerance) { Divide(ghostTriangles[i]); GhostTriangle2D ghostTriangle = new GhostTriangle2D(ghostTriangles[i].A, ghostTriangles[i].B, this.firstPolygon.PointCount - 1); ghostTriangles.Add(ghostTriangle); ghostTriangle = new GhostTriangle2D(ghostTriangles[i].A, this.firstPolygon.PointCount - 1, ghostTriangles[i].C); ghostTriangles.Add(ghostTriangle); ghostTriangles[i].A = this.firstPolygon.PointCount - 1; } } }
internal void Divide(GhostTriangle2DCollection ghostTriangles) { int Count = ghostTriangles.Count; for (int i = 0; i < Count; i++) { if(QualityDeterminer.AreaQuality(ghostTriangles[i], firstPolygon) < AreaTolerance|| QualityDeterminer.AreaQuality(ghostTriangles[i], secondPolygon) < AreaTolerance) { Divide(ghostTriangles[i]); GhostTriangle2D ghostTriangle = new GhostTriangle2D(ghostTriangles[i].A, ghostTriangles[i].B, this.firstPolygon.PointCount - 1); ghostTriangles.Add(ghostTriangle); ghostTriangle = new GhostTriangle2D(ghostTriangles[i].A, this.firstPolygon.PointCount - 1, ghostTriangles[i].C); ghostTriangles.Add(ghostTriangle); ghostTriangles[i].A = this.firstPolygon.PointCount - 1; } } }
private bool isNeighbor(GhostTriangle2D a, GhostTriangle2D b) { int i = 0; if (a.A == b.A || a.A == b.B || a.A == b.C) { i++; } if (a.B == b.A || a.B == b.B || a.B == b.C) { i++; } if (a.C == b.A || a.C == b.B || a.C == b.C) { i++; } return i == 2; }
internal static double TriangleQuality(GhostTriangle2D ghostTriangle, Polygon2D polygon) { return TriangleQuality(ghostTriangle.ToTriangle(polygon)); }
internal static double ShapeQuality(GhostTriangle2D ghostTriangle, Polygon2D polygon) { Triangle2D triangle = ghostTriangle.ToTriangle(polygon); return ShapeQuality(triangle); }
static internal double TriangleQuality(GhostTriangle2D ghostTriangle, Polygon2D polygon) { return(TriangleQuality(ghostTriangle.ToTriangle(polygon))); }
private GhostTriangle2D Split(Polygon2D first, Polygon2D second, GhostTriangle2D ghostTriangle) { Triangle2D triangle = ghostTriangle.ToTriangle(first); LineSegment2D splitLine = Max(triangle.AB, triangle.BC, triangle.AC); int a = first.GetPointIndex(splitLine.FirstPoint); int b = first.GetPointIndex(splitLine.LastPoint); Point2D p1 = splitLine.MidPoint; splitLine = new LineSegment2D(second.GetPoint(a), second.GetPoint(b)); Point2D p2 = splitLine.MidPoint; Polygon2DEditor polygonEditor = new Polygon2DEditor(first); polygonEditor.AddInnerPoint(p1); polygonEditor = new Polygon2DEditor(second); polygonEditor.AddInnerPoint(p2); return new GhostTriangle2D(a, b, first.PointCount - 1); }
private GhostTriangle2D Split(GhostTriangle2D ghostTriangle) { if (QualityDeterminer.TriangleQuality(ghostTriangle, firstPolygon) < QualityDeterminer.TriangleQuality(ghostTriangle, secondPolygon)) { return Split(this.firstPolygon, this.secondPolygon, ghostTriangle); } else { return Split(this.secondPolygon, this.firstPolygon, ghostTriangle); } }
public GhostTriangle2DCollection(GhostTriangle2D[] ghostTriangles) { Capacity = ghostTriangles.Length; GhostTriangles = ghostTriangles; CurrentCount = Capacity; }
public GhostTriangle2DCollection(GhostTriangle2D[] ghostTriangles, int capacity) { Capacity = capacity; CurrentCount = ghostTriangles.Length; if (Capacity < CurrentCount) { throw (new CollectionCapacityException()); } GhostTriangles = ghostTriangles; }
static internal double AreaQuality(GhostTriangle2D ghostTriangle, Polygon2D polygon) { Triangle2D triangle = ghostTriangle.ToTriangle(polygon); return(AreaQuality(triangle)); }