TheSwamp

Code Red => .NET => Topic started by: guohq on January 30, 2016, 04:06:20 AM

Title: how to draw a cylinder by two points and radius?
Post by: guohq on January 30, 2016, 04:06:20 AM
I want to draw a cylinder with  bottom center point and top center point and radius.


edit ->kdub:title
Title: Re: how to darw a cylinder by tow points and radius?
Post by: kdub_nz on January 30, 2016, 04:09:39 AM
I want to draw a cylinder with  bottom center point and top center point and radius.

What have you tried ?
Title: Re: how to darw a cylinder by tow points and radius?
Post by: MickD on January 30, 2016, 04:22:57 AM
Hint:
look at the Solid3d class in the SDK 'managed class reference guide'. ;)
Title: Re: how to darw a cylinder by tow points and radius?
Post by: guohq on January 30, 2016, 05:08:01 AM
Solid3d.CreateFrustum  method can create a cylinder.but  I can not specify   top center point and bottom center point. So I need to align the cylinder to the specified points.
Title: Re: how to darw a cylinder by tow points and radius?
Post by: Tharwat on January 30, 2016, 06:37:32 AM
Hello,

Here is my attempt.

Code - C#: [Select]
  1.         public static void CreateCylinder()
  2.         {
  3.             Document Acdoc = Application.DocumentManager.MdiActiveDocument;
  4.             Database dbs = Acdoc.Database;
  5.             Editor edt = Acdoc.Editor;
  6.             PromptPointResult p1 = edt.GetPoint("\nSpecify 1st point :");
  7.  
  8.             PromptPointOptions ppo = new PromptPointOptions("\nSpecify 2nd point :");
  9.             ppo.AllowNone = false;
  10.             ppo.UseBasePoint = true;
  11.             ppo.BasePoint = p1.Value;
  12.             PromptPointResult p2 = edt.GetPoint(ppo);
  13.  
  14.             PromptDistanceOptions pdo = new PromptDistanceOptions("\nSpecify radius :");
  15.             pdo.UseBasePoint = true;
  16.             pdo.BasePoint = p1.Value;
  17.              
  18.              PromptDoubleResult rad = edt.GetDistance(pdo);
  19.             if (p1.Status == PromptStatus.OK && p2.Status == PromptStatus.OK && rad.Status == PromptStatus.OK)
  20.             {
  21.                 using (Transaction trans = dbs.TransactionManager.StartTransaction())
  22.                 {
  23.                     try
  24.                     {
  25.                         var sp = (BlockTableRecord)trans.GetObject(dbs.CurrentSpaceId, OpenMode.ForWrite);
  26.                         Solid3d cl = new Solid3d();
  27.                         cl.RecordHistory = true;
  28.                         cl.CreateFrustum(p1.Value.DistanceTo(p2.Value), rad.Value, rad.Value, rad.Value);
  29.                         cl.TransformBy(Matrix3d.Displacement(p1.Value - Point3d.Origin));
  30.                         sp.AppendEntity(cl);
  31.                         trans.AddNewlyCreatedDBObject(cl, true);
  32.                         trans.Commit();
  33.                     }
  34.                     catch (System.Exception x)
  35.                     {
  36.                         edt.WriteMessage(x.Message);
  37.                     }                  
  38.                 }
  39.             }
  40.         }
  41.  
Title: Re: how to darw a cylinder by tow points and radius?
Post by: gile on January 30, 2016, 06:38:08 AM
Hi,

Solid3d.CreateFrustum() creates a cylinder which centroid is on WCS origin and axis on the WCS Z axis (as most Solid3d.CreateXxxx() methods do), so, after created, you have to align the cylinder to the specified points using TransformBy() method.

Another way is to create a temporary circle, a temporary region from the circle and a temporary line to be able to use Solid3d.ExtrudeAlongPath() method.

You can also, still using temporary entities, call  the Solid3d.CreateSweptSolid() method.
Title: Re: how to darw a cylinder by tow points and radius?
Post by: gile on January 30, 2016, 06:47:43 AM
Tharwat,

Did you try your code ?
It seems to me it doesn't work as is.
More, it neither deals with current UCS different from WCS nor with non vertical cylinders.
Title: Re: how to darw a cylinder by tow points and radius?
Post by: Tharwat on January 30, 2016, 02:36:20 PM
Tharwat,

Did you try your code ?
It seems to me it doesn't work as is.
More, it neither deals with current UCS different from WCS nor with non vertical cylinders.

Hello gile.

I tried the codes before posting them but I did not notice that the origin point of the created cylinder would be in the wrong place as it should be.
Actually I am a 2D guy and not dealing with 3D works at all with my work but for this thread , I was curious to know and with a bit reading about the Solid3D entity I could have come up with codes to create the object but it needs to be revised to set the origin in its correct place.

Your second suggestion is really worth a try and I will see if I had time tomorrow at the office , I would try to write something in this regard.

Would love to see your way of coding it as well.

Thank you.
Title: Re: how to draw a cylinder by two points and radius?
Post by: kdub_nz on January 31, 2016, 02:50:20 AM
You've probably seen this ...
http://forums.autodesk.com/autodesk/board/message?board.id=152&message.id=47378#M47378


thanks gile :)

