# 4x4 transformation matrix

## Recommended Posts

Greetings.

The region is drawn in ModelSpace as a rectangle with sides 500 and 300.

```(command "_.rectangle" '(100.0 100.0 0.0) '(600.0 400.0 0.0))
(setq entity (entlast))
(command "_.region" entity "")
(setq entity (entlast))```

Its position in the WCS will be expressed by two points and a normal vector.
The second point is relative to the first.

```(regapp "PositionWCS")

;; some manipulation

;; initial data assigned to region
(-3 ("PositionWCS" (1011 100.0 100.0 0.0) (1012 500.0 0.0 0.0) (1013 0 0 1)))```

Now I move and rotate the region with the commands move and rotate.
The region takes a new position in the WCS. Its values in Xdata have changed.

```For example:
(-3 ("PositionWCS" (1011 1100.0 1100.0 500.0) (1012 500.0 0.0 0.0) (1013 0 -1 0)))
or:
(-3 ("PositionWCS" (1011 -400.0 100.0 -600.0) (1012 0.0 -500.0 0.0) (1013 1 0 0)))```

I would like to create a function that creates a transformation matrix for a region from the original position to the new one.

```Command:
_\$ (CreateMatrix4x4
'(100.0 100.0 0.0) '(500.0 0.0 0.0) '(0 0 1)
'(-400.0 100.0 -600.0) '(0.0 -500.0 0.0) '(1 0 0) )

The result:
((n1 n2 n3 n4) (n5 n6 n7 n8) (n9 n10 n11 n12) (n13 n14 n15 n16))```

To be able to apply the method:

```(setq obj (vlax-ename->vla-object entity))
(vla-TransformBy obj matrix)```

Help me with a solution so I don’t have to sit on this problem for unknown amount of time?

##### Share on other sites

I may be totally misunderstanding the question, but it sounds like what they do in Blender with matrix algebra. To apply successive transformations, they simply multiply (dot product) each one by the next. The only caveat is to apply them in the correct order.

If that doesn't help, please elaborate.

##### Share on other sites

Essentially you need to obtain three orthogonal vectors representing the transformation from the first set of points to the second set of points - such vectors will then form the columns of the 3x3 upper-left component of your transformation matrix. You would then apply such matrix to your original point and calculate the difference from the target point - such difference is the translation vector of your 4x4 matrix. Google 'change of basis matrix' for more information on this subject.

##### Share on other sites

Still not working as it should, problem with the axes.

```(defun CreateMatrix4x4 (wcp wsd normal wcpNew wsdNew normalNew /
dot-product cross-product normalize matrix-multiply Acos
translation-vector theta axis x y z cosT sinT R TT M)

;; Scalar product.
(defun dot-product (u v)
(apply '+ (mapcar '* u v)))

;; Vector product.
(defun cross-product (v1 v2)

;; To normalize a vector.
(defun normalize (v)
(setq len (sqrt (dot-product v v)))
(mapcar '(lambda (x) (/ x len)) v))

(defun matrix-multiply (a b)
(mapcar
'(lambda (row)
(mapcar
'(lambda (col)
(apply '+ (mapcar '* row col)))
(apply 'mapcar (cons 'list b)))) a))

;; Arccosine of the number.
(defun Acos (x)
(if (<= -1. x 1.)
(atan (sqrt (- 1. (* x x))) x)))

;;; Routine

;; axis of rotation.
;; TODO: several rotate axis.
(setq axis (cross-product (normalize wsd) (normalize wsdNew)))
(setq x (nth 0 axis)
y (nth 1 axis)
z (nth 2 axis))

(setq theta (acos (dot-product normal normalNew)))

;; cosine and sine of an angle
(setq cosT (cos theta)
sinT (sin theta))

;; Creating a rotation matrix
(setq R
(list
(list (+ cosT (* (- 1 cosT) (* x x)))
(- (* (- 1 cosT) (* x y)) (* sinT z))
(+ (* (- 1 cosT) (* x z)) (* sinT y))
0)
(list (+ (* (- 1 cosT) (* y x)) (* sinT z))
(+ cosT (* (- 1 cosT) (* y y)))
(- (* (- 1 cosT) (* y z)) (* sinT x))
0)
(list (- (* (- 1 cosT) (* z x)) (* sinT y))
(+ (* (- 1 cosT) (* z y)) (* sinT x))
(+ cosT (* (- 1 cosT) (* z z)))
0)
(list 0 0 0 1)))

;; displacement vector
(setq translation-vector (mapcar '- wcpNew wcp))

;; Creating a displacement matrix
(setq TT
(list
(list 1 0 0 (nth 0 translation-vector))
(list 0 1 0 (nth 1 translation-vector))
(list 0 0 1 (nth 2 translation-vector))
(list 0 0 0 1)))

;; Combining the translation and rotation matrices
(setq M (matrix-multiply TT R))

;; matrix result
M)```
```;; Command:
_\$ (CreateMatrix4x4 '(0. 0. 0.) '(500. 0. 0.) '(0 0 1) '(1500. 1500. 0.) '(0. -500. 0.) '(-1. 0. 0.))

The call should return the correct matrix, here it is:

(setq matrix '(
( 0.0 0.0 -1.0 1500.0)
(-1.0 0.0  0.0 1500.0)
( 0.0 1.0  0.0 0.0)
( 0.0 0.0  0.0 1.0)
))```

