Author Topic: Best way to create Polyline3d from 2 lines and an Arc  (Read 2692 times)

0 Members and 1 Guest are viewing this topic.

Keith Brown

  • Swamp Rat
  • Posts: 601
Best way to create Polyline3d from 2 lines and an Arc
« on: November 12, 2016, 11:13:42 AM »
For some reason I am struggling with this.  I see lots of examples of creating a 2d polyline but i need to combine lines and arcs in 3d space.  Can anyone point out an example?  Thank you.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

kpblc

  • Bull Frog
  • Posts: 396
Re: Best way to create Polyline3d from 2 lines and an Arc
« Reply #1 on: November 12, 2016, 11:25:29 AM »
3d polyline can't have arcs. You have to create spline, i think
Sorry for my English.

Jochen

  • Newt
  • Posts: 30
Re: Best way to create Polyline3d from 2 lines and an Arc
« Reply #2 on: November 13, 2016, 12:29:20 AM »
KPbIC is right.
But if you can live with "arcs" consisting of short straight lines, so you can find a free download of PEDIT3D.vlx at
www.ant-ares.de
regards
Jochen
 

SEANT

  • Bull Frog
  • Posts: 345
Re: Best way to create Polyline3d from 2 lines and an Arc
« Reply #3 on: November 13, 2016, 04:00:39 AM »
To continue in the "kpblc is right" vein, a NURBS based spline can combine straight and arc like segments.

https://knowledge.autodesk.com/support/autocad/learn-explore/caas/screencast/Main/Details/5e33242a-03aa-493f-b2da-102408f3f945.html

Of course, splines come with their own set of issues - not the least of which is that they are a handfull to work with programatically.

If you do consider splines a possible solution, Look at the Autodesk.AutoCAD.DatabaseServices.Entity.JoinEntities and/or Autodesk.AutoCAD.Geometry.NurbCurve3d.JoinWith methods.
Sean Tessier
AutoCAD 2016 Mechanical

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Best way to create Polyline3d from 2 lines and an Arc
« Reply #4 on: November 13, 2016, 09:57:28 AM »
Hi,

If the arc and the lines lies on the same plane, you can try to join them into a polyline. You have to search which start point or end point are corresponding.

Here's a little example to make a polyline from 2 lines and one arc with the arc between the lines.

Code - C#: [Select]
  1.         private Polyline Join(Arc arc, Line line1, Line line2, Tolerance tolerance)
  2.         {
  3.             var plane = arc.GetPlane();
  4.             if (!(plane.IsOn(line1.StartPoint) && plane.IsOn(line1.EndPoint) &&
  5.                 plane.IsOn(line2.StartPoint) && plane.IsOn(line2.EndPoint)))
  6.                 return null;
  7.  
  8.             Point2d p0, p3;
  9.             var p1 = arc.StartPoint.Convert2d(plane);
  10.             var p2 = arc.EndPoint.Convert2d(plane);
  11.             var start1 = line1.StartPoint.Convert2d(plane);
  12.             var end1 = line1.EndPoint.Convert2d(plane);
  13.             var start2 = line2.StartPoint.Convert2d(plane);
  14.             var end2 = line2.EndPoint.Convert2d(plane);
  15.  
  16.             if (start1.IsEqualTo(p1, tolerance))
  17.             {
  18.                 p0 = end1;
  19.                 if (start2.IsEqualTo(p2, tolerance)) p3 = end2;
  20.                 else if (end2.IsEqualTo(p2, tolerance)) p3 = start2;
  21.                 else return null;
  22.             }
  23.             else if (end1.IsEqualTo(p1, tolerance))
  24.             {
  25.                 p0 = start1;
  26.                 if (start2.IsEqualTo(p2, tolerance)) p3 = end2;
  27.                 else if (end2.IsEqualTo(p2, tolerance)) p3 = start2;
  28.                 else return null;
  29.             }
  30.             else if (start2.IsEqualTo(p1, tolerance))
  31.             {
  32.                 p0 = end2;
  33.                 if (start1.IsEqualTo(p2, tolerance)) p3 = end1;
  34.                 else if (end1.IsEqualTo(p2, tolerance)) p3 = start1;
  35.                 else return null;
  36.             }
  37.             else if (end2.IsEqualTo(p1, tolerance))
  38.             {
  39.                 p0 = line2.StartPoint.Convert2d(plane);
  40.                 if (start1.IsEqualTo(p2, tolerance)) p3 = end1;
  41.                 else if (end1.IsEqualTo(p2, tolerance)) p3 = start1;
  42.                 else return null;
  43.             }
  44.             else
  45.             {
  46.                 return null;
  47.             }
  48.             var angle = arc.EndAngle - arc.StartAngle;
  49.             if (angle < 0)
  50.                 angle += Math.PI * 2.0;
  51.             double bulge = Math.Tan(angle / 4.0);
  52.  
  53.             Polyline pline = new Polyline(4);
  54.             pline.AddVertexAt(0, p0, 0.0, 0.0, 0.0);
  55.             pline.AddVertexAt(1, p1, bulge, 0.0, 0.0);
  56.             pline.AddVertexAt(2, p2, 0.0, 0.0, 0.0);
  57.             pline.AddVertexAt(3, p3, 0.0, 0.0, 0.0);
  58.             pline.Normal = arc.Normal;
  59.             pline.TransformBy(Matrix3d.Displacement(arc.Center.GetAsVector()));
  60.             return pline;
  61.         }

