Author Topic: Rotate the Current UCS using vla methods  (Read 3626 times)

0 Members and 1 Guest are viewing this topic.

PKENEWELL

  • Bull Frog
  • Posts: 320
Rotate the Current UCS using vla methods
« on: July 05, 2016, 03:56:18 PM »
Hi folks,

I have been working on a program for making 3D holes, and currently I am using (command "._ucs" "x" "90") to rotate the current UCS to create a profile for a revolved solid.

My question is: How does one rotate the current UCS to a specified angle without using the UCS command? i.e. using the methods (vla-put-xvector) and/or (vla-put-yvector). Is it even advisable to use Visual LISP for this? I'm afraid I am rather deficient in understanding vector transformations. I do not know the formula for example to rotate the UCSYDIR from (0.0 1.0 0.0) to (0.0 0.0 1.0) or the equivalent of the above UCS command to rotate the UCS around the X axis 90 degrees (or any axis or angle for that matter).

I have tried searching for this on the forums but have come up short. Could someone provide a relatively simple explanation for the vector challenged?

Thanks for your time!
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Rotate the Current UCS using vla methods
« Reply #1 on: July 05, 2016, 06:46:05 PM »
Code - Auto/Visual Lisp: [Select]
  1. (defun setucs ( origin xdir ydir / *adoc* ucs )
  2.  
  3.  
  4.   (setq ucs (vla-add (vla-get-usercoordinatesystems (setq *adoc* (vla-get-activedocument (vlax-get-acad-object)))) (vlax-3d-point origin) (vlax-3d-point (mapcar '+ origin xdir)) (vlax-3d-point (mapcar '+ origin ydir)) "{ UCS }"))
  5.   (vla-put-activeucs *adoc* ucs)
  6.   (command "_.UCS" "_D" "{ UCS }")
  7. )
  8.  

Used arguments, variables and defun syntax is self descriptive...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

PKENEWELL

  • Bull Frog
  • Posts: 320
Re: Rotate the Current UCS using vla methods
« Reply #2 on: July 06, 2016, 09:24:35 AM »
Code - Auto/Visual Lisp: [Select]
  1. (defun setucs ( origin xdir ydir / *adoc* ucs )
  2.  
  3.  
  4.   (setq ucs (vla-add (vla-get-usercoordinatesystems (setq *adoc* (vla-get-activedocument (vlax-get-acad-object)))) (vlax-3d-point origin) (vlax-3d-point (mapcar '+ origin xdir)) (vlax-3d-point (mapcar '+ origin ydir)) "{ UCS }"))
  5.   (vla-put-activeucs *adoc* ucs)
  6.   (command "_.UCS" "_D" "{ UCS }")
  7. )
  8.  

Used arguments, variables and defun syntax is self descriptive...

Hi Marko,

Thanks for the reply. I do understand how to create a UCS with known vector values. What I need to understand is how to rotate a vector mathematically around an axis to a specified angle, to plug in a new X direction or Y Direction for your function. Example: YDIR = (0.0 1.0 0.0) then rotate around X axis by angle A in radians = ?
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Rotate the Current UCS using vla methods
« Reply #3 on: July 06, 2016, 09:39:13 AM »
There are various ways to calculate for this... Maybe the most simple one is not to use matrix calculation, but built-in functions :

