Author Topic: Angle from 2 points, with UCS not World  (Read 558 times)

0 Members and 1 Guest are viewing this topic.

latour_g

  • Newt
  • Posts: 184
Angle from 2 points, with UCS not World
« on: January 29, 2024, 05:24:20 PM »
Hi,

I'm having trouble getting the angle of 2 selected points when the UCS is different from the World.

Code: [Select]

            //Angle à partir des 2 points
            Matrix3d ucsmtx = doc.Editor.CurrentUserCoordinateSystem;
            CoordinateSystem3d ucs = ucsmtx.CoordinateSystem3d;
            Plane ucsplane = new Plane(ucs.Origin, ucs.Xaxis, ucs.Yaxis);
            Vector3d vec = pntFin - selPnt;

            double selAngle = vec.AngleOnPlane(ucsplane);


This is the part of the code that give me the angle, it's working fine with UCS World.

I rarely work with Matrix3d, Plane, Vector3D... maybe it's not difficult, I'm just not used to it.

Thanks for any help !

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Angle from 2 points, with UCS not World
« Reply #1 on: January 30, 2024, 02:35:41 AM »
Hi,

You should give more precision about the context and what you wnat ti achieve.
  • Are 'pntFin' and 'selPnt' WCS points or UCS points (as returned by Editor.GetPoint)?
  • Do you want to get the angle from the WCS X axis or from the UCS Xaxis?
  • Is the UCS plane parallel to the WCS one?
« Last Edit: January 30, 2024, 03:21:02 AM by gile »
Speaking English as a French Frog

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: Angle from 2 points, with UCS not World
« Reply #2 on: January 30, 2024, 04:27:08 AM »
Hi,

I'm having trouble getting the angle of 2 selected points when the UCS is different from the World.

Code: [Select]

            //Angle à partir des 2 points
            Matrix3d ucsmtx = doc.Editor.CurrentUserCoordinateSystem;
            CoordinateSystem3d ucs = ucsmtx.CoordinateSystem3d;
            Plane ucsplane = new Plane(ucs.Origin, ucs.Xaxis, ucs.Yaxis);
            Vector3d vec = pntFin - selPnt;

            double selAngle = vec.AngleOnPlane(ucsplane);


This is the part of the code that give me the angle, it's working fine with UCS World.

I rarely work with Matrix3d, Plane, Vector3D... maybe it's not difficult, I'm just not used to it.

Thanks for any help !

See if this helps while creating a response for Gilles:

Getpoint is in UCS.
Entity construction is in WCS.

Translation is with :
Code - C#: [Select]
  1. spWCS = spUCS.TransformBy(ed.CurrentUserCoordinateSystem);

Example in ac2023,  .NET Framework 4.8 :
Code - C#: [Select]
  1. using Autodesk.AutoCAD.EditorInput;
  2. using Autodesk.AutoCAD.Geometry;
  3. using Autodesk.AutoCAD.Runtime;
  4.  
  5. using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
  6.  
  7. [assembly: CommandClass(typeof(Angles.Commands))]
  8.  
  9. namespace Angles
  10. {
  11.    public class Commands
  12.    {
  13.       [CommandMethod("TEST_UCS-WCS")]
  14.       public static void Test()
  15.       {
  16.          var doc = AcadApp.DocumentManager.MdiActiveDocument;
  17.          var db = doc.Database;
  18.          var ed = doc.Editor;
  19.  
  20.          ed.WriteMessage("Select some Points\n");
  21.  
  22.          Point3d spUCS = default, epUCS = default, spWCS = default, epWCS = default;
  23.          PromptPointResult pointResult = default;
  24.  
  25.          // Select Start Point
  26.  
  27.          pointResult = ed.GetPoint("\nSelect Start Point : ");
  28.          if (pointResult.Status == PromptStatus.OK)
  29.             spUCS = pointResult.Value;
  30.          else
  31.          {
  32.             ed.WriteMessage("\n Invalid Point Selection.");
  33.             return;
  34.          }
  35.          // Select SecondPoint
  36.  
  37.          pointResult = ed.GetPoint("\nSelect second Point : ");
  38.          if (pointResult.Status == PromptStatus.OK)
  39.             epUCS = pointResult.Value;
  40.          else
  41.          {
  42.             ed.WriteMessage("\n Invalid Point Selection.");
  43.             return;
  44.          }
  45.  
  46.          ed.WriteMessage($"\nspUCS: {spUCS:0.00000} \nepUCS: {epUCS:0.00000}");
  47.  
  48.          // ----------------
  49.  
  50.          spWCS = spUCS.TransformBy(ed.CurrentUserCoordinateSystem);
  51.          epWCS = epUCS.TransformBy(ed.CurrentUserCoordinateSystem);
  52.  
  53.          ed.WriteMessage($"\nspWCS: {spWCS:0.00000} \nepWCS: {epWCS:0.00000}");
  54.  
  55.       }
  56.    }
  57. }
  58.  

