Author Topic: How do you get a pickpoint on a line as a 3d point ?  (Read 4742 times)

0 Members and 1 Guest are viewing this topic.

Peter Laker

  • Guest
How do you get a pickpoint on a line as a 3d point ?
« on: February 23, 2008, 12:05:00 AM »
Just started getting into C# & can't work out how to get a 3d point from a pick point on a 3d line.
I have worked out this so far which works ok in 2d but not 3d, in 3d it looks like it returns a point in the DCS (it's got no Z)

Point3d pickPt = entitySelectionResult.PickedPoint;

I have seen some reference made to PointOnLine but can't work out how to use it.

Any help would be appreciated, Thanks...

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #1 on: February 23, 2008, 12:33:59 AM »
Code - C#: [Select]
  1.  
Hello Peter ;

Have a play with something like  this
..
Code - C#: [Select]
  1. //// CodeHimBelongaKwb ©  Feb 2008
  2.  
  3.         [AcRx.CommandMethod("ListIt")]
  4.         static public void ListIt()
  5.         {
  6.             AcEd.Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
  7.             AcEd.PromptEntityResult resEnt = ed.GetEntity("\nSelect an Object: ");
  8.             if (resEnt.Status != AcEd.PromptStatus.OK)
  9.             {
  10.                 ed.WriteMessage("\nNothing selected");
  11.                 return;
  12.             }
  13.             // Something selected, so ..
  14.             // do come stuff ..
  15.             ed.WriteMessage("\n PromptEntityResult : " + resEnt.ToString());
  16.             ed.WriteMessage("\n PickedPoint : " + resEnt.PickedPoint.ToString());
  17.  
  18.             // Get the ObjectId
  19.             AcDb.ObjectId ObjId = (resEnt.ObjectId);
  20.             ed.WriteMessage("\n Object Id : " + resEnt.ObjectId.ToString());
  21.  
  22.             // Add Breakpoint here
  23.             Point3d pickPt = resEnt.PickedPoint;
  24.  
  25.             // Get the Entity
  26.             AcDb.Entity ent = kdubGetEntity(resEnt.ObjectId);
  27.             ed.WriteMessage("\n Entity : " + ent.ToString() + "\n");
  28.             ent.List();
  29.  
  30.             Extents3d extents3D = ent.GeometricExtents;
  31.             ed.WriteMessage("\n extents3D : " + extents3D.ToString());
  32.             ed.WriteMessage("\n extents3D.LLPoint : " + extents3D.MinPoint.ToString());
  33.             ed.WriteMessage("\n extents3D.URPoint : " + extents3D.MaxPoint.ToString());
  34.  
  35.             // PROBLEM : how to locate the Entity WCS location ??
  36.  
  37.             Matrix3d ecsPossy = ent.Ecs;
  38.             ed.WriteMessage("\n ECS : " + ecsPossy.ToString());
  39.  
  40.         }
  41.  
  42.         public static Entity kdubGetEntity(AcDb.ObjectId id)
  43.         {
  44.             AcDb.Entity ent;
  45.             AcDb.TransactionManager tm =
  46.                 AcadApp.DocumentManager.MdiActiveDocument.TransactionManager;
  47.    
  48.             using (AcDb.Transaction tr = tm.StartTransaction())
  49.             {
  50.                 ent = (AcDb.Entity)tm.GetObject(id, AcDb.OpenMode.ForRead, true);
  51.             }
  52.             return ent;
  53.         }
« Last Edit: August 10, 2023, 02:25:15 AM by kdub_nz »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #2 on: February 23, 2008, 12:50:44 AM »
Quote
Command: list
Select objects: 1 found

Select objects:

                  LINE      Layer: "0"
                            Space: Model space
                   Handle = 7f
              from point, X= 223.7900  Y=   0.0000  Z= 222.1967
                to point, X=1538.5387  Y= 867.8355  Z=-368.4467
Extrusion direction relative to UCS:
                   X=   0.0000  Y=   1.0000  Z=   0.0000
          In Current UCS, Length =1575.3420,  Angle in XY Plane =     33
                  3D Length  =1682.4275,  Angle from XY Plane =    339
                  Delta X =1314.7487, Delta Y =  867.8355, Delta Z =-590.6434

Command: listit

Select an Object: _MID of
 PromptEntityResult :
((OK,),(2130436152),(881.164319159307,433.917747505122,-73.125000386091))
 PickedPoint : (881.164319159307,433.917747505122,-73.125000386091)
 Object Id : (2130436152)
 Entity : Autodesk.AutoCAD.DatabaseServices.Line
                  LINE      Layer: "0"
                            Space: Model space
                   Handle = 7f
              from point, X= 223.7900  Y=   0.0000  Z= 222.1967
                to point, X=1538.5387  Y= 867.8355  Z=-368.4467
Extrusion direction relative to UCS:
                   X=   0.0000  Y=   1.0000  Z=   0.0000
          In Current UCS, Length =1575.3420,  Angle in XY Plane =     33
                  3D Length  =1682.4275,  Angle from XY Plane =    339
                  Delta X =1314.7487, Delta Y =  867.8355, Delta Z =-590.6434

 extents3D :
((223.789977837311,-222.196720773481,0),(1538.5386604813,368.446721545663,867.835495010243))
 extents3D.LLPoint : (223.789977837311,-222.196720773481,0)
 extents3D.URPoint : (1538.5386604813,368.446721545663,867.835495010243)
 ECS : ((1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1))

and the piccy
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #3 on: February 23, 2008, 01:54:01 AM »
This may help too ..

Add these helpers  to a static class
Code - C#: [Select]
  1.  
  2. // CodeHimBelongaKwb ©  Feb 2008
  3.  
  4. public static partial class dbExtensions
  5.     {
  6.         public static AcGe.Point3d UcsToWcs(this AcGe.Point3d pt, AcDb.Database db)
  7.         {
  8.             return pt.TransformBy(db.GetUcsMatrix());
  9.         }
  10.         public static bool IsPaperSpaceActive(this AcDb.Database db)
  11.         {
  12.             if (db.TileMode)
  13.             { return false; }
  14.             return (db.PaperSpaceVportId == AcadApp.DocumentManager.MdiActiveDocument.
  15.                 Editor.CurrentViewportObjectId);
  16.         }
  17.         public static AcGe.Matrix3d GetUcsMatrix(this AcDb.Database db)
  18.         {
  19.             AcGe.Point3d ucsorgin = db.Ucsorg;
  20.             AcGe.Vector3d ucsxdir = db.Ucsxdir;
  21.             AcGe.Vector3d ucsydir = db.Ucsydir;
  22.             // re-assign variables if PaperSpace is Active            
  23.             if (db.IsPaperSpaceActive())
  24.             {
  25.                 ucsorgin = db.Pucsorg;
  26.                 ucsxdir = db.Pucsxdir;
  27.                 ucsydir = db.Pucsydir;
  28.             }
  29.             // Vector3d newZAxis = ucsxdir.CrossProduct(ucsydir);          
  30.             return Matrix3d.AlignCoordinateSystem(
  31.                 AcGe.Point3d.Origin,
  32.                 AcGe.Vector3d.XAxis,
  33.                 AcGe.Vector3d.YAxis,
  34.                 AcGe.Vector3d.ZAxis,
  35.                 ucsorgin,
  36.                 ucsxdir,
  37.                 ucsydir,
  38.                 ucsxdir.CrossProduct(ucsydir)
  39.              );
  40.         }
  41.     }

Amend the code to return the point in WCS as well as UCS
Code - C#: [Select]
  1.  
  2.         // // CodeHimBelongaKwb ©  Feb 2008      
  3.         [AcRx.CommandMethod("ListIt")]
  4.         static public void ListIt()
  5.         {
  6.             AcDb.Database db = AcDb.HostApplicationServices.WorkingDatabase;
  7.             AcEd.Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
  8.             AcEd.PromptEntityResult resEnt = ed.GetEntity("\nSelect an Object: ");
  9.             if (resEnt.Status != AcEd.PromptStatus.OK)
  10.             {
  11.                 ed.WriteMessage("\nNothing selected");
  12.                 return;
  13.             }
  14.             // Something selected, so ..
  15.             // do come stuff ..
  16.             ed.WriteMessage("\n PromptEntityResult : " + resEnt.ToString());          
  17.  
  18.             AcGe.Point3d pickPt = resEnt.PickedPoint;
  19.             ed.WriteMessage("\n PickedPoint in UCS : " + pickPt.ToString());
  20.  
  21.             AcGe.Point3d WCSPoint = pickPt.UcsToWcs(db);
  22.             ed.WriteMessage("\n Picked Point in WCS : " + WCSPoint.ToString());
  23.  
  24.             // Get the ObjectId
  25.             AcDb.ObjectId ObjId = (resEnt.ObjectId);            
  26.             ed.WriteMessage("\n Object Id : " + resEnt.ObjectId.ToString());
  27.  
  28.             // Get the Entity
  29.             AcDb.Entity ent = kdubGetEntity(resEnt.ObjectId);
  30.             ed.WriteMessage("\n Entity : " + ent.ToString() + "\n");
  31.             ent.List();
  32.  
  33.             AcGe.Extents3d extents3D = ent.GeometricExtents;
  34.             ed.WriteMessage("\n extents3D : " + extents3D.ToString());
  35.             ed.WriteMessage("\n extents3D.LLPoint : " + extents3D.MinPoint.ToString());
  36.             ed.WriteMessage("\n extents3D.URPoint : " + extents3D.MaxPoint.ToString());            
  37.  
  38.             AcGe.Matrix3d ecsPossy = ent.Ecs;
  39.             ed.WriteMessage("\n ECS : " + ecsPossy.ToString());
  40.         }

and the result :-
Command: ListIt

Select an Object: _MID of
 PromptEntityResult :
((OK,),(2130436152),(106.529729152112,1.92859694466527E-14,-86.8562848134239))
PickedPoint in UCS : (106.529729152112,1.92859694466527E-14,-86.8562848134239)
Picked Point in WCS : (106.529729152112,86.8562848134239,0)
 Object Id : (2130436152)
..>>>>>>>>>>
« Last Edit: August 10, 2023, 02:26:37 AM by kdub_nz »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #4 on: February 23, 2008, 02:02:02 AM »
And this is the typical header I use ...
may clarify some of the class addresses listed :-)
Code - C#: [Select]
  1. // CodeHimBelongaKwb ©  Feb 2008
  2.  
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Text;
  7. using System.Data;
  8. using System.Linq;
  9. using System.Windows.Forms;
  10.  
  11. // using System.Runtime.InteropServices;
  12.  
  13. using Autodesk.AutoCAD.ApplicationServices;
  14. using Autodesk.AutoCAD.DatabaseServices;
  15. using Autodesk.AutoCAD.EditorInput;
  16. using Autodesk.AutoCAD.Geometry;
  17. using Autodesk.AutoCAD.Runtime;
  18. //
  19. using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
  20. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  21. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  22. using AcEd = Autodesk.AutoCAD.EditorInput;
  23. using AcGe = Autodesk.AutoCAD.Geometry;
  24. using AcRx = Autodesk.AutoCAD.Runtime;
  25. //
  26. using AcCm = Autodesk.AutoCAD.Colors;
  27. using AcGi = Autodesk.AutoCAD.GraphicsInterface;
  28. using AcLy = Autodesk.AutoCAD.LayerManager;
  29. using AcPl = Autodesk.AutoCAD.PlottingServices;
  30. using AcUi = Autodesk.AutoCAD.Windows;
  31.  
  32. using WinForms = System.Windows.Forms;