this is particularly 'nice' for learners to take notice of ..
Code - C#: [Select]
  1. using (var circle = new Circle( //.........
Title: Re: how to draw a cylinder by two points and radius?
Post by: gile on January 31, 2016, 03:21:44 AM
Some samples.

Using CreateFrustum() method and aligning the solid to the specified points.
Code - C#: [Select]
  1.         private void CreateFrustumCylinder(Point3d bottomCenterPoint, Point3d topCenterPoint, double radius)
  2.         {
  3.             var normal = bottomCenterPoint.GetVectorTo(topCenterPoint);
  4.             var plane = new Plane(bottomCenterPoint, normal);
  5.  
  6.             var db = HostApplicationServices.WorkingDatabase;
  7.             using (var tr = db.TransactionManager.StartTransaction())
  8.             {
  9.                 var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  10.                 var cylinder = new Solid3d();
  11.                 cylinder.CreateFrustum(bottomCenterPoint.DistanceTo(topCenterPoint), radius, radius, radius);
  12.                 curSpace.AppendEntity(cylinder);
  13.                 tr.AddNewlyCreatedDBObject(cylinder, true);
  14.                 cylinder.TransformBy(Matrix3d.Displacement(normal * 0.5) * Matrix3d.PlaneToWorld(plane));
  15.                 tr.Commit();
  16.             }
  17.         }

Using ExtrudeAlongPath() method. The Circle/Region normal have to be colinear to the specified points.
Code - C#: [Select]
  1.         private void CreateExtrudedCylinder(Point3d bottomCenterPoint, Point3d topCenterPoint, double radius)
  2.         {
  3.             var normal = bottomCenterPoint.GetVectorTo(topCenterPoint);
  4.  
  5.             var db = HostApplicationServices.WorkingDatabase;
  6.             using (var tr = db.TransactionManager.StartTransaction())
  7.             {
  8.                 var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  9.                 using (var circle = new Circle(bottomCenterPoint, normal, radius))
  10.                 using (var line = new Line(bottomCenterPoint, topCenterPoint))
  11.                 {
  12.                     var curveSegments = new DBObjectCollection();
  13.                     curveSegments.Add(circle);
  14.                     using (var region = (Region)Region.CreateFromCurves(curveSegments)[0])
  15.                     {
  16.                         var cylinder = new Solid3d();
  17.                         cylinder.ExtrudeAlongPath(region, line, 0.0);
  18.                         curSpace.AppendEntity(cylinder);
  19.                         tr.AddNewlyCreatedDBObject(cylinder, true);
  20.                     }
  21.                 }
  22.                 tr.Commit();
  23.             }
  24.         }

Using CreateSweptSolid() method. The Circle/Region normal have to be colinear to the specified points.
Code - C#: [Select]
  1.         private void CreateSweptCylinder(Point3d bottomCenterPoint, Point3d topCenterPoint, double radius)
  2.         {
  3.             var normal = bottomCenterPoint.GetVectorTo(topCenterPoint);
  4.  
  5.             var db = HostApplicationServices.WorkingDatabase;
  6.             using (var tr = db.TransactionManager.StartTransaction())
  7.             {
  8.                 var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  9.                 using (var circle = new Circle(bottomCenterPoint, normal, radius))
  10.                 using (var line = new Line(bottomCenterPoint, topCenterPoint))
  11.                 {
  12.                     var cylinder = new Solid3d();
  13.                     cylinder.CreateSweptSolid(circle, line, new SweepOptions());
  14.                     curSpace.AppendEntity(cylinder);
  15.                     tr.AddNewlyCreatedDBObject(cylinder, true);
  16.                 }
  17.                 tr.Commit();
  18.             }
  19.         }

A testing command
Code - C#: [Select]
  1.         [CommandMethod("CMD1")]
  2.         public void Cmd1()
  3.         {
  4.             var ed = Application.DocumentManager.MdiActiveDocument.Editor;
  5.  
  6.             var pointOptions = new PromptPointOptions("\nBottom center point: ");
  7.             var pointResult = ed.GetPoint(pointOptions);
  8.             if (pointResult.Status != PromptStatus.OK)
  9.                 return;
  10.             var bottomCenterPoint = pointResult.Value;
  11.  
  12.             var distanceOptions = new PromptDistanceOptions("\nRadius: ");
  13.             distanceOptions.UseBasePoint = true;
  14.             distanceOptions.BasePoint = bottomCenterPoint;
  15.             var distanceResult = ed.GetDistance(distanceOptions);
  16.             if (distanceResult.Status != PromptStatus.OK)
  17.                 return;
  18.             var radius = distanceResult.Value;
  19.  
  20.             pointOptions.Message = "\nTop center point: ";
  21.             pointOptions.UseBasePoint = true;
  22.             pointOptions.BasePoint = bottomCenterPoint;
  23.             pointResult = ed.GetPoint(pointOptions);
  24.             if (pointResult.Status != PromptStatus.OK)
  25.                 return;
  26.             var topCenterPoint = pointResult.Value;
  27.  
  28.             // transform the UCS defined points into WCS defined points
  29.             var ucs = ed.CurrentUserCoordinateSystem;
  30.             bottomCenterPoint = bottomCenterPoint.TransformBy(ucs);
  31.             topCenterPoint = topCenterPoint.TransformBy(ucs);
  32.  
  33.             CreateFrustumCylinder(bottomCenterPoint, topCenterPoint, radius);
  34.             //CreateExtrudedCylinder(bottomCenterPoint, topCenterPoint, radius);
  35.             //CreateSweptCylinder(bottomCenterPoint, topCenterPoint, radius);
  36.         }

<Edit: corrected a typo>
Title: Re: how to draw a cylinder by two points and radius?
Post by: guohq on January 31, 2016, 09:28:51 PM
Thanks to gile!!