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); }
public Polygon2DDiviser(Polygon2D parent) { Parent = parent; SubDivision = new Polygon2DCollection(); Divisers = new LineSegment2DCollection(); InnerPoints = new Point2DCollection(); SubDivision.Add(Parent); }
public Polygon2D(Polygon2D polygon) { Vertices = new Point2DCollection(); Vertices.Clone(polygon.Vertices); SetStatus(); }
public Polygon2DAdorner(Polygon2D p) { polygon = p; triangles = new Triangle2DCollection(1); lineSegments = new LineSegment2DCollection(1); internalSegments = new Vector2DCollection(1); ghostTriangles = new GhostTriangle2DCollection(1); }
public GhostWeb(Polygon2D poly, GhostTriangle2DCollection ghostTriangles) { Polygon = poly; webNodes = new WebNode[poly.PointCount]; this.BuildGhostWeb(ghostTriangles); }
public Fliper(Polygon2D firstPolygon, Polygon2D secondPolygon) { if (firstPolygon.VertexCount != secondPolygon.VertexCount) { throw (new ArgumentException()); } this.FirstPolygon = firstPolygon; this.SecondPolygon = secondPolygon; }
public CompatibleDiviser(Polygon2D a, Polygon2D b) { this.firstPolygon = a; this.secondPolygon = b; this.firstPolygonCollection = new Polygon2DCollection(); this.secondPolygonCollection = new Polygon2DCollection(); targetDiviser = new TargetDiviser(b); }
public Polygon2DCollection(Polygon2D[] polygons, int capacity) { Capacity = capacity; CurrentCount = polygons.Length; if (Capacity < CurrentCount) { throw (new CollectionCapacityException()); } Polygons = polygons; }
internal SurfaceFitter(Polygon2D a, Polygon2D b, GhostTriangle2DCollection ghost) { if (a.VertexCount != b.VertexCount) { throw (new ArgumentException()); } sourcePolygon = a; targetPolygon = b; ghostTriangles = ghost; }
public HighQualityTriangulator(Polygon2D a, Polygon2D b) { if (!a.isRegular && !b.isRegular) { throw (new ArgumentException()); } if (a.VertexCount != b.VertexCount) { throw (new ArgumentException()); } FirstPolygons = new Polygon2DDiviser(a); SecondPolygons = new Polygon2DDiviser(b); }
public Polygon2DLinkMaker(Polygon2D polygon, int a, int b) : base(polygon) { if (!polygon.isRegular) { throw (new ArgumentException()); } FirstPoint = polygon.GetPoint(a); LastPoint = polygon.GetPoint(b); LinkDivisers = new Point2DCollection(); //Partitions = new Polygon2DCollection(); //Partitions.Add(polygon); }
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 TriangleDiviser(Polygon2D a, Polygon2D b) { firstPolygon = a; secondPolygon = b; }
private bool isEdge(int a, int b,Polygon2D polygon) { if (Math.Abs(a - b) == 1 || Math.Abs(a - b) == polygon.VertexCount - 1) { return true; } else { return false; } }
/// <summary> /// Divide a sub polygon by a line segment. /// </summary> /// <param name="lineSegment">the line segment.</param> /// <param name="poly">the polygon to divide.</param> /// <returns>one of the sub polygon divided from the polygon.</returns> internal Polygon2D DividedBy(LineSegment2D lineSegment, Polygon2D poly) { if (poly.isDiagonal(lineSegment)) { int a = poly.HasVertex(lineSegment.FirstPoint); int b = poly.HasVertex(lineSegment.LastPoint); if (a > b) { int tmp = a; a = b; b = tmp; } Point2DCollection p2 = new Point2DCollection(b - a + 1); Point2DCollection p1 = new Point2DCollection(poly.VertexCount - p2.Size + 2); for (int i = 0; i < poly.VertexCount; i++) { if (i <= a || i >= b) { p1.Add(poly.GetPoint(i)); } if (i >= a && i <= b) { p2.Add(poly.GetPoint(i)); } } if (p1.Count > p2.Count) { SubDivision.Add(new Polygon2D(p1)); return new Polygon2D(p2); } else { SubDivision.Add(new Polygon2D(p2)); return new Polygon2D(p1); } } else if (lineSegment.Intersects(poly)) { Point2DCollection Points = new Point2DCollection(2); for (int i = 0; i < poly.VertexCount; i++) { LineSegment2D border = poly.GetEdge(i); Point2D p = lineSegment.GetIntersectPoint(border); if (p.isRegular) { Points.DistinctAdd(p); } } Debug.Assert(Points.Count == 2); if (poly.HasVertex(Points[0]) == Polygon2D.NoSuchPoint) { poly.Add(Points[0], poly.OnEdge(Points[0])); Parent.AddInner(Points[0]); this.InnerPoints.DistinctAdd(Points[0]); } if (poly.HasVertex(Points[1]) == Polygon2D.NoSuchPoint) { poly.Add(Points[1], poly.OnEdge(Points[1])); Parent.AddInner(Points[1]); this.InnerPoints.DistinctAdd(Points[1]); } LineSegment2D line = new LineSegment2D(Points[0], Points[1]); return DividedBy(line, poly); } else { return poly; } }
/// <summary> /// Divide a polygon by a path.(point2DCollection) /// </summary> /// <param name="path">the path.</param> /// <param name="polygon">the polygon to divide.</param> public void DividedBy(Point2DCollection path, Polygon2D polygon) { int a = polygon.HasVertex(path.FirstPoint); int b = polygon.HasVertex(path.LastPoint); if (a == Polygon2D.NoSuchPoint || b == Polygon2D.NoSuchPoint) { throw (new ArgumentException()); } if (a > b) { int tmp = a; a = b; b = tmp; } Point2DCollection p2 = new Point2DCollection(); Point2DCollection p1 = new Point2DCollection(); for (int i = 0; i < polygon.VertexCount; i++) { if (i <= a || i >= b) { p1.Add(polygon.GetPoint(i)); } if (i >= a && i <= b) { p2.Add(polygon.GetPoint(i)); } } for (int i = 1; i < path.Count - 1; i++) { p1.Add(path[i], a + i); p2.Add(path[i], 0); Parent.AddInner(path[i]); } if (p1.Count > p2.Count) { SubDivision.Add(new Polygon2D(p1)); SubDivision.Add(new Polygon2D(p2)); } else { SubDivision.Add(new Polygon2D(p2)); SubDivision.Add(new Polygon2D(p1)); } }
/// <summary> /// Divide a sub polygon by a line segment. /// </summary> /// <param name="lineSegment">the line segment.</param> /// <param name="poly">the polygon to divide.</param> /// <returns>one of the sub polygon divided from the polygon.</returns> internal Polygon2D DividedBy(LineSegment2D lineSegment, Polygon2D poly) { if (poly.isDiagonal(lineSegment)) { int a = poly.HasVertex(lineSegment.FirstPoint); int b = poly.HasVertex(lineSegment.LastPoint); if (a > b) { int tmp = a; a = b; b = tmp; } Point2DCollection p2 = new Point2DCollection(b - a + 1); Point2DCollection p1 = new Point2DCollection(poly.VertexCount - p2.Size + 2); for (int i = 0; i < poly.VertexCount; i++) { if (i <= a || i >= b) { p1.Add(poly.GetPoint(i)); } if (i >= a && i <= b) { p2.Add(poly.GetPoint(i)); } } if (p1.Count > p2.Count) { SubDivision.Add(new Polygon2D(p1)); return(new Polygon2D(p2)); } else { SubDivision.Add(new Polygon2D(p2)); return(new Polygon2D(p1)); } } else if (lineSegment.Intersects(poly)) { Point2DCollection Points = new Point2DCollection(2); for (int i = 0; i < poly.VertexCount; i++) { LineSegment2D border = poly.GetEdge(i); Point2D p = lineSegment.GetIntersectPoint(border); if (p.isRegular) { Points.DistinctAdd(p); } } Debug.Assert(Points.Count == 2); if (poly.HasVertex(Points[0]) == Polygon2D.NoSuchPoint) { poly.Add(Points[0], poly.OnEdge(Points[0])); Parent.AddInner(Points[0]); this.InnerPoints.DistinctAdd(Points[0]); } if (poly.HasVertex(Points[1]) == Polygon2D.NoSuchPoint) { poly.Add(Points[1], poly.OnEdge(Points[1])); Parent.AddInner(Points[1]); this.InnerPoints.DistinctAdd(Points[1]); } LineSegment2D line = new LineSegment2D(Points[0], Points[1]); return(DividedBy(line, poly)); } else { return(poly); } }
private void Initialize() { this.MoveTimer.Stop(); this.splitingMenuItem1.Checked = true; this.subDivisionMenuItem.Checked = true; this.flippingMenuItem1.Checked = true; this.areaBasedRemeshingMenuItem.Checked = true; this.competibleTriangulationMenuItem.Checked = true; StatusController.Triangulator = TriangulationTech.Simple; Polygon2D firstPolygon = new Polygon2D(new Point2DCollection()); LeftPolygon = new Polygon2DAdorner(firstPolygon); Polygon2D secondPolygon = new Polygon2D(new Point2DCollection()); RightPolygon = new Polygon2DAdorner(secondPolygon); this.triangulationMenuItem.Enabled = false; StatusController.canAddPoint = true; this.toolBarButton4.Enabled = true; this.toolBarButton4.Pushed = true; this.toolBar1.Buttons[5].Enabled = false; StatusController.LeftZoom.ratio = 1.0; StatusController.LeftZoom.Offset = new PointF(0.0F, -30.0F); StatusController.RightZoom.ratio = 1.0; StatusController.RightZoom.Offset = new PointF(0.0F, -30.0F); this.statusBarPanel1.Text = this.GetPolygonStatus(new Point2D(1, 1)); this.statusBarPanel2.Text = "Hint Index : -1 "; this.Invalidate(); }
private void PolygonScroll(Polygon2D polygon) { Polygon2DEditor pe = new Polygon2DEditor(polygon); pe.Scroll(); }
internal static double TriangleQuality(GhostTriangle2D ghostTriangle, Polygon2D polygon) { return TriangleQuality(ghostTriangle.ToTriangle(polygon)); }
public Triangle2D ToTriangle(Polygon2D polygon) { Point2D a = polygon.GetPoint(this.A); Point2D b = polygon.GetPoint(this.B); Point2D c = polygon.GetPoint(this.C); return new Triangle2D(a, b, c); }
private void SetReverse(Polygon2D polygon) { for (int i = 0; i < polygon.VertexCount; i++) { Point2D point = polygon.GetPoint(i); if (this.Reverse < point.Y) { this.Reverse = point.Y; } } }
private Polygon2D BuildPolygon() { Polygon2D polygon = new Polygon2D(); Polygon2DEditor polygonEditor = new Polygon2DEditor(polygon); int j = 0; for (int i = 0; i < this.indices.Length; i++) { this.points[j].Y = this.Reverse - this.points[j].Y + XWFParser.Margin; polygonEditor.AddPoint(this.points[j]); j = this.indices[j]; } return polygon; }
public void Write(Polygon2D Polygon) { this.SetReverse(Polygon); XmlTextWriter xmlWriter = new XmlTextWriter(Path, Encoding.UTF8); xmlWriter.WriteStartDocument(true); xmlWriter.WriteStartElement("pn", "Polygon", "urn:Microsoft.VS.Akira.Triangulations"); xmlWriter.WriteStartElement("pn:Coordinate"); xmlWriter.WriteStartAttribute("", "type", ""); xmlWriter.WriteString("Reversed"); xmlWriter.WriteEndAttribute(); xmlWriter.WriteStartAttribute("", "top", ""); xmlWriter.WriteString(this.Reverse.ToString()); xmlWriter.WriteEndAttribute(); xmlWriter.WriteStartAttribute("", "margin", ""); xmlWriter.WriteString(XWFParser.Margin.ToString()); xmlWriter.WriteEndAttribute(); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("pn:Vertices"); xmlWriter.WriteStartAttribute("","count",""); xmlWriter.WriteString(Polygon.VertexCount.ToString()); xmlWriter.WriteEndAttribute(); for(int i = 0; i < Polygon.VertexCount; i++) { Point2D point = new Point2D(Polygon.GetPoint(i)); point.Y = this.Reverse + XWFParser.Margin - point.Y; xmlWriter.WriteStartElement("pn:Vertex"); xmlWriter.WriteStartAttribute("","index",""); xmlWriter.WriteString(i.ToString()); xmlWriter.WriteEndAttribute(); xmlWriter.WriteStartAttribute("","x",""); xmlWriter.WriteString(point.X.ToString()); xmlWriter.WriteEndAttribute(); xmlWriter.WriteStartAttribute("","y",""); xmlWriter.WriteString(point.Y.ToString()); xmlWriter.WriteEndAttribute(); xmlWriter.WriteStartAttribute("","z",""); xmlWriter.WriteString("0"); xmlWriter.WriteEndAttribute(); xmlWriter.WriteEndElement(); } xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("pn:Edges"); for (int i = 0; i < Polygon.VertexCount; i++) { xmlWriter.WriteStartElement("pn:Edge"); xmlWriter.WriteStartAttribute("","from",""); xmlWriter.WriteString(i.ToString()); xmlWriter.WriteEndAttribute(); xmlWriter.WriteStartAttribute("","to",""); xmlWriter.WriteString(((i+1) % Polygon.VertexCount).ToString()); xmlWriter.WriteEndAttribute(); xmlWriter.WriteEndElement(); } xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndDocument(); xmlWriter.Close(); }
public int GetParentIndex(int PointIndex, int SubIndex) { Polygon2D subPolygon = this.SubDivision[SubIndex]; return(this.Parent.GetPointIndex(subPolygon.GetPoint(PointIndex))); }
internal static double ShapeQuality(GhostTriangle2D ghostTriangle, Polygon2D polygon) { Triangle2D triangle = ghostTriangle.ToTriangle(polygon); return ShapeQuality(triangle); }
/// <summary> /// Divide the source polygon to compute link distance. /// </summary> public void Divide() { LineSegment2D entrance = this.LastDiviser; LineSegment2D path = new LineSegment2D(entrance.FirstPoint, this.LastPoint); if (this.CurrentPolygon.Contains(path)) { return; } path = new LineSegment2D(entrance.LastPoint, this.LastPoint); if (this.CurrentPolygon.Contains(path)) { return; } for (int i = 0; i < this.CurrentPolygon.VertexCount; i++) { if (this.CurrentPolygon.GetPoint(i) == entrance.FirstPoint) { continue; } LineSegment2D lineSegment = new LineSegment2D(entrance.FirstPoint, this.CurrentPolygon.GetPoint(i)); if (!this.CurrentPolygon.Contains(lineSegment) && !this.CurrentPolygon.isEdge(lineSegment)) { continue; } LineSegment2D lineDiviser = this.ChooseDiviser(lineSegment); if (lineDiviser == null) { continue; } Polygon2D testPoly = new Polygon2D(this.CurrentPolygon); if (!testPoly.isVertex(lineDiviser.LastPoint)) { testPoly.Add(lineDiviser.LastPoint, testPoly.OnEdge(lineDiviser.LastPoint)); } Polygon2D polygon = this.DividedBy(lineDiviser, testPoly); if (polygon.isVertex(this.LastPoint)) { testPoly = this.CurrentPolygon; this.SubDivision.Remove(this.SubDivision.Count - 1); } else { testPoly = polygon; polygon = this.CurrentPolygon; this.SubDivision.Remove(this.SubDivision.Count - 1); } if (entrance.FirstPoint == entrance.LastPoint) { this.SubDivision.Remove(this.SubDivision.Count - 1); this.SubDivision.Add(testPoly); this.SubDivision.Add(polygon); } else { LineSegment2D testLine = new LineSegment2D(entrance.LastPoint, lineDiviser.FirstPoint); if (!testLine.isRegular) { entrance = new LineSegment2D(entrance.LastPoint, entrance.LastPoint); continue; } if (this.CurrentPolygon.Contains(testLine)) { testLine = this.ChooseDiviser(testLine); if (testLine != null && !testPoly.Contains(testLine)) { lineDiviser = testLine; testPoly = new Polygon2D(this.CurrentPolygon); if (!testPoly.isVertex(lineDiviser.LastPoint)) { testPoly.Add(lineDiviser.LastPoint, testPoly.OnEdge(lineDiviser.LastPoint)); } polygon = this.DividedBy(lineDiviser, testPoly); testPoly = this.CurrentPolygon; this.SubDivision.Remove(this.SubDivision.Count - 1); } else if (testLine == null) { continue; } } if (!polygon.isVertex(this.LastPoint)) { this.SubDivision.Remove(this.SubDivision.Count - 1); this.SubDivision.Add(polygon); this.SubDivision.Add(testPoly); } else { this.SubDivision.Remove(this.SubDivision.Count - 1); this.SubDivision.Add(testPoly); this.SubDivision.Add(polygon); } } this.Divisers.Add(lineDiviser); this.Divide(); return; } }
public Polygon2DEditor(Polygon2D polygon) { Polygon = polygon; }
/// <summary> /// Construct a minimum link path of a polygon. /// </summary> public void BuildPath() { this.LinkDivisers.Clear(); Point2D CurrentPoint = this.LastPoint; Point2D IntersectPoint = null; LineSegment2D CurrentLine = null; LineSegment2D IntersectLine = null; for (int i = this.Divisers.Count - 1; i >= 0; i--) { double position = -1.0; Polygon2D currentPolygon = this.SubDivision[i + 1]; CurrentLine = this.Divisers[i]; if (CurrentLine.Contains(CurrentPoint)) { this.LinkDivisers.Add(CurrentPoint); Vector2D vector = CurrentLine.ToVector().Normal().Normalize(); IntersectPoint = CurrentLine.MidPoint + vector; if (!this.SubDivision[i].Contains(IntersectPoint)) { vector = -vector; } double length = CurrentLine.Length; LineSegment2D testLine = null; do { IntersectPoint = CurrentLine.MidPoint + vector * length; length /= 2; testLine = new LineSegment2D(CurrentPoint, IntersectPoint); } while (!this.SubDivision[i].Contains(testLine)); continue; } for (int j = 0; j < currentPolygon.VertexCount; j++) { Point2D point = currentPolygon.GetPoint(j); if (CurrentPoint == point) { continue; } LineSegment2D lineSegment = new LineSegment2D(CurrentPoint, point); if (currentPolygon.Contains(lineSegment) || currentPolygon.isEdge(lineSegment)) { if (CurrentLine.LineIntersects(lineSegment)) { IntersectPoint = CurrentLine.ToLine().Intersects(lineSegment.ToLine()); if (position < 0) { position = CurrentLine.GetPosition(IntersectPoint); } else { position += CurrentLine.GetPosition(IntersectPoint); position /= 2; } } } } if (position < -0.5) { CurrentPoint = IntersectPoint + IntersectLine.ToVector().Normalize(); i++; continue; } this.LinkDivisers.Add(CurrentPoint); IntersectPoint = CurrentLine.GetPoint(position); IntersectLine = new LineSegment2D(CurrentPoint, IntersectPoint); double extend = IntersectLine.Length; do { extend /= 2; CurrentPoint = IntersectLine.Extend(extend); } while (!this.SubDivision[i].Contains(CurrentPoint)); //CurrentPoint = CurrentLine.GetPoint(position); } CurrentLine = new LineSegment2D(CurrentPoint, this.FirstPoint); if (this.Parent.Contains(CurrentLine)) { this.LinkDivisers.Add(CurrentPoint); this.LinkDivisers.Add(this.FirstPoint); } else if (IntersectLine != null) { CurrentPoint = IntersectPoint + IntersectLine.ToVector().Normalize(); this.LinkDivisers.Add(CurrentPoint); this.LinkDivisers.Add(this.FirstPoint); } else { Vector2D vector = CurrentLine.ToVector().Normal().Normalize(); IntersectPoint = CurrentLine.MidPoint + vector; if (!this.Parent.Contains(IntersectPoint)) { vector = -vector; } IntersectPoint = CurrentLine.MidPoint; double length = CurrentLine.Length; do { length /= 2; CurrentPoint = IntersectPoint + vector * length; }while (!this.Parent.Contains(CurrentPoint)); this.LinkDivisers.Add(this.LastPoint); this.LinkDivisers.Add(CurrentPoint); this.LinkDivisers.Add(this.FirstPoint); } }
private void Restart() { this.FileName = null; this.Clear(); StatusController.canRestart = true; polygonLinkAdorner = null; if (StatusController.availablePartition == Partition.Left) { Polygon2D firstPolygon = new Polygon2D(new Point2DCollection()); LeftPolygon = new Polygon2DAdorner(firstPolygon); } else { Polygon2D secondPolygon = new Polygon2D(new Point2DCollection()); RightPolygon = new Polygon2DAdorner(secondPolygon); } this.triangulationMenuItem.Enabled = false; StatusController.canAddPoint = true; this.toolBarButton4.Enabled = true; this.toolBarButton4.Pushed = true; this.toolBar1.Buttons[5].Enabled = false; StatusController.LeftZoom.ratio = 1.0; StatusController.LeftZoom.Offset = new PointF(0.0F, -30.0F); StatusController.RightZoom.ratio = 1.0; StatusController.RightZoom.Offset = new PointF(0.0F, -30.0F); this.statusBarPanel1.Text = this.GetPolygonStatus(new Point2D(1,1)); this.statusBarPanel2.Text = "Hint Index : -1 "; this.Invalidate(); }
internal Rebuild(Polygon2D poly) { polygon = new Polygon2D(poly); ghostTriangles = new GhostTriangle2DCollection(); }
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> /// Whether ths line segment intersects a polygon. /// </summary> /// <param name="polygon">the polygon.</param> /// <returns>true if intersects.</returns> public bool Intersects(Polygon2D polygon) { bool bResult = false; for (int i = 0; i < polygon.VertexCount; i++) { LineSegment2D lineSegment = polygon.GetEdge(i); //bResult |= this.TrulyIntersects(polygon.GetEdge(i)); bResult |= (this.TrulyLineIntersects(lineSegment) && lineSegment.Intersects(this)); if (bResult) { return true; } } return bResult; }
private GhostWeb(Polygon2D poly) { Polygon = poly; webNodes = new WebNode[poly.PointCount]; }