public static double GetArea(Polyline pline) { CircularArc2d arc = new CircularArc2d(); double area = 0.0; int last = pline.NumberOfVertices - 1; Point2d p0 = pline.GetPoint2dAt(0); if (pline.GetBulgeAt(0) != 0.0) { area += pline.GetArcSegment2dAt(0).GetArea(); } for (int i = 1; i < last; i++) { area += GetArea(p0, pline.GetPoint2dAt(i), pline.GetPoint2dAt(i + 1)); if (pline.GetBulgeAt(i) != 0.0) { area += pline.GetArcSegment2dAt(i).GetArea();; } } if ((pline.GetBulgeAt(last) != 0.0) && pline.Closed) { area += pline.GetArcSegment2dAt(last).GetArea(); } return(area); }
/// <summary> /// Gets the algebraic (signed) area of the circular arc. /// </summary> /// <param name="arc">The instance to which the method applies.</param> /// <returns>The algebraic area.</returns> public static double AlgebricArea([NotNull] this CircularArc2d arc) { var rad = arc.Radius; var ang = arc.IsClockWise ? arc.StartAngle - arc.EndAngle : arc.EndAngle - arc.StartAngle; return(rad * rad * (ang - Math.Sin(ang)) / 2.0); }
public static LineSegment2d[] GetTangentsTo([NotNull] this CircularArc2d arc, Point2d pt) { // check if the point is inside the circle var center = arc.Center; if (pt.GetDistanceTo(center) <= arc.Radius) { return(null); } var vec = center.GetVectorTo(pt) / 2.0; var tmp = new CircularArc2d(center + vec, vec.Length); var inters = arc.IntersectWith(tmp); if (inters == null) { return(null); } var result = new LineSegment2d[2]; var v1 = inters[0] - center; var i = vec.X * v1.Y - vec.Y - v1.X > 0 ? 0 : 1; var j = i ^ 1; result[i] = new LineSegment2d(inters[0], pt); result[j] = new LineSegment2d(inters[1], pt); return(result); }
/// <summary> /// Returns the tangents between the active CircularArc3d instance complete circle and another one. /// </summary> /// <remarks> /// Tangents start points are on the object to which this method applies, end points on the one passed as argument. /// Tangents are always returned in the same order: outer tangents before inner tangents, and for both, /// the tangent on the left side of the line from this circular arc center to the other one before the one on the right side. /// </remarks> /// <param name="arc">The instance to which this method applies.</param> /// <param name="other">The CircularArc3d to which searched for tangents.</param> /// <param name="flags">An enum value specifying which type of tangent is returned.</param> /// <returns>An array of LineSegment3d representing the tangents (maybe 2 or 4) or null if there is none.</returns> /// <exception cref="Autodesk.AutoCAD.Runtime.Exception"> /// eNonCoplanarGeometry is thrown if the objects do not lies on the same plane.</exception> public static LineSegment3d[] GetTangentsTo(this CircularArc3d arc, CircularArc3d other, TangentType flags) { // check if circles lies on the same plane Vector3d normal = arc.Normal; Matrix3d WCS2OCS = Matrix3d.WorldToPlane(normal); double elevation = arc.Center.TransformBy(WCS2OCS).Z; if (!(normal.IsParallelTo(other.Normal) && Math.Abs(elevation - other.Center.TransformBy(WCS2OCS).Z) < Tolerance.Global.EqualPoint)) { throw new Autodesk.AutoCAD.Runtime.Exception( Autodesk.AutoCAD.Runtime.ErrorStatus.NonCoplanarGeometry); } Plane plane = new Plane(Point3d.Origin, normal); Matrix3d OCS2WCS = Matrix3d.PlaneToWorld(plane); CircularArc2d ca2d1 = new CircularArc2d(arc.Center.Convert2d(plane), arc.Radius); CircularArc2d ca2d2 = new CircularArc2d(other.Center.Convert2d(plane), other.Radius); LineSegment2d[] lines2d = ca2d1.GetTangentsTo(ca2d2, flags); if (lines2d == null) { return(null); } LineSegment3d[] result = new LineSegment3d[lines2d.Length]; for (int i = 0; i < lines2d.Length; i++) { LineSegment2d ls2d = lines2d[i]; result[i] = new LineSegment3d(ls2d.StartPoint.Convert3d(normal, elevation), ls2d.EndPoint.Convert3d(normal, elevation)); } return(result); }
public Arc GetArc2(Point2d pit1, Point2d pit2, Point2d pit3, ref CircularArc2d arc2d) { arc2d = new CircularArc2d(pit1, pit2, pit3); Point2d pitCenter = arc2d.Center; double radius = arc2d.Radius; double startAngle = AngleFromXAxis(pit1, pitCenter); double endAngle = AngleFromXAxis(pit3, pitCenter); double sangle = (startAngle / (2 * Math.PI * radius) * 360); double eangle = (endAngle / (2 * Math.PI * radius) * 360); double temp = 0; if ((endAngle - startAngle) >= Math.PI || (startAngle > endAngle && Math.Abs(startAngle - endAngle) < Math.PI)) { temp = startAngle; startAngle = endAngle; endAngle = temp; } Arc arc = new Arc(new Point3d(pitCenter.X, pitCenter.Y, 0), radius, startAngle, endAngle); return(arc); }
/// <summary> /// Returns the tangents between the active CircularArc3d instance complete circle and another one. /// </summary> /// <remarks> /// Tangents start points are on the object to which this method applies, end points on the one passed as argument. /// Tangents are always returned in the same order: outer tangents before inner tangents, and for both, /// the tangent on the left side of the line from this circular arc center to the other one before the one on the right side. /// </remarks> /// <param name="arc">The instance to which this method applies.</param> /// <param name="other">The CircularArc3d to which searched for tangents.</param> /// <param name="flags">An enum value specifying which type of tangent is returned.</param> /// <returns>An array of LineSegment3d representing the tangents (maybe 2 or 4) or null if there is none.</returns> /// <exception cref="Autodesk.AutoCAD.Runtime.Exception"> /// eNonCoplanarGeometry is thrown if the objects do not lies on the same plane.</exception> public static LineSegment3d[] GetTangentsTo(this CircularArc3d arc, CircularArc3d other, TangentType flags) { // check if circles lies on the same plane Vector3d normal = arc.Normal; Matrix3d WCS2OCS = Matrix3d.WorldToPlane(normal); double elevation = arc.Center.TransformBy(WCS2OCS).Z; if (!(normal.IsParallelTo(other.Normal) && Math.Abs(elevation - other.Center.TransformBy(WCS2OCS).Z) < Tolerance.Global.EqualPoint)) throw new Autodesk.AutoCAD.Runtime.Exception( Autodesk.AutoCAD.Runtime.ErrorStatus.NonCoplanarGeometry); Plane plane = new Plane(Point3d.Origin, normal); Matrix3d OCS2WCS = Matrix3d.PlaneToWorld(plane); CircularArc2d ca2d1 = new CircularArc2d(arc.Center.Convert2d(plane), arc.Radius); CircularArc2d ca2d2 = new CircularArc2d(other.Center.Convert2d(plane), other.Radius); LineSegment2d[] lines2d = ca2d1.GetTangentsTo(ca2d2, flags); if (lines2d == null) return null; LineSegment3d[] result = new LineSegment3d[lines2d.Length]; for (int i = 0; i < lines2d.Length; i++) { LineSegment2d ls2d = lines2d[i]; result[i] = new LineSegment3d(ls2d.StartPoint.Convert3d(normal, elevation), ls2d.EndPoint.Convert3d(normal, elevation)); } return result; }
/// <summary> /// Returns the tangents between the active CircularArc3d instance complete circle and a point. /// </summary> /// <remarks> /// Tangents start points are on the object to which this method applies, end points on the point passed as argument. /// Tangents are always returned in the same order: the tangent on the left side of the line from the circular arc center /// to the point before the one on the right side. /// </remarks> /// <param name="arc">The instance to which this method applies.</param> /// <param name="pt">The Point3d to which tangents are searched</param> /// <returns>An array of LineSegement3d representing the tangents (2) or null if there is none.</returns> /// <exception cref="Autodesk.AutoCAD.Runtime.Exception"> /// eNonCoplanarGeometry is thrown if the objects do not lies on the same plane.</exception> public static LineSegment3d[]? GetTangentsTo([NotNull] this CircularArc3d arc, Point3d pt) { // check if arc and point lies on the plane var normal = arc.Normal; var WCS2OCS = Matrix3d.WorldToPlane(normal); var elevation = arc.Center.TransformBy(WCS2OCS).Z; if (Math.Abs(elevation - pt.TransformBy(WCS2OCS).Z) < Tolerance.Global.EqualPoint) { throw new Autodesk.AutoCAD.Runtime.Exception( Autodesk.AutoCAD.Runtime.ErrorStatus.NonCoplanarGeometry); } var plane = new Plane(Point3d.Origin, normal); var ca2d = new CircularArc2d(arc.Center.Convert2d(plane), arc.Radius); var lines2d = ca2d.GetTangentsTo(pt.Convert2d(plane)); if (lines2d == null) { return(null); } var result = new LineSegment3d[lines2d.Length]; for (var i = 0; i < lines2d.Length; i++) { var ls2d = lines2d[i]; result[i] = new LineSegment3d(ls2d.StartPoint.Convert3d(normal, elevation), ls2d.EndPoint.Convert3d(normal, elevation)); } return(result); }
/// <summary> /// Returns the tangents between the active CircularArc3d instance complete circle and a point. /// </summary> /// <remarks> /// Tangents start points are on the object to which this method applies, end points on the point passed as argument. /// Tangents are always returned in the same order: the tangent on the left side of the line from the circular arc /// center /// to the point before the one on the right side. /// </remarks> /// <param name="arc">The instance to which this method applies.</param> /// <param name="pt">The Point3d to which tangents are searched</param> /// <returns>An array of LineSegement3d representing the tangents (2) or null if there is none.</returns> /// <exception cref="Autodesk.AutoCAD.Runtime.Exception"> /// eNonCoplanarGeometry is thrown if the objects do not lies on the same plane. /// </exception> public static LineSegment3d[] GetTangentsTo(this CircularArc3d arc, Point3d pt) { // check if arc and point lies on the plane var normal = arc.Normal; var wcs2Ocs = Matrix3d.WorldToPlane(normal); var elevation = arc.Center.TransformBy(wcs2Ocs).Z; if (Math.Abs(elevation - pt.TransformBy(wcs2Ocs).Z) < Tolerance.Global.EqualPoint) { throw new Exception( ErrorStatus.NonCoplanarGeometry); } var plane = new Plane(Point3d.Origin, normal); _ = Matrix3d.PlaneToWorld(plane); var ca2D = new CircularArc2d(arc.Center.Convert2d(plane), arc.Radius); var lines2D = ca2D.GetTangentsTo(pt.Convert2d(plane)); if (lines2D == null) { return(null); } var result = new LineSegment3d[lines2D.Length]; for (var i = 0; i < lines2D.Length; i++) { var ls2D = lines2D[i]; result[i] = new LineSegment3d(ls2D.StartPoint.Convert3D(normal, elevation), ls2D.EndPoint.Convert3D(normal, elevation)); } return(result); }
public static Polyline ConvertToPolyline([NotNull] this CircularArc2d arc) { var poly = new Polyline(); poly.AddVertexAt(0, new Point2d(arc.StartPoint.X, arc.StartPoint.Y), GetBulge(arc, arc.IsClockWise), 0, 0); poly.AddVertexAt(1, new Point2d(arc.EndPoint.X, arc.EndPoint.Y), 0, 0, 0); return(poly); }
/// <summary> /// Initializes a new instance of the <see cref="ConstructionRow"/> class. /// </summary> /// <param name="arc">The arc segment taken from a polyline.</param> /// <param name="index">The vertex index.</param> /// <param name="cumulativeDistance">The cumulative distance.</param> public ConstructionRow(CircularArc2d arc, int index, Double cumulativeDistance = 0) : this((arc as Curve2d), index, cumulativeDistance) { Arc a = new Arc(arc.Center.ToPoint3d(), arc.Radius, arc.StartAngle, arc.EndAngle); this.Distance = a.Length; this.CumulativeDistance = cumulativeDistance + this.Distance; }
/// <summary> /// Gets the area of an arc segment. /// </summary> /// <param name="arc"></param> /// <returns></returns> public static double GetArea(this CircularArc2d arc) { double ang = arc.IsClockWise ? arc.StartAngle - arc.EndAngle : arc.EndAngle - arc.StartAngle; return((ang - Math.Sin(ang)) * arc.Radius * arc.Radius / 2.0); }
/// <summary> /// Gets the centroid of the polyline 2d. /// </summary> /// <param name="pl">The instance to which the method applies.</param> /// <returns>The centroid of the polyline 2d (WCS coordinates).</returns> public static Point3d Centroid(this Polyline2d pl) { var vertices = pl.GetVertices().ToArray(); var last = vertices.Length - 1; var vertex = vertices[0]; var p0 = vertex.Position.Convert2D(); _ = pl.Elevation; var cen = new Point2d(0.0, 0.0); var area = 0.0; var bulge = vertex.Bulge; double tmpArea; Point2d tmpPt; var tri = new Triangle2D(); var arc = new CircularArc2d(); if (bulge != 0.0) { arc = pl.GetArcSegment2DAt(0); tmpArea = arc.AlgebricArea(); tmpPt = arc.Centroid(); area += tmpArea; cen += (new Point2d(tmpPt.X, tmpPt.Y) * tmpArea).GetAsVector(); } for (var i = 1; i < last; i++) { var p1 = vertices[i].Position.Convert2D(); var p2 = vertices[i + 1].Position.Convert2D(); tri.Set(p0, p1, p2); tmpArea = tri.AlgebricArea; area += tmpArea; cen += (tri.Centroid * tmpArea).GetAsVector(); bulge = vertices[i].Bulge; if (bulge != 0.0) { arc = pl.GetArcSegment2DAt(i); tmpArea = arc.AlgebricArea(); tmpPt = arc.Centroid(); area += tmpArea; cen += (new Point2d(tmpPt.X, tmpPt.Y) * tmpArea).GetAsVector(); } } bulge = vertices[last].Bulge; if (bulge != 0.0 && pl.Closed) { arc = pl.GetArcSegment2DAt(last); tmpArea = arc.AlgebricArea(); tmpPt = arc.Centroid(); area += tmpArea; cen += (new Point2d(tmpPt.X, tmpPt.Y) * tmpArea).GetAsVector(); } cen = cen.DivideBy(area); return(new Point3d(cen.X, cen.Y, pl.Elevation).TransformBy(Matrix3d.PlaneToWorld(pl.Normal))); }
/// <summary> /// Gets the signed area of the circular arc. /// </summary> /// <param name="arc">The instance to which the method applies.</param> /// <returns>The signed area.</returns> public static double SignedArea(this CircularArc2d arc) { double rad = arc.Radius; double ang = arc.IsClockWise ? arc.StartAngle - arc.EndAngle : arc.EndAngle - arc.StartAngle; return(rad * rad * (ang - Math.Sin(ang)) / 2.0); }
/// <summary> /// Gets the centroid of the circular arc. /// </summary> /// <param name="arc">The instance to which the method applies.</param> /// <returns>The centroid of the arc.</returns> public static Point2d Centroid([NotNull] this CircularArc2d arc) { var start = arc.StartPoint; var end = arc.EndPoint; var area = arc.AlgebricArea(); var chord = start.GetDistanceTo(end); var angle = (end - start).Angle; return(arc.Center.Polar(angle - Math.PI / 2.0, chord * chord * chord / (12.0 * area))); }
/// <summary> /// Gets the centroid of the circular arc. /// </summary> /// <param name="arc">The instance to which the method applies.</param> /// <returns>The centroid of the arc.</returns> public static Point2d Centroid(this CircularArc2d arc) { Point2d start = arc.StartPoint; Point2d end = arc.EndPoint; double area = arc.SignedArea(); double chord = start.GetDistanceTo(end); double angle = (end - start).Angle; return(arc.Center.Polar(angle - (Math.PI / 2.0), (chord * chord * chord) / (12.0 * area))); }
/// <summary> /// Creates a new instance of PolylineSegment from a CircularArc2d /// </summary> /// <param name="arc">A CircularArc2d instance.</param> public PolylineSegment(CircularArc2d arc) { _startPoint = arc.StartPoint; _endPoint = arc.EndPoint; _bulge = Math.Tan((arc.EndAngle - arc.StartAngle) / 4.0); if (arc.IsClockWise) { _bulge = -_bulge; } _startWidth = 0.0; _endWidth = 0.0; }
// 多段线和直线求交点 private void PolyIntersectWithLine(Polyline poly, Line line, double tol, ref Point3dCollection points) { Point2dCollection intPoints2d = new Point2dCollection(); // 获得直线对应的几何类 LineSegment2d geLine = new LineSegment2d(ToPoint2d(line.StartPoint), ToPoint2d(line.EndPoint)); // 每一段分别计算交点 Tolerance tolerance = new Tolerance(tol, tol); for (int i = 0; i < poly.NumberOfVertices; i++) { if (i < poly.NumberOfVertices - 1 || poly.Closed) { SegmentType st = poly.GetSegmentType(i); if (st == SegmentType.Line) { LineSegment2d geLineSeg = poly.GetLineSegment2dAt(i); Point2d[] pts = geLineSeg.IntersectWith(geLine, tolerance); if (pts != null) { for (int j = 0; j < pts.Length; j++) { if (FindPointIn(intPoints2d, pts[j], tol) < 0) { intPoints2d.Add(pts[j]); } } } } else if (st == SegmentType.Arc) { CircularArc2d geArcSeg = poly.GetArcSegment2dAt(i); Point2d[] pts = geArcSeg.IntersectWith(geLine, tolerance); if (pts != null) { for (int j = 0; j < pts.Length; j++) { if (FindPointIn(intPoints2d, pts[j], tol) < 0) { intPoints2d.Add(pts[j]); } } } } } } for (int i = 0; i < intPoints2d.Count; i++) { points.Add(ToPoint3d(intPoints2d[i])); } }
private static double CalculateMidPointDistance(Point2d fromPoint, Point2d endPoint, Point2d centerPoint, double theta, bool IsCounterClockwise) { double num = Math.Tan(theta / 4.0); if (!IsCounterClockwise) { num *= -1.0; } CircularArc2d circularArc2d = new CircularArc2d(fromPoint, endPoint, num, false); return(circularArc2d.Radius); }
/// <summary> /// Gets the centroid of the polyline 2d. /// </summary> /// <param name="pl">The instance to which the method applies.</param> /// <returns>The centroid of the polyline 2d (WCS coordinates).</returns> public static Point3d Centroid(this Polyline2d pl) { Vertex2d[] vertices = pl.GetVertices().ToArray(); int last = vertices.Length - 1; Vertex2d vertex = vertices[0]; Point2d p0 = vertex.Position.Convert2d(); double elev = pl.Elevation; Point2d cen = new Point2d(0.0, 0.0); double area = 0.0; double bulge = vertex.Bulge; double tmpArea; Point2d tmpPt; Triangle2d tri = new Triangle2d(); CircularArc2d arc = new CircularArc2d(); if (bulge != 0.0) { arc = pl.GetArcSegment2dAt(0); tmpArea = arc.SignedArea(); tmpPt = arc.Centroid(); area += tmpArea; cen += ((new Point2d(tmpPt.X, tmpPt.Y)) * tmpArea).GetAsVector(); } for (int i = 1; i < last; i++) { Point2d p1 = vertices[i].Position.Convert2d(); Point2d p2 = vertices[i + 1].Position.Convert2d(); tri.Set(p0, p1, p2); tmpArea = tri.SignedArea; area += tmpArea; cen += (tri.Centroid * tmpArea).GetAsVector(); bulge = vertices[i].Bulge; if (bulge != 0.0) { arc = pl.GetArcSegment2dAt(i); tmpArea = arc.SignedArea(); tmpPt = arc.Centroid(); area += tmpArea; cen += ((new Point2d(tmpPt.X, tmpPt.Y)) * tmpArea).GetAsVector(); } } bulge = vertices[last].Bulge; if ((bulge != 0.0) && (pl.Closed == true)) { arc = pl.GetArcSegment2dAt(last); tmpArea = arc.SignedArea(); tmpPt = arc.Centroid(); area += tmpArea; cen += ((new Point2d(tmpPt.X, tmpPt.Y)) * tmpArea).GetAsVector(); } cen = cen.DivideBy(area); return(new Point3d(cen.X, cen.Y, pl.Elevation).TransformBy(Matrix3d.PlaneToWorld(pl.Normal))); }
/// <summary> /// Creates a new instance of PolylineSegment from a CircularArc2d /// </summary> /// <param name="arc">A CircularArc2d instance.</param> public PolylineSegment([NotNull] CircularArc2d arc) { _startPoint = arc.StartPoint; _endPoint = arc.EndPoint; Bulge = Math.Tan((arc.EndAngle - arc.StartAngle) / 4.0); if (arc.IsClockWise) { Bulge = -Bulge; } StartWidth = 0.0; EndWidth = 0.0; }
private static Entity DrawCircularArc(CircularArc arc, double defaultElevation, Point[] densifiedPoints) { PointN pointN = arc.FromPoint as PointN; PointN pointN2 = arc.ToPoint as PointN; PointN pointN3 = arc.CenterPoint as PointN; Point3d point3d = new Point3d(pointN.X, pointN.Y, pointN.Z); Point3d point3d2 = new Point3d(pointN3.X, pointN3.Y, pointN3.Z); Point3d point3d3 = new Point3d(pointN2.X, pointN2.Y, pointN2.Z); Point2d centerPoint = new Point2d(pointN3.X, pointN3.Y); Point2d point2d = new Point2d(pointN.X, pointN.Y); Math.Abs(centerPoint.GetDistanceTo(point2d)); CircularArc3d circArc; if (densifiedPoints != null) { int num = densifiedPoints.Length / 2; PointN pointN4 = (PointN)densifiedPoints[num]; if (arc.IsCounterClockwise) { PointN arg_CC_0 = (PointN)densifiedPoints[0]; PointN arg_D9_0 = (PointN)densifiedPoints[densifiedPoints.Length - 1]; } else { PointN arg_E4_0 = (PointN)densifiedPoints[0]; PointN arg_F1_0 = (PointN)densifiedPoints[densifiedPoints.Length - 1]; } Point3d point3d4 = new Point3d(pointN4.X, pointN4.Y, pointN4.Z); circArc = new CircularArc3d(point3d, point3d4, point3d3); } else { Point2d point2d2 = new Point2d(point3d.X, point3d.Y); Point2d point2d3 = new Point2d(point3d3.X, point3d3.Y); double num2 = GIS2CAD.CalcThetaFromVectors(point2d2, point2d3, centerPoint, arc.IsCounterClockwise); double num3 = Math.Tan(num2 / 4.0); if (!arc.IsCounterClockwise) { num3 *= -1.0; } CircularArc2d circularArc2d = new CircularArc2d(point2d2, point2d3, num3, false); Point2d[] samplePoints = circularArc2d.GetSamplePoints(3); Point3d point3d5 = new Point3d(samplePoints[1].X, samplePoints[1].Y, point3d2.Z); circArc = new CircularArc3d(point3d, point3d5, point3d3); } new Point3d(pointN3.X, pointN3.Y, pointN3.Z); Arc arc2 = GIS2CAD.CreateFromCircularArc(circArc); arc2.ColorIndex = (256); return(arc2); }
public CircularArc2d GetArcSegment2dAt(int index) { if (base.isInstanced()) { CircularArc2d GetArcSegment2dAt = BasePolyline.GetArcSegment2dAt(index); tr.Dispose(); return(GetArcSegment2dAt); } else { return(BasePolyline.GetArcSegment2dAt(index)); } }
Coordinate[] GetTessellatedCurveCoordinates(Matrix3d parentEcs, CircularArc2d curve) { Matrix3d matrix3d = parentEcs.Inverse(); Point2d[] samplePoints = curve.GetSamplePoints(3); var point3d = new Point3d(samplePoints[0].X, samplePoints[0].Y, 0.0); var point3d2 = new Point3d(samplePoints[1].X, samplePoints[1].Y, 0.0); var point3d3 = new Point3d(samplePoints[2].X, samplePoints[2].Y, 0.0); point3d.TransformBy(matrix3d); point3d2.TransformBy(matrix3d); point3d3.TransformBy(matrix3d); return(this.GetTessellatedCurveCoordinates(new CircularArc3d(point3d, point3d2, point3d3))); }
private void GetEdgeInformation(Polyline pline, ref Curve2dCollection plCurves, ref IntegerCollection edgeTypes) { int segCount = pline.NumberOfVertices; for (int cnt = 0; cnt < segCount; cnt++) { SegmentType type = pline.GetSegmentType(cnt); switch (type) { case SegmentType.Arc: CircularArc2d arc2d = pline.GetArcSegment2dAt(cnt); plCurves.Add(arc2d); edgeTypes.Add((int)Enum.Parse(typeof(HatchEdgeType), HatchEdgeType.CircularArc.ToString())); break; case SegmentType.Line: LineSegment2d line2d = pline.GetLineSegment2dAt(cnt); plCurves.Add(line2d); edgeTypes.Add((int)Enum.Parse(typeof(HatchEdgeType), HatchEdgeType.Line.ToString())); break; case SegmentType.Coincident: break; case SegmentType.Empty: break; case SegmentType.Point: break; } } }
/// <summary> /// Returns the parameter value of point. /// </summary> /// <param name="pt">The Point 2d whose get the PolylineSegment parameter at.</param> /// <returns>A double between 0.0 and 1.0, or -1.0 if the point does not lie on the segment.</returns> public double GetParameterOf(Point2d pt) { if (IsLinear) { LineSegment2d line = ToLineSegment(); return(line.IsOn(pt) ? _startPoint.GetDistanceTo(pt) / line.Length : -1.0); } else { CircularArc2d arc = ToCircularArc(); return(arc.IsOn(pt) ? arc.GetLength(arc.GetParameterOf(_startPoint), arc.GetParameterOf(pt)) / arc.GetLength(arc.GetParameterOf(_startPoint), arc.GetParameterOf(_endPoint)) : -1.0); } }
public override void Input(List <Entity> objects) { foreach (Entity ent in objects) { if (ent is Line) { segments.Add(new StraitItemSegment(((Line)ent).Length)); } else if (ent is Arc) { segments.Add(new RadiusItemSegment(ent as Arc)); } else if (ent is Polyline) { Polyline pl = ent as Polyline; int count; if (pl.Closed) { count = pl.NumberOfVertices; } else { count = pl.NumberOfVertices - 1; } for (int j = 0; j < count; j++) { SegmentType st = pl.GetSegmentType(j); if (st == SegmentType.Line) { LineSegment2d lsd = pl.GetLineSegment2dAt(j); segments.Add(new StraitItemSegment(lsd.Length)); } else if (st == SegmentType.Arc) { CircularArc2d arc_s = pl.GetArcSegment2dAt(j); Plane pn = new Plane(Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis); Arc arc = new Arc(new Point3d(pn, arc_s.Center), Vector3d.ZAxis, arc_s.Radius, arc_s.StartAngle, arc_s.EndAngle); segments.Add(new RadiusItemSegment(arc)); } } } } base.count = ItemInput.ItemCount(); status = true; }
/// <summary> /// Gets the centroid of the polyline. /// </summary> /// <param name="pl">The instance to which the method applies.</param> /// <returns>The centroid of the polyline (OCS coordinates).</returns> public static Point2d Centroid2D(this Polyline pl) { var cen = new Point2d(); var tri = new Triangle2D(); var arc = new CircularArc2d(); double tmpArea; var area = 0.0; var last = pl.NumberOfVertices - 1; var p0 = pl.GetPoint2dAt(0); var bulge = pl.GetBulgeAt(0); if (bulge != 0.0) { arc = pl.GetArcSegment2dAt(0); area = arc.AlgebricArea(); cen = arc.Centroid() * area; } for (var i = 1; i < last; i++) { tri.Set(p0, pl.GetPoint2dAt(i), pl.GetPoint2dAt(i + 1)); tmpArea = tri.AlgebricArea; cen += (tri.Centroid * tmpArea).GetAsVector(); area += tmpArea; bulge = pl.GetBulgeAt(i); if (bulge != 0.0) { arc = pl.GetArcSegment2dAt(i); tmpArea = arc.AlgebricArea(); area += tmpArea; cen += (arc.Centroid() * tmpArea).GetAsVector(); } } bulge = pl.GetBulgeAt(last); if (bulge != 0.0 && pl.Closed) { arc = pl.GetArcSegment2dAt(last); tmpArea = arc.AlgebricArea(); area += tmpArea; cen += (arc.Centroid() * tmpArea).GetAsVector(); } return(cen.DivideBy(area)); }
/// <summary> /// Gets the centroid of the polyline. /// </summary> /// <param name="pl">The instance to which the method applies.</param> /// <returns>The centroid of the polyline (OCS coordinates).</returns> public static Point2d Centroid2d(this Polyline pl) { Point2d cen = new Point2d(); Triangle2d tri = new Triangle2d(); CircularArc2d arc = new CircularArc2d(); double tmpArea; double area = 0.0; int last = pl.NumberOfVertices - 1; Point2d p0 = pl.GetPoint2dAt(0); double bulge = pl.GetBulgeAt(0); if (bulge != 0.0) { arc = pl.GetArcSegment2dAt(0); area = arc.AlgebricArea(); cen = arc.Centroid() * area; } for (int i = 1; i < last; i++) { tri.Set(p0, pl.GetPoint2dAt(i), pl.GetPoint2dAt(i + 1)); tmpArea = tri.AlgebricArea; cen += (tri.Centroid * tmpArea).GetAsVector(); area += tmpArea; bulge = pl.GetBulgeAt(i); if (bulge != 0.0) { arc = pl.GetArcSegment2dAt(i); tmpArea = arc.AlgebricArea(); area += tmpArea; cen += (arc.Centroid() * tmpArea).GetAsVector(); } } bulge = pl.GetBulgeAt(last); if ((bulge != 0.0) && (pl.Closed == true)) { arc = pl.GetArcSegment2dAt(last); tmpArea = arc.AlgebricArea(); area += tmpArea; cen += (arc.Centroid() * tmpArea).GetAsVector(); } return(cen.DivideBy(area)); }
/// <summary> /// Returns the tangents between the active CircularArc2d instance complete circle and a point. /// </summary> /// <remarks> /// Tangents start points are on the object to which this method applies, end points on the point passed as argument. /// Tangents are always returned in the same order: the tangent on the left side of the line from the circular arc center /// to the point before the other one. /// </remarks> /// <param name="arc">The instance to which this method applies.</param> /// <param name="pt">The Point2d to which tangents are searched</param> /// <returns>An array of LineSegement2d representing the tangents (2) or null if there is none.</returns> public static LineSegment2d[] GetTangentsTo(this CircularArc2d arc, Point2d pt) { // check if the point is inside the circle Point2d center = arc.Center; if (pt.GetDistanceTo(center) <= arc.Radius) return null; Vector2d vec = center.GetVectorTo(pt) / 2.0; CircularArc2d tmp = new CircularArc2d(center + vec, vec.Length); Point2d[] inters = arc.IntersectWith(tmp); if (inters == null) return null; LineSegment2d[] result = new LineSegment2d[2]; Vector2d v1 = inters[0] - center; Vector2d v2 = inters[1] - center; int i = vec.X * v1.Y - vec.Y - v1.X > 0 ? 0 : 1; int j = i ^ 1; result[i] = new LineSegment2d(inters[0], pt); result[j] = new LineSegment2d(inters[1], pt); return result; }
// 由给定圆上三点创建圆的函数. public static ObjectId AddCircle(Point2d pt1, Point2d pt2, Point2d pt3) { const double pi = Math.PI; Vector2d va = pt1.GetVectorTo(pt2); Vector2d vb = pt1.GetVectorTo(pt3); if (va.GetAngleTo(vb) == 0 | va.GetAngleTo(vb) == pi) { ObjectId nullId = ObjectId.Null; return(nullId); } else { CircularArc2d geoArc = new CircularArc2d(pt1, pt2, pt3); Point3d cenPt = new Point3d(geoArc.Center.X, geoArc.Center.Y, 0); double radius = geoArc.Radius; Circle ent = new Circle(cenPt, Vector3d.ZAxis, radius); ObjectId entId = AppendEntity(ent); return(entId); } }
public static ObjectId AddCircle(Point2d pt1, Point2d pt2, Point2d pt3) { Vector2d vectorTo = pt1.GetVectorTo(pt2); Vector2d vectorTo2 = pt1.GetVectorTo(pt3); ObjectId result; if (vectorTo.GetAngleTo(vectorTo2) == 0.0 | vectorTo.GetAngleTo(vectorTo2) == 3.1415926535897931) { ObjectId @null = ObjectId.Null; result = @null; } else { CircularArc2d circularArc2d = new CircularArc2d(pt1, pt2, pt3); Point3d point3d; point3d..ctor(circularArc2d.Center.X, circularArc2d.Center.Y, 0.0); double radius = circularArc2d.Radius; Circle ent = new Circle(point3d, Vector3d.ZAxis, radius); ObjectId objectId = ModelSpace.AddEnt(ent); result = objectId; } return(result); }
/// <summary> /// Creates a new instance of PolylineSegment from a CircularArc2d /// </summary> /// <param name="arc">A CircularArc2d instance.</param> public PolylineSegment(CircularArc2d arc) { _startPoint = arc.StartPoint; _endPoint = arc.EndPoint; _bulge = Math.Tan((arc.EndAngle - arc.StartAngle) / 4.0); if (arc.IsClockWise) _bulge = -_bulge; _startWidth = 0.0; _endWidth = 0.0; }
public void GetLine() { var doc = Application.DocumentManager.MdiActiveDocument; var ed = doc.Editor; var db = doc.Database; var intOpts = new PromptIntegerOptions("\n请输入每隔多少毫米进行点的合并"); var intRes = ed.GetInteger(intOpts); int intCmeter = 2000; if (intRes.Status == PromptStatus.OK) { intCmeter = intRes.Value; } var selectRes = ed.GetSelection(new SelectionFilter(new[] { new TypedValue((int)DxfCode.Start, "POLYLINE") })); if (selectRes.Status == PromptStatus.OK) { var selectSet = selectRes.Value; List <Polyline3d> listPl = new List <Polyline3d>(); List <Polyline3d> listPlold = MyForeach(selectSet); Point3dCollection p3dcoll = new Point3dCollection(); if (null == listPlold || listPlold.Count < 1) { return; } var pl3d1 = listPlold[0]; foreach (var pl3d in listPlold) { if (pl3d != null) { using (var trans = db.TransactionManager.StartTransaction()) { foreach (ObjectId objId in pl3d) { var vertex3d = trans.GetObject(objId, OpenMode.ForRead) as PolylineVertex3d; p3dcoll.Add(vertex3d.Position); } } } } Polyline pline = new Polyline(); Point3dCollection p3dColl2 = new Point3dCollection(); List <Entity> listEntity = new List <Entity>(); List <Entity> listEntity2 = new List <Entity>(); List <CircularArc2d> listC2d = new List <CircularArc2d>(); for (int i = 0; i < p3dcoll.Count; i++) { int startIndex = i; Point2d pit1 = new Point2d(p3dcoll[i].X, p3dcoll[i].Y); Point2d pit2 = Point2d.Origin; Point2d pit3 = Point2d.Origin; if (i + 1 < p3dcoll.Count) { pit2 = new Point2d(p3dcoll[i + 1].X, p3dcoll[i + 1].Y); i = i + 1; } if (i + 1 < p3dcoll.Count) { pit3 = new Point2d(p3dcoll[i + 1].X, p3dcoll[i + 1].Y); i = i + 1; } double length = (pit2 - pit1).Length + (pit3 - pit2).Length; int mid = 0; while (length < intCmeter) { if (i + 1 < p3dcoll.Count) { pit2 = pit3; pit3 = new Point2d(p3dcoll[i + 1].X, p3dcoll[i + 1].Y); } else { break; } i = i + 1; mid++; length = (pit2 - pit1).Length + (pit3 - pit2).Length; } Point2d pitMid = Point2d.Origin; if (mid / 2 > 0) { pitMid = new Point2d(p3dcoll[startIndex + mid / 2].X, p3dcoll[startIndex + mid / 2].Y); } else { pitMid = pit2; } pline.AddVertexAt(pline.NumberOfVertices, pit1, 0, 0, 0); p3dColl2.Add(new Point3d(pit1.X, pit1.Y, 0)); if (i < p3dcoll.Count) { pline.AddVertexAt(pline.NumberOfVertices, pitMid, 0, 0, 0); pline.AddVertexAt(pline.NumberOfVertices, pit3, 0, 0, 0); p3dColl2.Add(new Point3d(pitMid.X, pitMid.Y, 0)); p3dColl2.Add(new Point3d(pit3.X, pit3.Y, 0)); } if (i < p3dcoll.Count) { Arc arc = GetArc(pit1, pitMid, pit3); CircularArc2d c2d = null; Arc arc2 = GetArc2(pit1, pitMid, pit3, ref c2d); arc.ColorIndex = 0; arc2.ColorIndex = 0; listEntity.Add(arc); listEntity2.Add(arc2); listC2d.Add(c2d); } if (i == p3dcoll.Count - 1) { break; } i = i - 1; } pline.Closed = true; pline.ColorIndex = pl3d1.ColorIndex; PromptKeywordOptions pkOpts = new PromptKeywordOptions("请输入是否进行弧长优化[Y/N]", "Y N"); var keyRes = ed.GetKeywords(pkOpts); List <Entity> listEntsOptimize = new List <Entity>(); if (keyRes.Status == PromptStatus.OK && keyRes.StringResult == "Y") { ed.WriteMessage("进行弧长优化"); for (int i = 0; i < listEntity2.Count; i++) { Arc arc = listEntity2[i] as Arc; Arc arc2 = null; if (!listEntsOptimize.Contains(arc)) { listEntsOptimize.Add(arc); } if (i + 1 < listEntity2.Count) { arc2 = listEntity2[i + 1] as Arc; if (!listEntsOptimize.Contains(arc2)) { listEntsOptimize.Add(arc2); } i = i + 1; } List <CircularArc2d> tempArc = new List <CircularArc2d>(); if (arc != null && arc2 != null) { double angle1 = arc.EndAngle - arc.StartAngle; double angle2 = arc2.EndAngle - arc.StartAngle; while (Math.Abs(angle1 - angle2) <= Math.PI * (30.0 / 180)) { if (listEntsOptimize.Contains(arc)) { listEntsOptimize.Remove(arc); } if (listEntsOptimize.Contains(arc2)) { listEntsOptimize.Remove(arc2); } int index = listEntity2.IndexOf(arc); int index2 = listEntity2.IndexOf(arc2); tempArc.Add(listC2d[index]); tempArc.Add(listC2d[index2]); if (i + 1 < listEntity2.Count) { arc2 = listEntity2[i + 1] as Arc; i = i + 1; } else { arc2 = null; break; } angle1 = arc.EndAngle - arc.StartAngle; angle2 = arc2.EndAngle - arc.StartAngle; } } List <Polyline> listpolytemp = new List <Polyline>(); if (tempArc.Count > 1) { Arc newTempArc = null; Point2d startPoint = tempArc[0].StartPoint; Point2d endPoint = tempArc[tempArc.Count - 1].EndPoint; if (tempArc.Count == 2) { Point2d centerPoint = tempArc[0].EndPoint; newTempArc = GetArc(startPoint, centerPoint, endPoint); } else { Point2d centerPoint = tempArc[0].EndPoint; newTempArc = GetArc(startPoint, centerPoint, endPoint); } newTempArc.Color = Autodesk.AutoCAD.Colors.Color.FromColor(System.Drawing.Color.Red); Polyline l = new Polyline(); listEntsOptimize.Add(newTempArc); } if (i == listEntity2.Count - 1) { break; } i = i - 1; } } List <Polyline> listPoly = ArcToPolyline(listEntity); List <Polyline> listPoly2 = ArcToPolyline(listEntsOptimize); Polyline poly = GetPolyline(listPoly); Polyline poly2 = GetPolyline(listPoly2); if (keyRes.Status == PromptStatus.OK && keyRes.StringResult == "Y") { poly2.ToSpace(); } else { poly.ToSpace(); } //List<Polyline> listpolyOptimize = ArcToPolyline(listEntsOptimize); // Polyline poly = GetPolyline(listpolyOptimize); //var newDoc = Application.DocumentManager.Add(""); //using (var lock1 = newDoc.LockDocument()) //{ // var newDb = newDoc.Database; // if (keyRes.Status == PromptStatus.OK && keyRes.StringResult == "Y") // poly2.ToSpace(newDb); // else // poly.ToSpace(newDb); //} } }
/// <summary> /// Gets the centroid of the polyline. /// </summary> /// <param name="pl">The instance to which the method applies.</param> /// <returns>The centroid of the polyline (OCS coordinates).</returns> public static Point2d Centroid2d(this Polyline pl) { Point2d cen = new Point2d(); Triangle2d tri = new Triangle2d(); CircularArc2d arc = new CircularArc2d(); double tmpArea; double area = 0.0; int last = pl.NumberOfVertices - 1; Point2d p0 = pl.GetPoint2dAt(0); double bulge = pl.GetBulgeAt(0); if (bulge != 0.0) { arc = pl.GetArcSegment2dAt(0); area = arc.AlgebricArea(); cen = arc.Centroid() * area; } for (int i = 1; i < last; i++) { tri.Set(p0, pl.GetPoint2dAt(i), pl.GetPoint2dAt(i + 1)); tmpArea = tri.AlgebricArea; cen += (tri.Centroid * tmpArea).GetAsVector(); area += tmpArea; bulge = pl.GetBulgeAt(i); if (bulge != 0.0) { arc = pl.GetArcSegment2dAt(i); tmpArea = arc.AlgebricArea(); area += tmpArea; cen += (arc.Centroid() * tmpArea).GetAsVector(); } } bulge = pl.GetBulgeAt(last); if ((bulge != 0.0) && (pl.Closed == true)) { arc = pl.GetArcSegment2dAt(last); tmpArea = arc.AlgebricArea(); area += tmpArea; cen += (arc.Centroid() * tmpArea).GetAsVector(); } return cen.DivideBy(area); }
/// <summary> /// Returns the tangents between the active CircularArc2d instance complete circle and another one. /// </summary> /// <remarks> /// Tangents start points are on the object to which this method applies, end points on the one passed as argument. /// Tangents are always returned in the same order: outer tangents before inner tangents, and for both, /// the tangent on the left side of the line from this circular arc center to the other one before the other one. /// </remarks> /// <param name="arc">The instance to which this method applies.</param> /// <param name="other">The CircularArc2d to which searched for tangents.</param> /// <param name="flags">An enum value specifying which type of tangent is returned.</param> /// <returns>An array of LineSegment2d representing the tangents (maybe 2 or 4) or null if there is none.</returns> public static LineSegment2d[] GetTangentsTo(this CircularArc2d arc, CircularArc2d other, TangentType flags) { // check if a circle is inside the other double dist = arc.Center.GetDistanceTo(other.Center); if (dist - Math.Abs(arc.Radius - other.Radius) <= Tolerance.Global.EqualPoint) return null; // check if circles overlap bool overlap = arc.Radius + other.Radius >= dist; if (overlap && flags == TangentType.Inner) return null; CircularArc2d tmp1, tmp2; Point2d[] inters; Vector2d vec1, vec2, vec = other.Center - arc.Center; int i, j; LineSegment2d[] result = new LineSegment2d[(int)flags == 3 && !overlap ? 4 : 2]; // outer tangents if ((flags & TangentType.Outer) > 0) { if (arc.Radius == other.Radius) { Line2d perp = new Line2d(arc.Center, vec.GetPerpendicularVector()); inters = arc.IntersectWith(perp); if (inters == null) return null; vec1 = (inters[0] - arc.Center).GetNormal(); vec2 = (inters[1] - arc.Center).GetNormal(); i = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 0 : 1; j = i ^ 1; result[i] = new LineSegment2d(inters[0], inters[0] + vec); result[j] = new LineSegment2d(inters[1], inters[1] + vec); } else { Point2d center = arc.Radius < other.Radius ? other.Center : arc.Center; tmp1 = new CircularArc2d(center, Math.Abs(arc.Radius - other.Radius)); tmp2 = new CircularArc2d(arc.Center + vec / 2.0, dist / 2.0); inters = tmp1.IntersectWith(tmp2); if (inters == null) return null; vec1 = (inters[0] - center).GetNormal(); vec2 = (inters[1] - center).GetNormal(); i = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 0 : 1; j = i ^ 1; result[i] = new LineSegment2d(arc.Center + vec1 * arc.Radius, other.Center + vec1 * other.Radius); result[j] = new LineSegment2d(arc.Center + vec2 * arc.Radius, other.Center + vec2 * other.Radius); } } // inner tangents if ((flags & TangentType.Inner) > 0 && !overlap) { double ratio = (arc.Radius / (arc.Radius + other.Radius)) / 2.0; tmp1 = new CircularArc2d(arc.Center + vec * ratio, dist * ratio); inters = arc.IntersectWith(tmp1); if (inters == null) return null; vec1 = (inters[0] - arc.Center).GetNormal(); vec2 = (inters[1] - arc.Center).GetNormal(); i = vec.X * vec1.Y - vec.Y - vec1.X > 0 ? 2 : 3; j = i == 2 ? 3 : 2; result[i] = new LineSegment2d(arc.Center + vec1 * arc.Radius, other.Center + vec1.Negate() * other.Radius); result[j] = new LineSegment2d(arc.Center + vec2 * arc.Radius, other.Center + vec2.Negate() * other.Radius); } return result; }