### Author Topic: Rotate block back to 'no rotation'  (Read 2779 times)

0 Members and 1 Guest are viewing this topic.

#### Woabow

• Newt
• Posts: 56
##### Rotate block back to 'no rotation'
« 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?

#### Lee Mac

• Seagull
• Posts: 12390
• London, England
##### Re: Rotate block back to 'no rotation'
« Reply #1 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.             (setq enx (entget ent)
8.                   ang (cdr (assoc 50  enx))
9.                   nrm (cdr (assoc 210 enx))
10.                   ins (trans (cdr (assoc 10 enx)) nrm 0)
11.             )
12.             (vla-transformby (vlax-ename->vla-object ent)
13.                         (mapcar '(lambda ( r v ) (append r (list v)))
14.                             (setq mat
15.                                 (mxm
16.                                     (list
17.                                         (list (cos ang)     (sin ang) 0.0)
18.                                         (list (- (sin ang)) (cos ang) 0.0)
19.                                        '(0.0 0.0 1.0)
20.                                     )
21.                                     (mapcar '(lambda ( v ) (trans v nrm 0 t))
22.                                         '(
23.                                              (1.0 0.0 0.0)
24.                                              (0.0 1.0 0.0)
25.                                              (0.0 0.0 1.0)
26.                                          )
27.                                     )
28.                                 )
29.                             )
30.                             (mapcar '- ins (mxv mat ins))
31.                         )
32.                        '((0.0 0.0 0.0 1.0))
33.                     )
34.                 )
35.             )
36.         )
37.     )
38.     (princ)
39. )
40.
41. ;; Matrix Transpose  -  Doug Wilson
42. ;; Args: m - nxn matrix
43.
44. (defun trp ( m )
45.     (apply 'mapcar (cons 'list m))
46. )
47.
48. ;; Matrix x Matrix  -  Vladimir Nesterovsky
49. ;; Args: m,n - nxn matrices
50.
51. (defun mxm ( m n )
52.     ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n))
53. )
54.
55. ;; Matrix x Vector  -  Vladimir Nesterovsky
56. ;; Args: m - nxn matrix, v - vector in R^n
57.
58. (defun mxv ( m v )
59.     (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
60. )
61.

#### dgorsman

• Water Moccasin
• Posts: 2423
##### Re: Rotate block back to 'no rotation'
« Reply #2 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.
If you are going to fly by the seat of your pants, expect friction burns.

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

#### Woabow

• Newt
• Posts: 56
##### Re: Rotate block back to 'no rotation'
« Reply #3 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?

#### dgorsman

• Water Moccasin
• Posts: 2423
##### Re: Rotate block back to 'no rotation'
« Reply #4 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.
If you are going to fly by the seat of your pants, expect friction burns.

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

#### Lee Mac

• Seagull
• Posts: 12390
• London, England
##### Re: Rotate block back to 'no rotation'
« Reply #5 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.             (setq enx (entget ent)
11.                   ang (- rot (cdr (assoc 50 enx)))
12.                   nrm (cdr (assoc 210 enx))
13.                   ins (trans (cdr (assoc 10 enx)) nrm 0)
14.             )
15.             (vla-transformby (vlax-ename->vla-object ent)
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.

#### Woabow

• Newt
• Posts: 56
##### Re: Rotate block back to 'no rotation'
« Reply #6 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?

#### ribarm

• Water Moccasin
• Posts: 2369
• Marko Ribar, architect
##### Re: Rotate block back to 'no rotation'
« Reply #7 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.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(1.0 0.0 0.0)) "_non" (mapcar '+ o ux))
16.         (setq rx (angle '(0.0 0.0 0.0) (trans (mapcar '+ o ux) 0 1)))
17.         (vl-cmdf "_.ucs" "p")
18.       )
19.       (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)))
20.     )
21.     (if (not (or (equal uy '(0.0 1.0 0.0) 1e-8) (equal uy '(0.0 -1.0 0.0) 1e-8)))
22.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(0.0 1.0 0.0)) "_non" (mapcar '+ o uy))
23.         (setq ry (angle '(0.0 0.0 0.0) (trans (mapcar '+ o uy) 0 1)))
24.         (vl-cmdf "_.ucs" "p")
25.       )
26.       (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)))
27.     )
28.     (if (not (or (equal uz '(0.0 0.0 1.0) 1e-8) (equal uz '(0.0 0.0 -1.0) 1e-8)))
29.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(0.0 0.0 1.0)) "_non" (mapcar '+ o uz))
30.         (setq rz (angle '(0.0 0.0 0.0) (trans (mapcar '+ o uz) 0 1)))
31.         (vl-cmdf "_.ucs" "p")
32.       )
33.       (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)))
34.     )
35.     (vl-cmdf "_.ucs" "p")
36.     (prompt "\nCurrent angle of picked INSERT entity along X axis is : ") (princ (angtos rx 0 8)) (prompt " degree")
37.     (prompt "\nCurrent angle of picked INSERT entity along Y axis is : ") (princ (angtos ry 0 8)) (prompt " degree")
38.     (prompt "\nCurrent angle of picked INSERT entity along Z axis is : ") (princ (angtos rz 0 8)) (prompt " degree")
39.     (vl-cmdf "_.ucs" "p")
40.     (princ)
41.   )
42.   (curang)
43.   (defun rotbyaxises ( / rxn ryn rzn )
44.     (vl-cmdf "_.ucs" "w")
45.     (if (not (or (equal ux '(1.0 0.0 0.0) 1e-8) (equal ux '(-1.0 0.0 0.0) 1e-8)))
46.         (initget 1)
47.         (setq rxn (getangle "\nEnter new angle (by) X axis : "))
48.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(1.0 0.0 0.0)) "_non" (mapcar '+ o ux))
49.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos (- rxn rx) 0 8))
50.         (vl-cmdf "_.ucs" "p")
51.       )
52.         (initget 1)
53.         (setq rxn (getangle "\nEnter new angle (around) X axis : "))
54.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(0.0 1.0 0.0)) "_non" (mapcar '+ o '(0.0 0.0 1.0)))
55.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos rxn 0 8))
56.         (vl-cmdf "_.ucs" "p")
57.       )
58.     )
59.     (vl-cmdf "_.ucs" "p")
60.     (curang)
61.     (vl-cmdf "_.ucs" "w")
62.     (if (not (or (equal uy '(0.0 1.0 0.0) 1e-8) (equal uy '(0.0 -1.0 0.0) 1e-8)))
63.         (initget 1)
64.         (setq ryn (getangle "\nEnter new angle (by) Y axis : "))
65.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(0.0 1.0 0.0)) "_non" (mapcar '+ o uy))
66.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos (- ryn ry) 0 8))
67.         (vl-cmdf "_.ucs" "p")
68.       )
69.         (initget 1)
70.         (setq ryn (getangle "\nEnter new angle (around) Y axis : "))
71.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(1.0 0.0 0.0)) "_non" (mapcar '+ o '(0.0 0.0 1.0)))
72.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos ryn 0 8))
73.         (vl-cmdf "_.ucs" "p")
74.       )
75.     )
76.     (vl-cmdf "_.ucs" "p")
77.     (curang)
78.     (vl-cmdf "_.ucs" "w")
79.     (if (not (or (equal uz '(0.0 0.0 1.0) 1e-8) (equal uz '(0.0 0.0 -1.0) 1e-8)))
80.         (initget 1)
81.         (setq rzn (getangle "\nEnter new angle (by) Z axis : "))
82.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(0.0 0.0 1.0)) "_non" (mapcar '+ o uz))
83.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos (- rzn rz) 0 8))
84.         (vl-cmdf "_.ucs" "p")
85.       )
86.         (initget 1)
87.         (setq rzn (getangle "\nEnter new angle (around) Z axis : "))
88.         (vl-cmdf "_.ucs" "3" "_non" o "_non" (mapcar '+ o '(1.0 0.0 0.0)) "_non" (mapcar '+ o '(0.0 1.0 0.0)))
89.         (vl-cmdf "_.rotate" ent "" "_non" "0,0,0" (angtos rzn 0 8))
90.         (vl-cmdf "_.ucs" "p")
91.       )
92.     )
93.     (vl-cmdf "_.ucs" "p")
94.     (curang)
95.   )
96.   (defun rotaraxises ( / rxn ryn rzn )
97.     (initget 1)
98.     (setq rxn (getangle "\nEnter new angle (around) X axis : "))
99.     (if (/= rxn 0.0)
100.         (vl-cmdf "_.ucs" "e" ent)
101.         (vl-cmdf "_.rotate3d" ent "" "x" "_non" "0,0,0" (angtos rxn 0 8))
102.         (vl-cmdf "_.ucs" "p")
103.         (curang)
104.       )
105.     )
106.     (initget 1)
107.     (setq ryn (getangle "\nEnter new angle (around) Y axis : "))
108.     (if (/= ryn 0.0)
109.         (vl-cmdf "_.ucs" "e" ent)
110.         (vl-cmdf "_.rotate3d" ent "" "y" "_non" "0,0,0" (angtos ryn 0 8))
111.         (vl-cmdf "_.ucs" "p")
112.         (curang)
113.       )
114.     )
115.     (initget 1)
116.     (setq rzn (getangle "\nEnter new angle (around) Z axis : "))
117.     (if (/= rzn 0.0)
118.         (vl-cmdf "_.ucs" "e" ent)
119.         (vl-cmdf "_.rotate3d" ent "" "z" "_non" "0,0,0" (angtos rzn 0 8))
120.         (vl-cmdf "_.ucs" "p")
121.         (curang)
122.       )
123.     )
124.   )
125.   (initget 1 "By Around")
126.   (setq ch (getkword "\nEnter choice rot(BY)axises / rot(AROUND)axises : "))
127.   (if (eq ch "By") (rotbyaxises) (rotaraxises))
128.   (setvar 'cmdecho cmde)
129.   (princ)
130. )
131. (defun c:sr nil (c:setrotbyaxises))
132. (prompt "\nShortcut for c:setrotbyaxises is c:sr\nto invoke start routine with <Command: sr>")
133.

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.
« Last Edit: September 28, 2012, 03:12:42 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