« Last Edit: August 10, 2023, 02:31:57 AM by kdub_nz »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Peter Laker

  • Guest
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #5 on: February 23, 2008, 06:10:27 PM »
Awesome reply Kerry thanks.

I see in your samples that you have used mid point snap to select the line, in the testing I have been doing I haven't been using any snaps hence no Z.

I was trying to use this function without having to have the user select any snap modes when selecting the line, just run the command & pick.

Using your Listit function on the test2 drawing attached if I select a point on the line inside the green circle I get the following returned.
You will see on the PromptEntityResult: the Z is 0.
Quote
Command: listit

Select an Object:
 PromptEntityResult : ((OK,),(2130326424),(-108.540422813801,1969.286990748,0))
 PickedPoint in UCS : (-108.540422813801,1969.286990748,0)
 Picked Point in WCS : (-108.540422813801,1969.286990748,0)
 Object Id : (2130326424)
 Entity : Autodesk.AutoCAD.DatabaseServices.Line
                  LINE      Layer: "0"
                            Space: Model space
                   Handle = 1b3
              from point, X= 837.3668  Y= 811.1579  Z=1178.9697
                to point, X=1086.9430  Y=1698.9099  Z= 157.6337
Extrusion direction relative to UCS:
                   X=   0.0000  Y=  -1.0000  Z=   0.0000
          In Current UCS, Length = 922.1669,  Angle in XY Plane =     74
                  3D Length  =1376.0520,  Angle from XY Plane =    312
                  Delta X = 249.5762, Delta Y =  887.7520, Delta Z =-1021.3360

 extents3D :
