public LineSegment2D(Point2D a, Point2D b) { PointPair = new Point2D[2]; PointPair[0] = a; PointPair[1] = b; }
public Point2DCollection(Point2D[] points, int capacity) { Capacity = capacity; CurrentCount = points.Length; if (Capacity < CurrentCount) { throw (new CollectionCapacityException()); } Points = points; }
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); }
public Point2D ConvertPoint2DFromString(string point) { Point2D point2D = new Point2D(); StringBuilder stringBuilder = new StringBuilder(point); stringBuilder.Remove(0, 1); stringBuilder.Remove(stringBuilder.Length - 1, 1); string[] s = stringBuilder.ToString().Split(','); point2D.X = double.Parse(s[0]); point2D.Y = double.Parse(s[1]); return point2D; }
public Point2D(Point2D p) : base(p) { }
public Point2D GetClosestPointOnLineSegment(Point2D a, Point2D b) { Point2D p = this.ParametrizationToLineSegment(a, b); return WeightedAverage(a, b, p.X); }
/// <summary> /// Make a parametrization to a line segment specified by two other points. /// </summary> /// <param name="a">the first point of the line segment.</param> /// <param name="b">the second point of the line segment.</param> /// <returns></returns> protected Point2D ParametrizationToLineSegment(Point2D a, Point2D b) { if (a == b) { throw new ArgumentException("The points defining the line are not distinct."); } else { Vector2D AB = b - a; Vector2D AP = this - a; Point2D p = new Point2D(); // x = AB * AP/|AB|^2 = |AP|cos<AB,AP>/|AB| p.X = Vector2D.Dot(AB, AP) / AB.SquaredLength; // y = |AB X AP|/|AB|^2 = |AP|sin<AB,AP>/|AB| p.Y = Vector2D.Determinant(AB, AP) / AB.SquaredLength; return p; } }
/// <summary> /// Get the parametres of the points on line segment. (between 0 t0 1) /// </summary> /// <param name="point">the point.</param> /// <returns>the parametre of the point on line segment.</returns> public double GetPosition(Point2D point) { if (point == FirstPoint) { return 0; } else if (point == LastPoint) { return 1; } else { Vector2D v1 = point - FirstPoint; Vector2D v2 = this.ToVector(); double d = Vector2D.Determinant(v1, v2); if (d < ZeroTolerance) { return v1.Length / v2.Length; } else if (d >= ZeroTolerance) { return double.PositiveInfinity; } else { return double.NegativeInfinity; } } }
private PointF[] GhostTriangleToPoints(int i) { Point2D[] points = new Point2D[3]; points[0] = this.polygon.GetPoint(this.ghostTriangles[i].A); points[1] = this.polygon.GetPoint(this.ghostTriangles[i].B); points[2] = this.polygon.GetPoint(this.ghostTriangles[i].C); PointF[] pointfs = new PointF[3]; pointfs[0] = new PointF((float)(points[0].X), (float)(points[0].Y)); pointfs[1] = new PointF((float)(points[1].X), (float)(points[1].Y)); pointfs[2] = new PointF((float)(points[2].X), (float)(points[2].Y)); return pointfs; }
protected override void OnMouseMove(MouseEventArgs e) { Point2D point = new Point2D(e.X, e.Y - 30); Polygon2DAdorner polygonAdorner = null; Partition part = OnPart(point); this.statusBarPanel1.Text = this.GetPolygonStatus(point); if (part == Partition.Left) { polygonAdorner = this.LeftPolygon; } else { point.X -= this.ClientSize.Width / 2; polygonAdorner = this.RightPolygon; } int i = StatusController.CatchPoint; if (i != -1) { this.Cursor = System.Windows.Forms.Cursors.Default; if (StatusController.availablePartition == part) { Polygon2DEditor pe = new Polygon2DEditor(polygonAdorner.polygon); pe.SetPoint(point, i); StatusController.canRestart = false; } this.Invalidate(); } else { i = polygonAdorner.HitTest(point); if (i == -1) { this.Cursor = System.Windows.Forms.Cursors.Default; } else { this.Cursor = System.Windows.Forms.Cursors.Cross; } this.statusBarPanel2.Text =point.ToString() + " " + "Hint Index : " + i.ToString() + " "; } if (StatusController.isZoomView) { PointF midPoint; if (part == Partition.Left) { midPoint = new PointF(this.ClientSize.Width / 4, this.ClientSize.Height / 2); } else { midPoint = new PointF(3 * this.ClientSize.Width / 4, this.ClientSize.Height / 2); } if (e.X < midPoint.X && e.Y < midPoint.Y) { this.Cursor = System.Windows.Forms.Cursors.PanNW; } else if (e.X > midPoint.X && e.Y < midPoint.Y) { this.Cursor = System.Windows.Forms.Cursors.PanNE; } else if (e.X < midPoint.X && e.Y > midPoint.Y) { this.Cursor = System.Windows.Forms.Cursors.PanSW; } else { this.Cursor = System.Windows.Forms.Cursors.PanSE; } } }
private string GetPolygonStatus(Point2D point) { StringBuilder status = new StringBuilder(); Polygon2D polygon = null; status.Append("Polygon:"); if (this.OnPart(point) == Partition.Left) { status.Append("Left "); polygon = this.FirstPolygon; } else { status.Append("Right "); polygon = this.SecondPolygon; } status.Append(polygon.VertexCount.ToString()); status.Append("(" + polygon.InnerPointCount.ToString() + ")"); status.Append(" points"); if (polygon.isRegular) { status.Append(" Regular"); } else { status.Append(" Not regular"); } if (polygon.isSimple) { status.Append(" Simple"); } else { status.Append(" Complex"); } if (polygon.isConvex) { status.Append(" Convex "); } else { status.Append(" Concave "); } status.Append(polygon.PointDirection.ToString()); if (StatusController.isZoomView) { int r = 0; if (this.OnPart(point) == Partition.Left) { r = (int)(100 / StatusController.LeftZoom.ratio); } else { r = (int)(100 / StatusController.RightZoom.ratio); } status.Append(" "); status.Append(r.ToString()); status.Append("% Zoom"); } return status.ToString(); }
/// <summary> /// Add an inner point to the polygon. /// </summary> /// <param name="point">the new inner point.</param> public void AddInnerPoint(Point2D point) { Polygon.AddInner(point); }
/// <summary> /// Add new point to the polygon. /// </summary> /// <param name="point">new point.</param> public void AddPoint(Point2D point) { Polygon.Add(point); }
private bool isRegular(int index, Point2D point) { WebNode Router = this.webNodes[index]; while (Router != null) { if (this.GetArea(Router.firstIndex, Router.secondIndex, point.X, point.Y) < GhostWeb.AreaTolerance) { return false; } Router = Router.Next; } return true; }
/// <summary> /// Reset a point of the polygon. /// </summary> /// <param name="point">the new point.</param> /// <param name="i">the point index.</param> public void SetPoint(Point2D point, int i) { Polygon.SetPoint(point, i); }
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(); }
/// <summary> /// Get the intersect point of the two lines. /// </summary> /// <param name="line">the other line.</param> /// <returns>the point.</returns> public Point2D Intersects(Line2D line) { if (this.GetPosition(line) != Position.Intersect) { //throw (new ArgumentException("The two lines cannot Intersects!")); return new Point2D(double.PositiveInfinity, double.PositiveInfinity); } Vector v1 = null; Vector v2 = null; if (Math.Abs(this.A) > Math.Abs(line.A)) { v1 = new Vector(this.vector); v2 = new Vector(line.vector); } else { v1 = new Vector(line.vector); v2 = new Vector(this.vector); } Vector v3 = new Vector(v1); v1 = Vector.Multiply(v2[0] / v1[0], v1); v1 = Vector.Subtract(v1, v2); v1 = Vector.Multiply(1/v1[1], v1); Point2D point = new Point2D(new Line2D(v3).GetX(-v1[2]), -v1[2]); if (!this.Contains(point) || !line.Contains(point)) { throw (new ArgumentException()); } return point; }
public void Write(Polygon2D polygon) { Stream stream = new FileStream(this.Path, FileMode.Create, FileAccess.Write, FileShare.None); string str = "# WFMESH2"; stream.Write(this.GetBytes(str), 0, str.Length); stream.WriteByte((byte)'\r'); stream.WriteByte((byte)'\n'); str = "# Created by Triangulator"; stream.Write(this.GetBytes(str), 0, str.Length); stream.WriteByte((byte)'\r'); stream.WriteByte((byte)'\n'); str = "# Vertices"; stream.Write(this.GetBytes(str), 0, str.Length); stream.WriteByte((byte)'\r'); stream.WriteByte((byte)'\n'); this.SetReverse(polygon); for (int i = 0; i < polygon.VertexCount; i++) { Point2D point = new Point2D(polygon.GetPoint(i)); point.Y = this.Reverse + WFParser.Margin - point.Y; str = point.X.ToString() + " " + point.Y.ToString() + " " + "0.00" + " " + i.ToString(); stream.Write(this.GetBytes(str), 0, str.Length); stream.WriteByte((byte)'\r'); stream.WriteByte((byte)'\n'); } stream.WriteByte((byte)'\r'); stream.WriteByte((byte)'\n'); str = "# Edges"; stream.Write(this.GetBytes(str), 0, str.Length); stream.WriteByte((byte)'\r'); stream.WriteByte((byte)'\n'); for (int i = 0; i < polygon.VertexCount - 1; i++) { str = i.ToString() + " " + (i + 1).ToString(); stream.Write(this.GetBytes(str), 0, str.Length); stream.WriteByte((byte)'\r'); stream.WriteByte((byte)'\n'); } str = (polygon.VertexCount - 1).ToString() + " 0"; stream.Write(this.GetBytes(str), 0, str.Length); stream.WriteByte((byte)'\r'); stream.WriteByte((byte)'\n'); stream.Close(); }
private Partition OnPart(Point2D point) { if (point.X < this.ClientSize.Width / 2) { return Partition.Left; } else { return Partition.Right; } }
/// <summary> /// Add new point to the polygon. /// </summary> /// <param name="point">new point.</param> /// <param name="i">point index.</param> public void AddPoint(Point2D point, int i) { Polygon.Add(point, i); }
protected override void OnMouseDown(MouseEventArgs e) { Point2D point = new Point2D(e.X, e.Y - 30); if (StatusController.availablePartition != OnPart(point)) { StatusController.availablePartition = OnPart(point); this.Invalidate(); return; } if (StatusController.isZoomView) { if (e.Button == MouseButtons.Left) { this.MoveTimer.Start(); if (OnPart(point) == Partition.Left) { PointF midPoint = new PointF(this.ClientSize.Width / 4, this.ClientSize.Height / 2); if (e.X < midPoint.X) { StatusController.LeftZoom.Offset.X += (float)StatusController.LeftZoom.ratio; } else { StatusController.LeftZoom.Offset.X -= (float)StatusController.LeftZoom.ratio; } if (e.Y < midPoint.Y) { StatusController.LeftZoom.Offset.Y += (float)StatusController.LeftZoom.ratio; } else { StatusController.LeftZoom.Offset.Y -= (float)StatusController.LeftZoom.ratio; } } else { PointF midPoint = new PointF(3 * this.ClientSize.Width / 4, this.ClientSize.Height / 2); if (e.X < midPoint.X) { StatusController.RightZoom.Offset.X += (float)StatusController.RightZoom.ratio; } else { StatusController.RightZoom.Offset.X -= (float)StatusController.RightZoom.ratio; } if (e.Y < midPoint.Y) { StatusController.RightZoom.Offset.Y += (float)StatusController.RightZoom.ratio; } else { StatusController.RightZoom.Offset.Y -= (float)StatusController.RightZoom.ratio; } } } else if (e.Button == MouseButtons.Right) { this.MoveTimer.Stop(); 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.Invalidate(); return; } Polygon2DAdorner polygonAdorner = null; if (OnPart(point) == Partition.Left) { polygonAdorner = this.LeftPolygon; } else { point.X -= this.ClientSize.Width / 2; polygonAdorner = this.RightPolygon; } if (e.Button == MouseButtons.Left) { int i = polygonAdorner.HitTest(point); if (i == -1 && StatusController.canAddPoint) { if (StatusController.availablePartition == Partition.Left) { Polygon2DEditor pe = new Polygon2DEditor(FirstPolygon); pe.AddPoint(point); StatusController.canRestart = false; } else { Polygon2DEditor pe = new Polygon2DEditor(this.SecondPolygon); pe.AddPoint(new Point2D(point)); StatusController.canRestart = false; } } else { StatusController.CatchPoint = i; } } else { int i = polygonAdorner.HitTest(point); if (i != -1) { if (StatusController.availablePartition == Partition.Left) { Polygon2DEditor pe = new Polygon2DEditor(this.FirstPolygon); pe.RemovePoint(i); StatusController.canRestart = false; } else { Polygon2DEditor pe = new Polygon2DEditor(this.SecondPolygon); pe.RemovePoint(i); StatusController.canRestart = false; } } } this.Invalidate(); }
/// <summary> /// Whether the point is on the line. /// </summary> /// <param name="point">the point.</param> /// <returns>true if is on the line.</returns> public bool isOnLine(Point2D point) { if (point == FirstPoint || point == LastPoint) { return true; } else { Vector2D v1 = point - FirstPoint; Vector2D v2 = LastPoint - point; return Vector2D.Determinant(v1, v2) < ZeroTolerance; } }
protected override void OnMouseUp(MouseEventArgs e) { Point2D point = new Point2D(e.X, e.Y); StatusController.CatchPoint = -1; this.statusBarPanel1.Text = this.GetPolygonStatus(point); this.MoveTimer.Stop(); }
/// <summary> /// Wether the line contains the point. /// </summary> /// <param name="point">the point.</param> /// <returns>true if contains.</returns> public bool Contains(Point2D point) { double d = point.X * this.A + point.Y * this.B + this.C; if (d < Line2D.ZeroTolerance) { return true; } else { return false; } }
/// <summary> /// Whether the three points is on a line. /// </summary> /// <param name="a">the first point.</param> /// <param name="b">the second point.</param> /// <param name="c">the third point.</param> /// <returns>true if is on a line.</returns> public static bool isOnLine(Point2D a, Point2D b, Point2D c) { LineSegment2D line = new LineSegment2D(a, b); return line.isOnLine(c); }
/// <summary> /// Computes the shortest distance from this point to the line defined by the parameters. /// Points <paramref name="a"/> and <paramref name="b"/> must be distinct. /// </summary> /// <param name="a">The first point defining the line.</param> /// <param name="b">The second point defining the line.</param> /// <returns>The distance from this point to the line defined by the parameters.</returns> /// <exception cref="ArgumentException"> /// The points defining the line are not distinct. /// </exception> public double DistanceToLine(Point2D a, Point2D b) { if (a == b) { throw new ArgumentException("The points defining the line are not distinct."); } else { double distanceAB = Distance(a, b); // dist(P, Line(A,B) = |det(AB,AP)| / d(A,B). return Math.Abs(((b.X - a.X) * (this.Y - a.Y) - (this.X - a.X) * (b.Y - a.Y)) / distanceAB); } }
/// <summary> /// Compares two points using lexicographic order. /// </summary> /// <param name="a">The first point.</param> /// <param name="b">The second point.</param> /// <returns>-1 if <paramref name="a"/> is less than <paramref name="b"/>, /// 0 if <paramref name="a"/> equals <paramref name="b"/>, /// and 1 if <paramref name="a"/> is greater than <paramref name="b"/>.</returns> public static int Compare(Point2D a, Point2D b) { if (a.X > b.X || (a.X == b.X && a.Y > b.Y)) { return 1; } else if (a.X < b.X || (a.X == b.X && a.Y < b.Y)) { return -1; } else { return 0; } }
/*private void SetOffset(ref PointF[] points, PointF point) { for (int i = 0; i < points.Length; i++) { points[i].X -= point.X; points[i].Y -= point.Y; } } private void SetOffset(ref PointF a, PointF b) { a.X -= b.X; a.Y -= b.Y; }*/ public int HitTest(Point2D point) { for (int i = 0; i < this.polygon.VertexCount; i++) { Point2D p = this.polygon.GetPoint(i); if (Math.Abs(point.X - p.X) <= 3 && Math.Abs(point.Y - p.Y) <= 3) { return i; } } return -1; }
/// <summary> /// Whether the line segment contains the point and the point is not on the terminal. /// </summary> /// <param name="point">the point.</param> /// <returns>true if truly contains.</returns> public bool TrulyContains(Point2D point) { Vector2D v1 = point - FirstPoint; Vector2D v2 = LastPoint - point; double d1 = v1 * v2; double d2 = Vector2D.Determinant(v1, v2); if ((d1 > ZeroTolerance) && Math.Abs(d2) < ZeroTolerance) { return true; } else { return false; } }
/// <summary> /// Returns the weighted average of two points. /// </summary> /// <param name="a">The first point.</param> /// <param name="b">The second point.</param> /// <param name="t">The weight.</param> /// <returns>The point (1 - <paramref name="t"/>)*<paramref name="a"/> + <paramref name="t"/>*<paramref name="b"/>.</returns> public static Point2D WeightedAverage(Point2D a, Point2D b, double t) { if (t <= 0) { return new Point2D(a); } else if (t >= 1) { return new Point2D(b); } else { double oneMinusT = 1 - t; return new Point2D((1 - t) * a + t * b.ToVector()); } }