### Author Topic: Angle from 2 points, with UCS not World  (Read 405 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

• Water Moccasin
• Posts: 2492
• 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: 2071
• 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]
4.
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.       {
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

Sometimes the question is more important than the answer.

#### gile

• Water Moccasin
• Posts: 2492
• 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: 2071
• 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 :

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

Sometimes the question is more important than the answer.

#### gile

• Water Moccasin
• Posts: 2492
• 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: 2071
• 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)

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

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,

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]
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 !