#### Lee Mac

• Seagull
• Posts: 12390
• London, England
##### Re: Rotate block back to 'no rotation'
« Reply #8 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.             (setq enx (entget ent)
15.                   ang (- (cdr (assoc 50 enx)))
16.                   nrm (cdr (assoc 210 enx))
17.                   ins (trans (cdr (assoc 10 enx)) nrm 0)
18.             )
19.             (vla-transformby (vlax-ename->vla-object ent)
20.                         (mapcar '(lambda ( r v ) (append r (list v)))
21.                             (setq mat
22.                                 (mxm
23.                                     (list
24.                                         (list (cos roz) (- (sin roz)) 0.0)
25.                                         (list (sin roz)    (cos roz)  0.0)
26.                                        '(0.0 0.0 1.0)
27.                                     )
28.                                     (mxm
29.                                         (list
30.                                             (list    (cos roy)  0.0 (sin roy))
31.                                            '(0.0 1.0 0.0)
32.                                             (list (- (sin roy)) 0.0 (cos roy))
33.                                         )
34.                                         (mxm
35.                                             (list
36.                                                '(1.0 0.0 0.0)
37.                                                 (list 0.0 (cos rox) (- (sin rox)))
38.                                                 (list 0.0 (sin rox)    (cos rox))
39.                                             )
40.                                             (mxm
41.                                                 (list
42.                                                     (list (cos ang) (- (sin ang)) 0.0)
43.                                                     (list (sin ang)    (cos ang)  0.0)
44.                                                    '(0.0 0.0 1.0)
45.                                                 )
46.                                                 (mapcar '(lambda ( v ) (trans v nrm 0 t))
47.                                                     '(
48.                                                          (1.0 0.0 0.0)
49.                                                          (0.0 1.0 0.0)
50.                                                          (0.0 0.0 1.0)
51.                                                      )
52.                                                 )
53.                                             )
54.                                         )
55.                                     )
56.                                 )
57.                             )
58.                             (mapcar '- ins (mxv mat ins))
59.                         )
60.                        '((0.0 0.0 0.0 1.0))
61.                     )
62.                 )
63.             )
64.         )
65.     )
66.     (princ)
67. )
68.
69. ;; Matrix Transpose  -  Doug Wilson
70. ;; Args: m - nxn matrix
71.
72. (defun trp ( m )
73.     (apply 'mapcar (cons 'list m))
74. )
75.
76. ;; Matrix x Matrix  -  Vladimir Nesterovsky
77. ;; Args: m,n - nxn matrices
78.
79. (defun mxm ( m n )
80.     ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n))
81. )
82.
83. ;; Matrix x Vector  -  Vladimir Nesterovsky
84. ;; Args: m - nxn matrix, v - vector in R^n
85.
86. (defun mxv ( m v )
87.     (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
88. )
89.
90.

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. ;;------------------------------------------------------------;;
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. ;;------------------------------------------------------------;;
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.                                 (lambda ( x v )
59.                                     (append x (list v))
60.                                 )
61.                             )
62.                             matrix vector
63.                         )
64.                        '((0.0 0.0 0.0 1.0))
65.                     )
66.                 )
67.             )
68.         )
69.         (   (listp target)
70.                     (lambda ( point )
71.                         (mapcar '+ (mxv matrix point) vector)
72.                     )
73.                 )
74.                 target
75.             )
76.         )
77.     )
78. )
79.
80. ;; Matrix x Vector - Vladimir Nesterovsky
81. ;; Args: m - nxn matrix, v - vector in R^n
82.
83. (defun mxv ( m v )
84.     (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
85. )
86.
87. ;; Matrix x Scalar - Lee Mac
88. ;; Args: m - nxn matrix, n - real scalar
89.
90. (defun mxs ( m s )
91.     (mapcar '(lambda ( r ) (mapcar '(lambda ( n ) (* n s)) r)) m)
92. )
93.
94. ;; Matrix + Matrix - Lee Mac
95. ;; Args: m,n - nxn matrices
96.
97. (defun m+m ( m n )
98.     (mapcar '(lambda ( r s ) (mapcar '+ r s)) m n)
99. )
100.
101. ;; Vector x Scalar - Lee Mac
102. ;; Args: v - vector in R^n, s - real scalar
103.
104. (defun vxs ( v s )
105.     (mapcar '(lambda ( n ) (* n s)) v)
106. )
107.
108. ;; Unit Vector  -  Lee Mac
109. ;; Args: v - vector in R^2 or R^3
110.
111. (defun v1 ( v )
112.     (   (lambda ( n ) (if (equal 0.0 n 1e-10) nil (mapcar '/ v (list n n n))))
113.         (distance '(0.0 0.0 0.0) v)
114.     )
115. )

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

#### ribarm

• Water Moccasin
• Posts: 2369
• Marko Ribar, architect
##### Re: Rotate block back to 'no rotation'
« Reply #9 on: September 28, 2012, 03:14:40 PM »
Marko Ribar, d.i.a. (graduated engineer of architecture)

#### Woabow

• Newt
• Posts: 56
##### Re: Rotate block back to 'no rotation'
« Reply #10 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...

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.