TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Woabow on September 26, 2012, 03:52:53 PM

Title: Rotate block back to 'no rotation'
Post by: Woabow on September 26, 2012, 03:52:53 PM
After rotating a block (3D) I figured out I can find the angles like this:
Code: [Select]

 (setq ent (car (entsel)))
 (setq vec (cdr (assoc 210 (entget ent))))
 (setq rx (atan (/(cadr vec) (caddr vec))))
 (setq ry (atan (/ (car vec) (caddr vec))))
 (setq rz  (cdr (assoc 50 (entget ent))))
 (print (strcat "Rotation X-Axis: " (angtos rx)))
 (print (strcat "Rotation Y-Axis: " (angtos ry)))
 (print (strcat "Rotation Z-Axis: " (angtos rz)))

But what if I want to rotate the block back to "normal", with no rotation, like it was when inserted. The z is easy by modifying the DXF code, but I have trouble to get the X and Y back to zero.

I moved the block for testing purposes to (0,0,0) and tried this (just X):
Code: [Select]
(setq p (list 0.0 0.0 0.0) )
(setq q (list (+ 1 (car p))  (cadr p) (caddr p))) ; p  q = x-axis
(setq ra  (+ rx  pi))
(command "_.rotate3d" ent "" "x" "_non" "0,0,0" (angtos ra))

And the same for the Y axis.