((837.36683616951,811.157907859753,157.633678487386),(1086.94300072584,1698.9099
0309033,1178.96967277117))
 extents3D.LLPoint : (837.36683616951,811.157907859753,157.633678487386)
 extents3D.URPoint : (1086.94300072584,1698.90990309033,1178.96967277117)
 ECS :
((1,0,0,0),(0,2.22044604925031E-16,-1,0),(0,1,2.22044604925031E-16,0),(0,0,0,1))


I have added a snap mode near to the PickPoint.
Code: [Select]
//Point3d pickPt = resEnt.PickedPoint;
Point3d pickPt = ed.Snap("NEAR", resEnt.PickedPoint);
ed.WriteMessage("\n PickedPoint in UCS : " + pickPt.ToString());
           


Listit using snap near code above.
You will see that the PromptEntityResult: has no Z & the PickPoint in UCS & WCS are now on the line.
This solution works for what I'm doing but I'm just wondering if a snap mode can be used with the first pick point or if there is another solution.
Quote
Command: listit

Select an Object:
 PromptEntityResult :
((OK,),(2130461592),(-104.371741178205,1962.27347647723,0))
 PickedPoint in UCS : (883.703374628186,975.978753399603,989.347500066942)
 Picked Point in WCS : (883.703374628186,975.978753399603,989.347500066942)
 Object Id : (2130461592)
 Entity : Autodesk.AutoCAD.DatabaseServices.Line
                  LINE      Layer: "0"
                            Space: Model space
                   Handle = 1b3
              from point, X= 837.3668  Y= 811.1579  Z=1178.9697
                to point, X=1086.9430  Y=1698.9099  Z= 157.6337
