/// <summary> /// Obtains a list of vertexes that represent the polyline approximating the curve segments as necessary. /// </summary> /// <param name="bulgePrecision">Curve segments precision (a value of zero means that no approximation will be made).</param> /// <param name="weldThreshold">Tolerance to consider if two new generated vertexes are equal.</param> /// <param name="bulgeThreshold">Minimun distance from which approximate curved segments of the polyline.</param> /// <returns>The return vertexes are expresed in object coordinate system.</returns> public List <Vector2f> PoligonalVertexes(int bulgePrecision, double weldThreshold, double bulgeThreshold) { List <Vector2f> ocsVertexes = new List <Vector2f>(); int index = 0; foreach (LightWeightPolylineVertex vertex in this.Vertexes) { double bulge = vertex.Bulge; Vector2f p1; Vector2f p2; if (index == this.Vertexes.Count - 1) { p1 = new Vector2f(vertex.Location.X, vertex.Location.Y); p2 = new Vector2f(this.vertexes[0].Location.X, this.vertexes[0].Location.Y); } else { p1 = new Vector2f(vertex.Location.X, vertex.Location.Y); p2 = new Vector2f(this.vertexes[index + 1].Location.X, this.vertexes[index + 1].Location.Y); } if (!p1.Equals(p2, weldThreshold)) { if (bulge == 0 || bulgePrecision == 0) { ocsVertexes.Add(p1); } else { double c = Vector2f.Distance(p1, p2); if (c >= bulgeThreshold) { double s = (c / 2) * Math.Abs(bulge); double r = ((c / 2) * (c / 2) + s * s) / (2 * s); double theta = (double)(4 * Math.Atan(Math.Abs(bulge))); double gamma = (double)((Math.PI - theta) / 2); double phi; if (bulge > 0) { phi = Vector2f.AngleBetween(Vector2f.UnitX, p2 - p1) + gamma; } else { phi = Vector2f.AngleBetween(Vector2f.UnitX, p2 - p1) - gamma; } Vector2f center = new Vector2f((double)(p1.X + r * Math.Cos(phi)), (double)(p1.Y + r * Math.Sin(phi))); Vector2f a1 = p1 - center; double angle = 4 * ((double)(Math.Atan(bulge))) / (bulgePrecision + 1); ocsVertexes.Add(p1); for (int i = 1; i <= bulgePrecision; i++) { Vector2f curvePoint = new Vector2f(); Vector2f prevCurvePoint = new Vector2f(this.vertexes[this.vertexes.Count - 1].Location.X, this.vertexes[this.vertexes.Count - 1].Location.Y); curvePoint.X = center.X + (double)(Math.Cos(i * angle) * a1.X - Math.Sin(i * angle) * a1.Y); curvePoint.Y = center.Y + (double)(Math.Sin(i * angle) * a1.X + Math.Cos(i * angle) * a1.Y); if (!curvePoint.Equals(prevCurvePoint, weldThreshold) && !curvePoint.Equals(p2, weldThreshold)) { ocsVertexes.Add(curvePoint); } } } else { ocsVertexes.Add(p1); } } } index++; } return(ocsVertexes); }