It seems to work, but can I modify the angles by directly set the vector to the 0,0,1 position?
Title: Re: Rotate block back to 'no rotation'
Post by: Lee Mac on September 26, 2012, 04:54:40 PM
It may be cleaner to use a transformation matrix to reverse the rotation and orientation changes, for example:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:revertblock ( / ang ent enx ins mat nrm )
  2.     (if
  3.         (and
  4.             (setq ent (car (entsel "\nSelect Block: ")))
  5.             (= "INSERT" (cdr (assoc 0 (entget ent))))
  6.         )
  7.         (progn
  8.             (setq enx (entget ent)
  9.                   ang (cdr (assoc 50  enx))
  10.                   nrm (cdr (assoc 210 enx))
  11.                   ins (trans (cdr (assoc 10 enx)) nrm 0)
  12.             )
  13.             (vla-transformby (vlax-ename->vla-object ent)
  14.                 (vlax-tmatrix
  15.                     (append
  16.                         (mapcar '(lambda ( r v ) (append r (list v)))
  17.                             (setq mat
  18.                                 (mxm
  19.                                     (list
  20.                                         (list (cos ang)     (sin ang) 0.0)
  21.                                         (list (- (sin ang)) (cos ang) 0.0)
  22.                                        '(0.0 0.0 1.0)
  23.                                     )
  24.                                     (mapcar '(lambda ( v ) (trans v nrm 0 t))
  25.                                         '(
  26.                                              (1.0 0.0 0.0)
  27.                                              (0.0 1.0 0.0)
  28.                                              (0.0 0.0 1.0)
  29.                                          )
  30.                                     )
  31.                                 )
  32.                             )
  33.                             (mapcar '- ins (mxv mat ins))
  34.                         )
  35.                        '((0.0 0.0 0.0 1.0))
  36.                     )
  37.                 )
  38.             )
  39.         )
  40.     )
  41.     (princ)                        
  42. )
  43.  
  44. ;; Matrix Transpose  -  Doug Wilson
  45. ;; Args: m - nxn matrix
  46.  
  47. (defun trp ( m )
  48.     (apply 'mapcar (cons 'list m))
  49. )
  50.  
  51. ;; Matrix x Matrix  -  Vladimir Nesterovsky
  52. ;; Args: m,n - nxn matrices
  53.  
  54. (defun mxm ( m n )
  55.     ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n))
  56. )
  57.  
  58. ;; Matrix x Vector  -  Vladimir Nesterovsky
  59. ;; Args: m - nxn matrix, v - vector in R^n
  60.  
  61. (defun mxv ( m v )
  62.     (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
  63. )
  64.  

Title: Re: Rotate block back to 'no rotation'
Post by: dgorsman on September 27, 2012, 10:17:39 AM
Also, take a look into XDATA.  There are a couple of types there that are specifically related to transforms; attached to the original object, they automatically apply translational, rotation, and scaling transformations applied to that object, which you can use to derive the matrix to transform the object back.
Title: Re: Rotate block back to 'no rotation'
Post by: Woabow on September 27, 2012, 12:55:40 PM
Didn't know XDATA contains translation info, I thought it was only used for user data. Thanks, I''ll look into it.

Quote
It may be cleaner to use a transformation matrix to reverse the rotation and orientation changes, for example:

Perfect! But, allow me to ask, what if I want to set other angles than zero? Where to put them?
Title: Re: Rotate block back to 'no rotation'
Post by: dgorsman on September 27, 2012, 01:48:32 PM
Check out DXF groups 1010 through 1033, and the DXF help under "Advanced DXF Issues -> Extended data".  Theres a table at the bottom of the page indicating which codes do what; towards the bottom are listed several values for World Space Position, World Space Displacement, and World direction, along with which operations (move, stretch, scale, rotate, etc.) are applied to each.
Title: Re: Rotate block back to 'no rotation'
Post by: Lee Mac on September 27, 2012, 02:42:50 PM
Quote
It may be cleaner to use a transformation matrix to reverse the rotation and orientation changes, for example:

Perfect! But, allow me to ask, what if I want to set other angles than zero? Where to put them?

You can offset the rotation from the block's rotation in the plane, for example, the following code will set the resultant block rotation to pi/3 radians (60 degs) in the WCS plane (z=0,0,1):

Code - Auto/Visual Lisp: [Select]
  1. (defun c:revertblock ( / ang ent enx ins mat nrm rot )
  2.  
  3.     (setq rot (/ pi 3.0)) ;; New Rotation
  4.    
  5.     (if
  6.         (and
  7.             (setq ent (car (entsel "\nSelect Block: ")))
  8.             (= "INSERT" (cdr (assoc 0 (entget ent))))
  9.         )
  10.         (progn
  11.             (setq enx (entget ent)
  12.                   ang (- rot (cdr (assoc 50 enx)))
  13.                   nrm (cdr (assoc 210 enx))
  14.                   ins (trans (cdr (assoc 10 enx)) nrm 0)
  15.             )
  16.             (vla-transformby (vlax-ename->vla-object ent)
  17.                 (vlax-tmatrix
  18.                     (append
  19.                         (mapcar '(lambda ( r v ) (append r (list v)))
  20.                             (setq mat
  21.                                 (mxm
  22.                                     (list
  23.                                         (list (cos ang) (- (sin ang)) 0.0)
  24.                                         (list (sin ang)    (cos ang)  0.0)
  25.                                        '(0.0 0.0 1.0)
  26.                                     )
  27.                                     (mapcar '(lambda ( v ) (trans v nrm 0 t))
  28.                                         '(
  29.                                              (1.0 0.0 0.0)
  30.                                              (0.0 1.0 0.0)
  31.                                              (0.0 0.0 1.0)
  32.                                          )
  33.                                     )
  34.                                 )
  35.                             )
  36.                             (mapcar '- ins (mxv mat ins))
  37.                         )
  38.                        '((0.0 0.0 0.0 1.0))
  39.                     )
  40.                 )
  41.             )
  42.         )
  43.     )
  44.     (princ)                        
  45. )
  46.  
  47. ;; Matrix Transpose  -  Doug Wilson
  48. ;; Args: m - nxn matrix
  49.  
  50. (defun trp ( m )
  51.     (apply 'mapcar (cons 'list m))
  52. )
  53.  
  54. ;; Matrix x Matrix  -  Vladimir Nesterovsky
  55. ;; Args: m,n - nxn matrices
  56.  
  57. (defun mxm ( m n )
  58.     ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n))
  59. )
  60.  
  61. ;; Matrix x Vector  -  Vladimir Nesterovsky
  62. ;; Args: m - nxn matrix, v - vector in R^n
  63.  
  64. (defun mxv ( m v )
  65.     (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
  66. )
  67.  

Title: Re: Rotate block back to 'no rotation'
Post by: Woabow on September 27, 2012, 04:05:33 PM
Right now I can't test the code, but this will result in a 2D rotation (around z-axis) right? This is the easy one  :-)

What if I want to have the block rotated about x-axis (or y)? With the code of my OP I can show the user the actual rotation around X, Y and Z. It would be perfect when I can rotate the block around a given axis in a given angle.

Do I have to mod the   
 (1.0 0.0 0.0)
 (0.0 1.0 0.0)
 (0.0 0.0 1.0)
code?

Title: Re: Rotate block back to 'no rotation'
Post by: ribarm on September 27, 2012, 07:14:24 PM
After rotating a block (3D) I figured out I can find the angles like this:
Code: [Select]

 (setq ent (car (entsel)))
 (setq vec (cdr (assoc 210 (entget ent))))
 (setq rx (atan (/(cadr vec) (caddr vec))))
 (setq ry (atan (/ (car vec) (caddr vec))))
 (setq rz  (cdr (assoc 50 (entget ent))))
 (print (strcat "Rotation X-Axis: " (angtos rx)))
 (print (strcat "Rotation Y-Axis: " (angtos ry)))
 (print (strcat "Rotation Z-Axis: " (angtos rz)))

Variables rx, ry and rz are wrong... You can check them with this code :
Code - Auto/Visual Lisp: [Select]
  1. (defun c:setrotbyaxises ( / ch cmde ux uy uz o rx ry rz rxn ryn rzn ent )
  2.   (while (or (null ent) (not (eq (cdr (assoc 0 (vl-catch-all-apply 'entget (list ent)))) "INSERT")))
  3.     (setq ent (car (entsel "\nPick INSERT entity to set angles of ratation by axises")))
  4.   )
  5.   (setq cmde (getvar 'cmdecho))
  6.   (setvar 'cmdecho 0)
  7.   (defun curang nil
  8.     (vl-cmdf "_.ucs" "e" ent)
  9.     (setq ux (getvar 'ucsxdir))
  10.     (setq uy (getvar 'ucsydir))
  11.     (setq uz (cdr (assoc 210 (entget ent))))
  12.     (setq o (trans (cdr (assoc 10 (entget ent))) ent 0))
  13.     (vl-cmdf "_.ucs" "w")
  14.     (if (not (or (equal ux '(1.0 0.0 0.0) 1e-8) (equal ux '(-1.0 0.0 0.0) 1e-8)))
  15.       (progn
  16.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(1.0 0.0 0.0)) "_non" (mapcar '+ o ux))
  17.         (setq rx (angle '(0.0 0.0 0.0) (trans (mapcar '+ o ux) 0 1)))
  18.         (vl-cmdf "_.ucs" "p")
  19.       )
  20.       (cond ((equal ux '(1.0 0.0 0.0) 1e-8) (setq rx 0.0)) ((equal ux '(-1.0 0.0 0.0) 1e-8) (setq rx pi)))
  21.     )
  22.     (if (not (or (equal uy '(0.0 1.0 0.0) 1e-8) (equal uy '(0.0 -1.0 0.0) 1e-8)))
  23.       (progn
  24.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(0.0 1.0 0.0)) "_non" (mapcar '+ o uy))
  25.         (setq ry (angle '(0.0 0.0 0.0) (trans (mapcar '+ o uy) 0 1)))
  26.         (vl-cmdf "_.ucs" "p")
  27.       )
  28.       (cond ((equal uy '(0.0 1.0 0.0) 1e-8) (setq ry 0.0)) ((equal uy '(0.0 -1.0 0.0) 1e-8) (setq ry pi)))
  29.     )
  30.     (if (not (or (equal uz '(0.0 0.0 1.0) 1e-8) (equal uz '(0.0 0.0 -1.0) 1e-8)))
  31.       (progn
  32.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(0.0 0.0 1.0)) "_non" (mapcar '+ o uz))
  33.         (setq rz (angle '(0.0 0.0 0.0) (trans (mapcar '+ o uz) 0 1)))
  34.         (vl-cmdf "_.ucs" "p")
  35.       )
  36.       (cond ((equal uz '(0.0 0.0 1.0) 1e-8) (setq rz 0.0)) ((equal uz '(0.0 0.0 -1.0) 1e-8) (setq rz pi)))
  37.     )
  38.     (vl-cmdf "_.ucs" "p")
  39.     (prompt "\nCurrent angle of picked INSERT entity along X axis is : ") (princ (angtos rx 0 8)) (prompt " degree")
  40.     (prompt "\nCurrent angle of picked INSERT entity along Y axis is : ") (princ (angtos ry 0 8)) (prompt " degree")
  41.     (prompt "\nCurrent angle of picked INSERT entity along Z axis is : ") (princ (angtos rz 0 8)) (prompt " degree")
  42.     (vl-cmdf "_.ucs" "p")
  43.     (princ)
  44.   )
  45.   (curang)
  46.   (defun rotbyaxises ( / rxn ryn rzn )
  47.     (vl-cmdf "_.ucs" "w")
  48.     (if (not (or (equal ux '(1.0 0.0 0.0) 1e-8) (equal ux '(-1.0 0.0 0.0) 1e-8)))
  49.       (progn
  50.         (initget 1)
  51.         (setq rxn (getangle "\nEnter new angle (by) X axis : "))
  52.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(1.0 0.0 0.0)) "_non" (mapcar '+ o ux))
  53.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos (- rxn rx) 0 8))
  54.         (vl-cmdf "_.ucs" "p")
  55.       )
  56.       (progn
  57.         (initget 1)
  58.         (setq rxn (getangle "\nEnter new angle (around) X axis : "))
  59.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(0.0 1.0 0.0)) "_non" (mapcar '+ o '(0.0 0.0 1.0)))
  60.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos rxn 0 8))
  61.         (vl-cmdf "_.ucs" "p")
  62.       )
  63.     )
  64.     (vl-cmdf "_.ucs" "p")
  65.     (curang)
  66.     (vl-cmdf "_.ucs" "w")
  67.     (if (not (or (equal uy '(0.0 1.0 0.0) 1e-8) (equal uy '(0.0 -1.0 0.0) 1e-8)))
  68.       (progn
  69.         (initget 1)
  70.         (setq ryn (getangle "\nEnter new angle (by) Y axis : "))
  71.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(0.0 1.0 0.0)) "_non" (mapcar '+ o uy))
  72.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos (- ryn ry) 0 8))
  73.         (vl-cmdf "_.ucs" "p")
  74.       )
  75.       (progn
  76.         (initget 1)
  77.         (setq ryn (getangle "\nEnter new angle (around) Y axis : "))
  78.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(1.0 0.0 0.0)) "_non" (mapcar '+ o '(0.0 0.0 1.0)))
  79.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos ryn 0 8))
  80.         (vl-cmdf "_.ucs" "p")
  81.       )
  82.     )
  83.     (vl-cmdf "_.ucs" "p")
  84.     (curang)
  85.     (vl-cmdf "_.ucs" "w")
  86.     (if (not (or (equal uz '(0.0 0.0 1.0) 1e-8) (equal uz '(0.0 0.0 -1.0) 1e-8)))
  87.       (progn
  88.         (initget 1)
  89.         (setq rzn (getangle "\nEnter new angle (by) Z axis : "))
  90.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(0.0 0.0 1.0)) "_non" (mapcar '+ o uz))
  91.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos (- rzn rz) 0 8))
  92.         (vl-cmdf "_.ucs" "p")
  93.       )
  94.       (progn
  95.         (initget 1)
  96.         (setq rzn (getangle "\nEnter new angle (around) Z axis : "))
  97.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(1.0 0.0 0.0)) "_non" (mapcar '+ o '(0.0 1.0 0.0)))
  98.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos rzn 0 8))
  99.         (vl-cmdf "_.ucs" "p")
  100.       )
  101.     )
  102.     (vl-cmdf "_.ucs" "p")
  103.     (curang)
  104.   )
  105.   (defun rotaraxises ( / rxn ryn rzn )
  106.     (initget 1)
  107.     (setq rxn (getangle "\nEnter new angle (around) X axis : "))
  108.     (if (/= rxn 0.0)
  109.       (progn
  110.         (vl-cmdf "_.ucs" "e" ent)
  111.         (vl-cmdf "_.rotate3d" ent "" "x" "_non" "0,0,0" (angtos rxn 0 8))
  112.         (vl-cmdf "_.ucs" "p")
  113.         (curang)
  114.       )
  115.     )
  116.     (initget 1)
  117.     (setq ryn (getangle "\nEnter new angle (around) Y axis : "))
  118.     (if (/= ryn 0.0)
  119.       (progn
  120.         (vl-cmdf "_.ucs" "e" ent)
  121.         (vl-cmdf "_.rotate3d" ent "" "y" "_non" "0,0,0" (angtos ryn 0 8))
  122.         (vl-cmdf "_.ucs" "p")
  123.         (curang)
  124.       )
  125.     )
  126.     (initget 1)
  127.     (setq rzn (getangle "\nEnter new angle (around) Z axis : "))
  128.     (if (/= rzn 0.0)
  129.       (progn
  130.         (vl-cmdf "_.ucs" "e" ent)
  131.         (vl-cmdf "_.rotate3d" ent "" "z" "_non" "0,0,0" (angtos rzn 0 8))
  132.         (vl-cmdf "_.ucs" "p")
  133.         (curang)
  134.       )
  135.     )
  136.   )
  137.   (initget 1 "By Around")
  138.   (setq ch (getkword "\nEnter choice rot(BY)axises / rot(AROUND)axises : "))
  139.   (if (eq ch "By") (rotbyaxises) (rotaraxises))
  140.   (setvar 'cmdecho cmde)
  141.   (princ)
  142. )
  143. (defun c:sr nil (c:setrotbyaxises))
  144. (prompt "\nShortcut for c:setrotbyaxises is c:sr\nto invoke start routine with <Command: sr>")
  145.  