Regards,


Edit Kerry : Update Image with check Dimensions
« Last Edit: January 30, 2024, 05:59:37 PM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Angle from 2 points, with UCS not World
« Reply #3 on: January 30, 2024, 05:58:21 AM »
I also guess the input points are UCS points.
If the ouptput angle have to used as Rotation property of an entity such as BlockReference, DBText, it have to be related to the OCS of this entity which depends on the Normal of the entity. In this case we can gess this Normal is equal to the UCS Z axis (this only matters if the UCS Z axis differs from the WCS Z axis.
Code - C#: [Select]
  1.         [CommandMethod("TEST_ANGLE")]
  2.         public static void AngleFromTwoPoints()
  3.         {
  4.             var doc = Application.DocumentManager.MdiActiveDocument;
  5.             var ed = doc.Editor;
  6.  
  7.             var ppo = new PromptPointOptions("\nFirst point: ");
  8.             var ppr = ed.GetPoint(ppo);
  9.             if (ppr.Status != PromptStatus.OK)
  10.                 return;
  11.             var ucsPt1 = ppr.Value;
  12.  
  13.             ppo.Message = "\nSecond point: ";
  14.             ppo.BasePoint = ucsPt1;
  15.             ppo.UseBasePoint = true;
  16.             ppr = ed.GetPoint(ppo);
  17.             if (ppr.Status != PromptStatus.OK)
  18.                 return;
  19.             var ucsPt2 = ppr.Value;
  20.  
  21.             // Angle about UCS X axis
  22.             var ucsVector = ucsPt2 - ucsPt1;
  23.             double ucsAngle = Vector3d.XAxis.GetAngleTo(ucsVector, Vector3d.ZAxis);
  24.             ed.WriteMessage($"\nUCS Angle: {Converter.AngleToString(ucsAngle)}");
  25.  
  26.             // Angle about WCS X axis
  27.             var ucsMatrix = ed.CurrentUserCoordinateSystem;
  28.             var wcsVector = ucsVector.TransformBy(ucsMatrix);
  29.             double wcsAngle = Vector3d.XAxis.GetAngleTo(wcsVector, Vector3d.ZAxis);
  30.             ed.WriteMessage($"\nWCS Angle: {Converter.AngleToString(wcsAngle)}");
  31.  
  32.             // Rotation in OCS
  33.             var ocsPlane = new Plane(Point3d.Origin, ucsMatrix.CoordinateSystem3d.Zaxis);
  34.             double ocsRotation = wcsVector.AngleOnPlane(ocsPlane);
  35.             ed.WriteMessage($"\nOCS: {Converter.AngleToString(ocsRotation)}");
  36.         }
Speaking English as a French Frog

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: Angle from 2 points, with UCS not World
« Reply #4 on: January 30, 2024, 06:41:59 PM »
Yes, Thanks Gilles.

for brevity, string interpolation has a default Converter, so the explicit conversion is not required.

I built your angle code into my sample :

The additions/changes
Code - C#: [Select]
  1.         ed.WriteMessage($"\nspUCS: {spUCS:0.00000}   epUCS: {epUCS:0.00000} ");
  2.  
  3.         // ----------------
  4.         var ucsMatrix = ed.CurrentUserCoordinateSystem;
  5.  
  6.         spWCS = spUCS.TransformBy(ucsMatrix);
  7.         epWCS = epUCS.TransformBy(ucsMatrix);
  8.  
  9.         ed.WriteMessage($"\nspWCS: {spWCS:0.00000}   epWCS: {epWCS:0.00000} ");
  10.  
  11.         // Angle from UCS X axis
  12.         var ucsVector = epUCS - spUCS;
  13.         double ucsAngle = Vector3d.XAxis.GetAngleTo(ucsVector, Vector3d.ZAxis);
  14.         ed.WriteMessage($"\nUCS Angle(rad): {ucsAngle:0.00000}    " +
  15.                                    $"(deg): {(ucsAngle * 180.0 / Math.PI):0.00000} ");
  16.  
  17.         // Angle from UCS X axis
  18.         var wcsVector = ucsVector.TransformBy(ucsMatrix);
  19.         double wcsAngle = Vector3d.XAxis.GetAngleTo(wcsVector, Vector3d.ZAxis);
  20.         ed.WriteMessage($"\nWCS Angle(rad): {wcsAngle:0.00000}    " +
  21.                                    $"(deg): {(wcsAngle * 180.0 / Math.PI):0.00000} ");
  22.  
  23.         // Rotation in OCS (based on ucs Z Axis)
  24.         var ocsPlane = new Plane(Point3d.Origin, ucsMatrix.CoordinateSystem3d.Zaxis);
  25.         double ocsRotation = wcsVector.AngleOnPlane(ocsPlane);
  26.         ed.WriteMessage($"\nOCS Angle(rad): {ocsRotation:0.00000}    " +
  27.                                    $"(deg): {(ocsRotation * 180.0 / Math.PI):0.00000} ");
  28.  

The results:


Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Angle from 2 points, with UCS not World
« Reply #5 on: January 31, 2024, 02:08:33 AM »
[...]
for brevity, string interpolation has a default Converter, so the explicit conversion is not required.
[...]
Code - C#: [Select]
  1. {Converter.AngleToString(ucsAngle)}
converts the angle into the current angular units (as does 'angtos' LISP function) avoiding the explicit conversion;
Code - C#: [Select]
  1. {(ucsAngle * 180.0 / Math.PI):0.00000}
Speaking English as a French Frog

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: Angle from 2 points, with UCS not World
« Reply #6 on: January 31, 2024, 02:24:26 AM »
Gilles,

Well that's embarrassing !

I have code here from up to 17 years ago using Converter.AngleToString(angle)   :oops:

not enough practice doing real jobs recently, apparently !!
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

latour_g

  • Newt
  • Posts: 184
Re: Angle from 2 points, with UCS not World
« Reply #7 on: January 31, 2024, 05:09:50 PM »
Hi,

thanks to both of you for your answer.

Gile, here are the answers to your questions :
Are 'pntFin' and 'selPnt' WCS points or UCS points (as returned by Editor.GetPoint)? UCS points
Do you want to get the angle from the WCS X axis or from the UCS Xaxis? UCS X axis
Is the UCS plane parallel to the WCS one? Yes (I guess we are talking about the Z here? everything is on 0)

Sorry I could have put the code for getting the two points :

Code: [Select]
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Point3d lastPnt = new Point3d(0, 0, 0);

            PromptPointOptions ppo = null;
            PromptPointResult resPt = null;

            ppo = new PromptPointOptions(rmD.GetString("INSPointDebut"));
            ppo.BasePoint = lastPnt;
            ppo.UseBasePoint = keepPrv;
            ppo.AllowNone = true;
            resPt = doc.Editor.GetPoint(ppo);
            selPnt = (resPt.Status != PromptStatus.OK) ? lastPnt : resPt.Value;
         

            ppo = new PromptPointOptions(rmD.GetString("INSPointFin"));
            ppo.BasePoint = selPnt;
            ppo.UseBasePoint = true;
            ppo.AllowNone = true;
            resPt = doc.Editor.GetPoint(ppo);
            //
            Point3d pntFin = (resPt.Status != PromptStatus.OK) ? lastPnt : resPt.Value;

            //Angle à partir des 2 points
            Matrix3d ucsmtx = doc.Editor.CurrentUserCoordinateSystem;
            CoordinateSystem3d ucs = ucsmtx.CoordinateSystem3d;
            Plane ucsplane = new Plane(ucs.Origin, ucs.Xaxis, ucs.Yaxis);
            Vector3d vec = pntFin - selPnt;

            double selAngle = vec.AngleOnPlane(ucsplane);

            //distance à partir des 2 points
            double selLength = selPnt.DistanceTo(pntFin);

I will take time tomorrow to take a look more attentively on the code you both sent me.

Thanks again !