You can also use the PolylineSegmentCollection.join() method from GeometryExtensions.
« Last Edit: November 13, 2016, 10:02:15 AM by gile »
Speaking English as a French Frog

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Best way to create Polyline3d from 2 lines and an Arc
« Reply #5 on: November 13, 2016, 10:55:47 AM »
Here's an example using GeometryExtensions PolylineSegmentCollection.Join() method.
All contiguous lines and arcs in the selection set which lie on the reference arc plane are joined into polylines.

Code - C#: [Select]
  1.         [CommandMethod("TEST")]
  2.         public void Test()
  3.         {
  4.             var doc = Application.DocumentManager.MdiActiveDocument;
  5.             var db = doc.Database;
  6.             var ed = doc.Editor;
  7.  
  8.             var arcOpts = new PromptEntityOptions("\nSelect the reference arc: ");
  9.             arcOpts.SetRejectMessage("\nSelected object is not an arc.");
  10.             arcOpts.AddAllowedClass(typeof(Arc), true);
  11.             var arcRes = ed.GetEntity(arcOpts);
  12.             if (arcRes.Status != PromptStatus.OK)
  13.                 return;
  14.             var arcId = arcRes.ObjectId;
  15.  
  16.             var selSet = ed.GetSelection(new SelectionFilter(new[] { new TypedValue(0, "ARC,LINE") }));
  17.             if (selSet.Status != PromptStatus.OK)
  18.                 return;
  19.  
  20.             using (var tr = db.TransactionManager.StartTransaction())
  21.             {
  22.                 var arc = (Arc)tr.GetObject(arcId, OpenMode.ForRead);
  23.                 var normal = arc.Normal;
  24.                 var plane = arc.GetPlane();
  25.                 var displace = Matrix3d.Displacement(arc.Center.GetAsVector());
  26.                 var segments = new PolylineSegmentCollection();
  27.                 segments.Add(new PolylineSegment(
  28.                     new CircularArc2d(
  29.                         arc.StartPoint.Convert2d(plane),
  30.                         arc.GetPointAtParameter((arc.StartParam + arc.EndParam) / 2.0).Convert2d(plane),
  31.                         arc.EndPoint.Convert2d(plane))));
  32.                 foreach (var id in selSet.Value.GetObjectIds())
  33.                 {
  34.                     if (id == arcId)
  35.                         continue;
  36.  
  37.                     if (id.ObjectClass.DxfName == "ARC")
  38.                     {
  39.                         arc = (Arc)tr.GetObject(id, OpenMode.ForRead);
  40.                         if (arc.Normal.IsEqualTo(normal))
  41.                         {
  42.                             segments.Add(new PolylineSegment(
  43.                                 new CircularArc2d(
  44.                                     arc.StartPoint.Convert2d(plane),
  45.                                     arc.GetPointAtParameter((arc.StartParam + arc.EndParam) / 2.0).Convert2d(plane),
  46.                                     arc.EndPoint.Convert2d(plane))));
  47.                         }
  48.                     }
  49.                     else
  50.                     {
  51.                         var line = (Line)tr.GetObject(id, OpenMode.ForRead);
  52.                         if (plane.IsOn(line.StartPoint) && plane.IsOn(line.EndPoint))
  53.                         {
  54.                             segments.Add(new PolylineSegment(
  55.                                 new LineSegment2d(
  56.                                     line.StartPoint.Convert2d(plane),
  57.                                     line.EndPoint.Convert2d(plane))));
  58.                         }
  59.                     }
  60.                 }
  61.  
  62.                 var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  63.                 foreach (var pline in segments.Join().Select(s => s.ToPolyline()))
  64.                 {
  65.                     curSpace.AppendEntity(pline);
  66.                     tr.AddNewlyCreatedDBObject(pline, true);
  67.                     pline.Normal = normal;
  68.                     pline.TransformBy(displace);
  69.                 }
  70.  
  71.                 tr.Commit();
  72.             }
  73.         }
Speaking English as a French Frog

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Best way to create Polyline3d from 2 lines and an Arc
« Reply #6 on: November 14, 2016, 09:45:39 AM »
Thank you all for the help.


Gile, I use your Geometry Extensions quite a bit and the part that I was missing was using the arc plane and converting everything to 2D.  Now that I have that missing piece the rest is cake.  Thank you once again.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013