Extrusion direction relative to UCS:
                   X=   0.0000  Y=  -1.0000  Z=   0.0000
          In Current UCS, Length = 922.1669,  Angle in XY Plane =     74
                  3D Length  =1376.0520,  Angle from XY Plane =    312
                  Delta X = 249.5762, Delta Y =  887.7520, Delta Z =-1021.3360

 extents3D :
((837.36683616951,811.157907859753,157.633678487386),(1086.94300072584,1698.9099
0309033,1178.96967277117))
 extents3D.LLPoint : (837.36683616951,811.157907859753,157.633678487386)
 extents3D.URPoint : (1086.94300072584,1698.90990309033,1178.96967277117)
 ECS :
((1,0,0,0),(0,2.22044604925031E-16,-1,0),(0,1,2.22044604925031E-16,0),(0,0,0,1))


Thanks again Kerry your a mountain of knowledge.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #6 on: February 24, 2008, 05:35:27 AM »
Peter,

I appears that the value held internally in the AcEd.PromptEntityResult IS in the DCS when there is no manual Osnap Override.

With your Test2 Drawing,
Rotate the UCS about X 90 and run the routine again.
Currently in the drawing, The active UCS is world ; so any selection , reported in UCS, will be the same as world.

For instance, before UCS rotation ;
the top of the line marked with a circle is now ;
Command: id
Specify point: _ENDP of  X = 837.3668     Y = 811.1579     Z = 1178.9697

when I rotate the ucs X 90 [ front ]
the top point is ;
Command: id
Specify point: _ENDP of  X = 837.3668     Y = 1178.9697     Z = -811.1579

Run Listit selecting the ' _END' of the same line ;
 PromptEntityResult :
((OK,),(2130633624),(837.36683616951, 1178.96967277117, -811.157907859751))
 PickedPoint in UCS : (837.36683616951,1178.96967277117,-811.157907859751)
 Picked Point in WCS : (837.36683616951,811.157907859753,1178.96967277117)

Change code to : (similar to your mod but using  "_ENDPOINT" )
{I know _ENDP would hardly ever be used , but it does select at a demonstrable known point}
selecting the same line, at the upper end ;
 PromptEntityResult : ((OK,),(2130633624),(1649.62730512099, 2001.15440070052, 0))
 PickedPoint in UCS : (837.36683616951,1178.96967277117,-811.157907859751)
 Picked Point in WCS : (837.36683616951,811.157907859753,1178.96967277117)
 
 
  Interesting bit of a testing exercise  :-)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #7 on: February 24, 2008, 06:10:11 AM »

This is related :-
http://www.theswamp.org/index.php?topic=21568.0
but I ran out of time ...
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #8 on: February 29, 2008, 10:25:30 PM »
Peter,

This may be handy , using the Library routines from  http://www.theswamp.org/index.php?topic=21568.0
... and the  reciprocal translations of course :-)
Code: [Select]
            AcGe.Point3d DCSPoint = WCSPoint.TranslateCoordinates(
                     dbExtensions.CoOrds.WCS,
                     dbExtensions.CoOrds.DisplayDCS
            );
            ed.WriteMessage("\n Picked Point translated WCS->DisplayDCS : " + DCSPoint.ToString());
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #9 on: March 01, 2008, 12:29:02 PM »
Quote
I appears that the value held internally in the AcEd.PromptEntityResult IS in the DCS when there is no manual Osnap Override.
Kerry, I've found it to be in ucs form, although .net may have a different version of Dcs than vba.
Quote
DCS
Display coordinate system: The coordinate system where objects are transformed before they are displayed. The origin of the DCS is the point stored in the AutoCAD system variable TARGET, and its Z axis is the viewing direction. In other words, a viewport is always a plan view of its DCS. These coordinates can be used to determine where something will be displayed to the AutoCAD user.

MickD

  • King Gator
  • Posts: 3646
  • (x-in)->[process]->(y-out) ... simples!
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #10 on: March 02, 2008, 04:13:41 PM »
If you don't use a snap to pick a point, the z value will always be the value of the pick point projected to current x/y working plane, therefore it will be 0.0. Otherwise the z value could be just 'anywhere', it is logical though to use the x and y values as that is the current work plane - if that makes sense :).
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Bryco

  • Water Moccasin
  • Posts: 1883
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #11 on: March 03, 2008, 08:35:30 PM »
Mick that's what it should be, so far my tests don't hold up that way.

Peter Laker

  • Guest
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #12 on: March 03, 2008, 11:39:12 PM »
Peter,

This may be handy , using the Library routines from  http://www.theswamp.org/index.php?topic=21568.0
... and the  reciprocal translations of course :-)
Code: [Select]
            AcGe.Point3d DCSPoint = WCSPoint.TranslateCoordinates(
                     dbExtensions.CoOrds.WCS,
                     dbExtensions.CoOrds.DisplayDCS
            );
            ed.WriteMessage("\n Picked Point translated WCS->DisplayDCS : " + DCSPoint.ToString());


I haven't had time to play with much of this been working at the day job to much.
Thanks for your help Kerry  8-)
« Last Edit: March 03, 2008, 11:47:14 PM by Peter Laker »

Peter Laker

  • Guest
Re: How do you get a pickpoint on a line as a 3d point ?
« Reply #13 on: March 03, 2008, 11:41:30 PM »
If you don't use a snap to pick a point, the z value will always be the value of the pick point projected to current x/y working plane, therefore it will be 0.0. Otherwise the z value could be just 'anywhere', it is logical though to use the x and y values as that is the current work plane - if that makes sense :).

Yes I aggree Mick, when I was testing this is exactly what was happening  :-)