Code - Auto/Visual Lisp: [Select]
  1. (defun rotucsXaxis ( ang / setucs xdir ydir yvec sang eang yvecn ydirn )
  2.  
  3.   (defun setucs ( origin xdir ydir / *adoc* ucs )
  4.  
  5.     (vl-load-com)
  6.  
  7.     (setq ucs (vla-add (vla-get-usercoordinatesystems (setq *adoc* (vla-get-activedocument (vlax-get-acad-object)))) (vlax-3d-point origin) (vlax-3d-point (mapcar '+ origin xdir)) (vlax-3d-point (mapcar '+ origin ydir)) "{ UCS }"))
  8.     (vla-put-activeucs *adoc* ucs)
  9.     (command "_.UCS" "_D" "{ UCS }")
  10.   )
  11.  
  12.   (setq xdir (getvar 'ucsxdir))
  13.   (setq ydir (getvar 'ucsydir))
  14.   (setq yvec (trans ydir 0 xdir))
  15.   (setq sang (angle '(0.0 0.0) yvec))
  16.   (setq eang (+ sang ang))
  17.   (setq yvecn (polar '(0.0 0.0) eang 1.0))
  18.   (setq ydirn (trans yvecn xdir 0))
  19.  
  20.   (setucs (getvar 'ucsorg) xdir ydirn)
  21.   (princ)
  22. )
  23.  

The above code - not tested...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

PKENEWELL

  • Bull Frog
  • Posts: 320
Re: Rotate the Current UCS using vla methods
« Reply #4 on: July 06, 2016, 12:27:10 PM »
There are various ways to calculate for this... Maybe the most simple one is not to use matrix calculation, but built-in functions :

Thanks Mark - I'll study your code. I admit I do not completely understand the use of (trans... in the way you are using it to translate the vectors. My ultimate goal is to create a function to rotate a UCS around any axis with a function like (RotateUCS "X" (/ pi 2)) or (RotateUCS "Y" (/ pi 4)) and avoid using the UCS command.
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Rotate the Current UCS using vla methods
« Reply #5 on: July 06, 2016, 02:06:10 PM »
You wouldn't necessarily be doing rotation operations, at least if you are only swapping axis directions.  The UCS axis directions are determined by two primary, mutually perpendicular vectors (the Z-axis is mutually perpendicular to both).  You can quickly flip the UCS axis directions by swapping ordinate values in the unit vectors.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

PKENEWELL

  • Bull Frog
  • Posts: 320
Re: Rotate the Current UCS using vla methods
« Reply #6 on: July 06, 2016, 02:40:37 PM »
You wouldn't necessarily be doing rotation operations, at least if you are only swapping axis directions.  The UCS axis directions are determined by two primary, mutually perpendicular vectors (the Z-axis is mutually perpendicular to both).  You can quickly flip the UCS axis directions by swapping ordinate values in the unit vectors.

Hi dgorsman,

Yes - for the application I stated in my original post, just flipping vectors would probably work fine, since your just working in 90 degree steps. I wanted to expand it however to be able to rotate a vector around an axis to any angle.

@Marko,

Could you explain how the trans function works in your example? Still not grasping the concept of how trans works in that situation. For rotating around "Y" I simply reversed the arguments without necessarily understanding how It works i.e. switching xdir and ydir in your statements worked. Now since I don't understand how it works, I don't know how to handle the "Z" axis?
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Rotate the Current UCS using vla methods
« Reply #7 on: July 06, 2016, 04:13:23 PM »
Hi, trans functions like this :

- you get vectors Xdir and Ydir
- then you go to imaginary OCS of Xdir with trans (trans Ydir 0 Xdir) - OCS Z axis is actually Xdir and Ydir vector is translated from WCS to Xdir OCS - of course OCS is just explanation
- then you work in Xdir OCS with vector Ydir translated, so you firstly calculate initial angle of Ydir translated - basically the same like you are in WCS (angle '(0.0 0.0) Ydir-translated)
- then you add argument angle to calculated initial angle, so you know new position of Ydir-translated
- then you use that angle through (polar) function to obtain position of new rotated Ydir-translated-new (polar '(0.0 0.0) eang 1.0); eang is calculated angle and distance of 1.0 means that Ydir-translated-new is unit vector - ort in OCS of Xdir
- finally you just translate Ydir-translated-new from OCS of Xdir back to WCS to get actual vector expressed in real WCS coordinates...
- then you simply provide that Ydir-trnaslated-new along with origin and Xdir through (setucs) function to perform UCS transformation...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Rotate the Current UCS using vla methods
« Reply #8 on: July 06, 2016, 04:21:26 PM »
For rotation around Y axis :

- you get Xdir and Ydir from WCS with (getvar 'ucsxdir) and 'ucsydir...
- you go to OCS of Ydir with (trans Xdir 0 Ydir)
- you calculate initial angle of Xdir in Ydir OCS (angle '(0.0 0.0) Xdir-translated)
- you add argument angle to initial angle = (+ sang ang) = eang
- you calculate Xdir-translated-new in Ydir OCS using (polar) - (polar '(0.0 0.0) eang 1.0)
- you translate Xdir-translated-new from Ydir OCS to WCS (trans Xdir-translated-new Ydir 0)
- you provide (setucs (getvar 'ucsorg) Xdir-translated-new Ydir)...

HTH.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Rotate the Current UCS using vla methods
« Reply #9 on: July 06, 2016, 04:26:24 PM »
For rotation around Z axis :

- you get Xdir and Ydir
- you translate Xdir from WCS to UCS - (trans Xdir 0 1) - this should always be '(1.0 0.0 0.0)
- you get initial angle of Xdir using (angle '(0.0 0.0) Xdir) = sang - this should always be 0.0
- you add initial angle with argument angle (+ sang ang) = eang
- you get Xdir-rotated using (polar) - (polar '(0.0 0.0) eang 1.0) - ort vector of Xdir-rotated
- you calculate Ydir-rotated - (polar '(0.0 0.0) (+ eang (* 0.5 pi)) 1.0) - also ort vector of Ydir-rotated
- you translate Xdir-rotated and Ydir-rotated from UCS to WCS - (trans Xdir-rot 1 0)=Xdir-rot-trans; (trans Ydir-rot 1 0)=Ydir-rot-trans
- you provide to (setucs) function : (setucs (getvar 'ucsorg) Xdir-rot-trans Ydir-rot-trans) to perform UCS transformation...

HTH.
« Last Edit: July 06, 2016, 05:17:13 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

PKENEWELL

  • Bull Frog
  • Posts: 320
Re: Rotate the Current UCS using vla methods
« Reply #10 on: July 07, 2016, 11:21:31 AM »
For rotation around Z axis :

- you get Xdir and Ydir
- you translate Xdir from WCS to UCS - (trans Xdir 0 1) - this should always be '(1.0 0.0 0.0)
- you get initial angle of Xdir using (angle '(0.0 0.0) Xdir) = sang - this should always be 0.0
- you add initial angle with argument angle (+ sang ang) = eang
- you get Xdir-rotated using (polar) - (polar '(0.0 0.0) eang 1.0) - ort vector of Xdir-rotated
- you calculate Ydir-rotated - (polar '(0.0 0.0) (+ eang (* 0.5 pi)) 1.0) - also ort vector of Ydir-rotated
- you translate Xdir-rotated and Ydir-rotated from UCS to WCS - (trans Xdir-rot 1 0)=Xdir-rot-trans; (trans Ydir-rot 1 0)=Ydir-rot-trans
- you provide to (setucs) function : (setucs (getvar 'ucsorg) Xdir-rot-trans Ydir-rot-trans) to perform UCS transformation...

HTH.

Hi Marko,

Thanks for your instructions. Your method for X and Y axis rotation work with no problems. However, the Z axis method returns an error "non-perpendicular UCS X and Y axes; Normalizing". I have attempted both setting a new UCS and altering the existing UCS via (vla-put-xvector) and (vla-put-yvector) and the results are the same. I don't see why this would happen considering I am not rounding any values and using straight radians for the angle.
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

PKENEWELL

  • Bull Frog
  • Posts: 320
Re: Rotate the Current UCS using vla methods
« Reply #11 on: July 07, 2016, 12:33:51 PM »
OK - so I was able to get the "Z" rotate working. I think I understand what I was doing wrong. Seems that if you are using (vla-add... for a new ucs - I was not using UCS origin properly (forgetting that it is relative to the WCS and just using 0,0,0), and when altering an existing UCS using (vla-put-xvector / yvector). you don't need to translate the vectors back to the WCS since they are relative to the current origin.

Thanks for your help Marko!
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt