Orienting newly added UCS "bottom down"

Orienting newly added UCS "bottom down"

CadWCCNL
Enthusiast Enthusiast
708 Views
5 Replies
Message 1 of 6

Orienting newly added UCS "bottom down"

CadWCCNL
Enthusiast
Enthusiast
//Get Vector from origin to xaxis
double[] xaxisVec = new double[3];
xaxisVec[0] = xaxis[0] - origin[0];
xaxisVec[1] = xaxis[1] - origin[1];
xaxisVec[2] = xaxis[2] - origin[2];
//Get Vector from origin to yaxis
double[] yaxisVec = new double[3];
yaxisVec[0] = yaxis[0] - origin[0];
yaxisVec[1] = yaxis[1] - origin[1];
yaxisVec[2] = yaxis[2] - origin[2];


double[] xCy = Cross3D(xaxisVec, yaxisVec);
double[] normyaxisVec = Cross3D(xaxisVec, xCy);

acUCSTblRec = acTrans.GetObject(acUCSTable[name],
                                    OpenMode.ForWrite) as UcsTableRecord;

acUCSTblRec.Origin = new Point3d(origin);
acUCSTblRec.XAxis = new Vector3d(xaxisVec);
acUCSTblRec.YAxis = new Vector3d(normyaxisVec);

 

With a newly generated UCS given Point3d origin, Vector3d Xaxis, Vector3d yaxis:

Is it possible insure that the orientation of the UCS is always "bottom down" & "top up"?

0 Likes
Accepted solutions (1)
709 Views
5 Replies
Replies (5)
Message 2 of 6

_gile
Consultant
Consultant
Accepted solution

Hi,

 

It is very difficult, if not impossible, to answer you without knowing what exactly does the 'Cross3d' method.

 

The Geometry namespace of the AutoCAD .NET API provides a Point3d structure and a Vector3d structure with many methods for manipulating points and vectors which should save you from having to define custom methods.

 

Assuming origin, xaxisPt and yaxisPt are Point3d instances instead of array of doubles, you could write the same thing like this:

            //Get Vector from origin to xaxis
            Vector3d xaxisVec = origin.GetVectorTo(xaxisPt);
            //Get Vector from origin to yaxis
            Vector3d yaxisVec = origin.GetVectorTo(yaxisPt);

            Vector3d zaxisVec = xaxisVec.CrossProduct(yaxisVec);
            yaxisVec = zaxisVec.CrossProduct(xaxisVec);

            acUCSTblRec = acTrans.GetObject(acUCSTable[name], OpenMode.ForWrite) as UcsTableRecord;
            acUCSTblRec.Origin = origin;
            acUCSTblRec.XAxis = xaxisVec.GetNormal();
            acUCSTblRec.YAxis = yaxisVec.GetNormal();

 

The cross product of X axis vector by Y axis vectors generates a Z axis vector which respects the "right hand rule".

Then, to insure the Y axis to be perpendicular to the X axis respecting the "right hand rule", you have to get the cross product of the Z axis by the X axis. This orger is mandatory because the cross product is not a commutative operation.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 6

CadWCCNL
Enthusiast
Enthusiast

Apologies!

 

 

        public static double[] Cross3D(double[] A, double[] B)
        {
            if (A.Length != 3 || B.Length != 3)
            {
                string message = "Vectors must have a length of 3";
                throw new System.Exception(message);
            }
            double[] C = new double[3];
            C[0] = (A[1] * B[2]) - (A[2] * B[1]);
            C[1] = -((A[0] * B[2]) - (A[2] * B[0]));
            C[2] = (A[0] * B[1]) - (A[1] * B[0]);
            return C;
        }

 

 

 

Well this is news to me! I have been casting them out of their native and writing custom functions and rebuilding Autocad types as needed...me wasting my own time aside...

 

Origin, xaxis, yaxis are indeed Point3D's originally (prior to being given to this function creating the UCS).  From your code it looks functionally the same, minus the yvec being crossproduct(z, x) vs (x, z), changing this flips all the outputed UCS's orientation 180. 

 

My understanding of the right-hand rule and it's uses is near NULL, I basically understand it's something that exists  and when respected, certain questions become easier (or possible) to answer😅 I also assumed that AutoCAD stores it's lines and poly's with handedness in mind. (based on minimal observations clicking next vertex on a few closed 3dpolylines) Please be gentle!

 

EDIT: 

 

 

acUCSTblRec.XAxis = xaxisVec.GetNormal();
acUCSTblRec.YAxis = yaxisVec.GetNormal();

 

 

 

Just noticed this bit...Tried with:

 

 

 

acUCSTblRec.Origin = new Point3d(origin);
acUCSTblRec.XAxis = new Vector3d(xaxisVec).GetNormal();
acUCSTblRec.YAxis = new Vector3d(perpYaxisPnt).GetNormal();

 

 

 

Having the same issue where this just flips all the coins. Top up to Top down and visa versa.

0 Likes
Message 4 of 6

CadWCCNL
Enthusiast
Enthusiast

@_gile Updated code to use the native types of AutoCAD and the available methods they come with. Very succinct. On that note alone you have saved me hours of future hassle, thank you.

 

Still have the same behavior though. I feel that I am missing some kind of conditional trick here. I have a series of X surfaces that need UCS's generated, all in the same drawing. It would be great if "top" was oriented for "top" in the WCS. I'm not sure if I'm heading in the right direction, but degrees of rotation required to rotate a vector to be parallel with z axis > 180 degrees = flip x/y. Something like that possible. I am looking further into this to see if there is a way to do that.

0 Likes
Message 5 of 6

_gile
Consultant
Consultant

If I don't misunderstand, the issue comes from the the specified points.

As said upper, coordinate systems uses the "right hand rule" to compute the axis. IOW, when looking from the "top", origin, point on x and point on Y are counterclockwise.

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 6

CadWCCNL
Enthusiast
Enthusiast

You are correct, I was able to fix it! I really appreciate your help, you are a champion of the people sir.

0 Likes