Note that to set INSERT entity to angles X : 0, Y : 0, Z : 0, you'll probably need to start code twice and set always values it asks to 0.0 and choose choice "B" rot(By)axises... When you set angle by one axis by some value, you'll probably modify another axises angles - test it and see for yourself...

M.R.
Title: Re: Rotate block back to 'no rotation'
Post by: Lee Mac on September 27, 2012, 08:17:00 PM
this will result in a 2D rotation (around z-axis) right?

Correct.  :-)

What if I want to have the block rotated about x-axis (or y)? With the code of my OP I can show the user the actual rotation around X, Y and Z. It would be perfect when I can rotate the block around a given axis in a given angle.

If you were looking to separately specify the rotation about each orthogonal axis, you could multiply the separate rotation transformation matrices for a rotation in each plane by the matrix constructed to revert the block to WCS orientation at zero rotation.

For example, the following code will construct a transformation matrix to first revert the selected block to WCS orientation (z=0,0,1) at zero rotation, and then rotate the block in each of the x, y & z axes, by angles pi/3 rads (60 degs), pi/6 rads (30 degs) & pi/4 rads (45 degs) respectively.

Code - Auto/Visual Lisp: [Select]
  1. ;; Revert Block  -  Lee Mac
  2. (defun c:revertblock ( / ang ent enx ins mat nrm rox roy roz )
  3.  
  4.     (setq rox (/ pi 3.0) ;; Rotation about x-axis
  5.           roy (/ pi 6.0) ;; Rotation about y-axis
  6.           roz (/ pi 4.0) ;; Rotation about z-axis
  7.     )
  8.  
  9.     (if
  10.         (and
  11.             (setq ent (car (entsel "\nSelect Block: ")))
  12.             (= "INSERT" (cdr (assoc 0 (entget ent))))
  13.         )
  14.         (progn
  15.             (setq enx (entget ent)
  16.                   ang (- (cdr (assoc 50 enx)))
  17.                   nrm (cdr (assoc 210 enx))
  18.                   ins (trans (cdr (assoc 10 enx)) nrm 0)
  19.             )
  20.             (vla-transformby (vlax-ename->vla-object ent)
  21.                 (vlax-tmatrix
  22.                     (append
  23.                         (mapcar '(lambda ( r v ) (append r (list v)))
  24.                             (setq mat
  25.                                 (mxm
  26.                                     (list
  27.                                         (list (cos roz) (- (sin roz)) 0.0)
  28.                                         (list (sin roz)    (cos roz)  0.0)
  29.                                        '(0.0 0.0 1.0)
  30.                                     )
  31.                                     (mxm
  32.                                         (list
  33.                                             (list    (cos roy)  0.0 (sin roy))
  34.                                            '(0.0 1.0 0.0)
  35.                                             (list (- (sin roy)) 0.0 (cos roy))
  36.                                         )
  37.                                         (mxm
  38.                                             (list
  39.                                                '(1.0 0.0 0.0)
  40.                                                 (list 0.0 (cos rox) (- (sin rox)))
  41.                                                 (list 0.0 (sin rox)    (cos rox))
  42.                                             )
  43.                                             (mxm
  44.                                                 (list
  45.                                                     (list (cos ang) (- (sin ang)) 0.0)
  46.                                                     (list (sin ang)    (cos ang)  0.0)
  47.                                                    '(0.0 0.0 1.0)
  48.                                                 )
  49.                                                 (mapcar '(lambda ( v ) (trans v nrm 0 t))
  50.                                                     '(
  51.                                                          (1.0 0.0 0.0)
  52.                                                          (0.0 1.0 0.0)
  53.                                                          (0.0 0.0 1.0)
  54.                                                      )
  55.                                                 )
  56.                                             )
  57.                                         )
  58.                                     )
  59.                                 )
  60.                             )
  61.                             (mapcar '- ins (mxv mat ins))
  62.                         )
  63.                        '((0.0 0.0 0.0 1.0))
  64.                     )
  65.                 )
  66.             )
  67.         )
  68.     )
  69.     (princ)
  70. )
  71.  
  72. ;; Matrix Transpose  -  Doug Wilson
  73. ;; Args: m - nxn matrix
  74.  
  75. (defun trp ( m )
  76.     (apply 'mapcar (cons 'list m))
  77. )
  78.  
  79. ;; Matrix x Matrix  -  Vladimir Nesterovsky
  80. ;; Args: m,n - nxn matrices
  81.  
  82. (defun mxm ( m n )
  83.     ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n))
  84. )
  85.  
  86. ;; Matrix x Vector  -  Vladimir Nesterovsky
  87. ;; Args: m - nxn matrix, v - vector in R^n
  88.  
  89. (defun mxv ( m v )
  90.     (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
  91. )
  92.  
  93.  

However, if you instead wanted to perform a rotation about an arbitrary axis, you could multiply the transformation matrix by the matrix utilised by the following function:

Code - Auto/Visual Lisp: [Select]
  1. ;;----------------=={ 3D Rotate by Matrix }==-----------------;;
  2. ;;                                                            ;;
  3. ;;  Rotates a VLA-Object or Point List about a 3D axis using  ;;
  4. ;;  a Transformation matrix.                                  ;;
  5. ;;------------------------------------------------------------;;
  6. ;;  Author: Lee Mac, Copyright © 2012 - www.lee-mac.com       ;;
  7. ;;------------------------------------------------------------;;
  8. ;;  Arguments:                                                ;;
  9. ;;  target - VLA-Object or Point List to Rotate               ;;
  10. ;;  p1,p2  - Two 3D points defining the axis of rotation      ;;
  11. ;;  ang    - Rotation Angle                                   ;;
  12. ;;------------------------------------------------------------;;
  13.  
  14. (defun LM:Rotate3D ( target p1 p2 ang / m u ux uy uz )
  15.     (mapcar 'set '(ux uy uz) (setq u (v1 (mapcar '- p2 p1))))
  16.     (LM:ApplyMatrixTransformation target
  17.         (setq m
  18.             (m+m
  19.                 (list
  20.                     (list (cos ang) 0.0 0.0)
  21.                     (list 0.0 (cos ang) 0.0)
  22.                     (list 0.0 0.0 (cos ang))
  23.                 )
  24.                 (m+m
  25.                     (mxs
  26.                         (list
  27.                             (list 0.0 (- uz) uy)
  28.                             (list uz 0.0 (- ux))
  29.                             (list (- uy) ux 0.0)
  30.                         )
  31.                         (sin ang)
  32.                     )
  33.                     (mxs (mapcar '(lambda ( e ) (vxs u e)) u) (- 1.0 (cos ang)))
  34.                 )
  35.             )
  36.         )      
  37.         (mapcar '- p1 (mxv m p1))
  38.     )
  39. )
  40.  
  41. ;;-----------=={ Apply Matrix Transformation }==--------------;;
  42. ;;                                                            ;;
  43. ;;  Transforms a VLA-Object or Point List using a             ;;
  44. ;;  Transformation Matrix                                     ;;
  45. ;;------------------------------------------------------------;;
  46. ;;  Author: Lee Mac, Copyright © 2010 - www.lee-mac.com       ;;
  47. ;;------------------------------------------------------------;;
  48. ;;  Arguments:                                                ;;
  49. ;;  target - VLA-Object or Point List to Transform            ;;
  50. ;;  matrix - 3x3 Matrix by which to Transform object          ;;
  51. ;;  vector - 3D translation vector                            ;;
  52. ;;------------------------------------------------------------;;
  53.  
  54. (defun LM:ApplyMatrixTransformation ( target matrix vector )
  55.     (cond
  56.         (   (= 'vla-object (type target))
  57.             (vla-transformby target
  58.                 (vlax-tmatrix
  59.                     (append
  60.                         (mapcar
  61.                             (function
  62.                                 (lambda ( x v )
  63.                                     (append x (list v))
  64.                                 )
  65.                             )
  66.                             matrix vector
  67.                         )
  68.                        '((0.0 0.0 0.0 1.0))
  69.                     )
  70.                 )
  71.             )
  72.         )
  73.         (   (listp target)
  74.             (mapcar
  75.                 (function
  76.                     (lambda ( point )
  77.                         (mapcar '+ (mxv matrix point) vector)
  78.                     )
  79.                 )
  80.                 target
  81.             )
  82.         )
  83.     )
  84. )
  85.  
  86. ;; Matrix x Vector - Vladimir Nesterovsky
  87. ;; Args: m - nxn matrix, v - vector in R^n
  88.  
  89. (defun mxv ( m v )
  90.     (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
  91. )
  92.  
  93. ;; Matrix x Scalar - Lee Mac
  94. ;; Args: m - nxn matrix, n - real scalar
  95.  
  96. (defun mxs ( m s )
  97.     (mapcar '(lambda ( r ) (mapcar '(lambda ( n ) (* n s)) r)) m)
  98. )
  99.  
  100. ;; Matrix + Matrix - Lee Mac
  101. ;; Args: m,n - nxn matrices
  102.  
  103. (defun m+m ( m n )
  104.     (mapcar '(lambda ( r s ) (mapcar '+ r s)) m n)
  105. )
  106.  
  107. ;; Vector x Scalar - Lee Mac
  108. ;; Args: v - vector in R^n, s - real scalar
  109.  
  110. (defun vxs ( v s )
  111.     (mapcar '(lambda ( n ) (* n s)) v)
  112. )
  113.  
  114. ;; Unit Vector  -  Lee Mac
  115. ;; Args: v - vector in R^2 or R^3
  116.  
  117. (defun v1 ( v )
  118.     (   (lambda ( n ) (if (equal 0.0 n 1e-10) nil (mapcar '/ v (list n n n))))
  119.         (distance '(0.0 0.0 0.0) v)
  120.     )
  121. )

Of course, if, after reverting the block to WCS orientation and zero rotation, you had an aversion to using transformation matrices, there is also the vla-rotate3d method applicable to all drawing objects.

Lee
Title: Re: Rotate block back to 'no rotation'
Post by: ribarm on September 28, 2012, 03:14:40 PM
code updated...

http://www.theswamp.org/index.php?topic=42869.msg480969#msg480969

Regards, M.R.
 :-)
Title: Re: Rotate block back to 'no rotation'
Post by: Woabow on September 30, 2012, 04:27:39 AM
Quote
Of course, if, after reverting the block to WCS orientation and zero rotation, you had an aversion to using transformation matrices, there is also the vla-rotate3d method applicable to all drawing objects.

No aversion, but vla-rotate3d is easier to apply with an average brain...  :oops:

Quote
code updated...

Thanks Marko, nice code. Also the way you use the "equal" with a margin is an eye opener for me. I remember having unpredictable results with angles like 0, 30 and 45.
Code: [Select]
(= 1.0 (tan (/ pi 4)))   
now I know why.