Could somebody tell me how to make that part where the axes are?

##### Share on other sites

"I would like to create a function that creates a transformation matrix for a region from the original position to the new one."

Essentially is this what you have and you want to solve for T?

T_original * T = T_new

If so,

T = T_new * (inverse T_orignal)

• 1
• 1
##### Share on other sites

• 2 weeks later...

Let's consider it solved.
There are several solutions though.

```(defun Get1011 (entity)
(cdr (assoc 1011 (cdadr (assoc -3 (entget entity '("PositionWCS")))))))

(defun Get1012 (entity)
(cdr (assoc 1012 (cdadr (assoc -3 (entget entity '("PositionWCS")))))))

(defun Get1013 (entity)
(cdr (assoc 1013 (cdadr (assoc -3 (entget entity '("PositionWCS")))))))

(defun DotProduct (u v)
(apply '+ (mapcar '* u v)))

(defun Normalize (v / len)
(setq len (sqrt (DotProduct v v)))
(mapcar '(lambda (x) (/ x len)) v))

(defun CrossProduct (v1 v2)
(list
(- (* (nth 1 v1) (nth 2 v2)) (* (nth 2 v1) (nth 1 v2)))
(- (* (nth 2 v1) (nth 0 v2)) (* (nth 0 v1) (nth 2 v2)))
(- (* (nth 0 v1) (nth 1 v2)) (* (nth 1 v1) (nth 0 v2)))))

(defun Transpose (matrix)
(apply 'mapcar (cons 'list matrix)))

(setq entity (car (entsel "\nSelect: ")))

(setq origin (Get1011 entity))
; (1500.0 1500.0 0.0)

(setq xvector (Normalize (Get1012 entity)))
; (0.0 -1.0 0.0)

(setq yvector (CrossProduct (Get1013 entity) xvector))
; (0.0 0.0 1.0)

(setq zvector (Get1013 entity))
; (-1.0 0.0 0.0)

(setq M (Transpose (list xvector yvector zvector)))

;; Multiply. [simplified]
(setq mlist
(list
(append (nth 0 M) (list (nth 0 origin)))
(append (nth 1 M) (list (nth 1 origin)))
(append (nth 2 M) (list (nth 2 origin)))
'(0. 0. 0. 1.)))

;; achieved
(setq matrix (vlax-tmatrix mlist))

;; Test.
center (vlax-3d-point 10 10 0)

(vla-TransformBy circleObj matrix)```

The End.

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.

×   Pasted as rich text.   Restore formatting

Only 75 emoji are allowed.