apply matrix transformation to object

apply matrix transformation to object

Moshe-A
Mentor Mentor
378 Views
4 Replies
Message 1 of 5

apply matrix transformation to object

Moshe-A
Mentor
Mentor

hi experts,

 

Have idea to write a command and make use of Lee Mac >> Matrix Transformation Functions << 

especially i am interested in doing scale + rotate transformation with no position change at this stage. we see this functionality in NCOPY command. never used transformation so i need a simple example for VLA-object taken from an insert (could be scaled + rotated) and copy it to model space.

 

thanks in advance

Moshe

 

 

 

0 Likes
Accepted solutions (1)
379 Views
4 Replies
Replies (4)
Message 2 of 5

_gile
Consultant
Consultant

Hi,

Here's an example which uses some matrix functions from the MathGeom library at the bottom of this page.

;; TRP
;; Transposes a matrice -Doug Wilson-
;;
;; Argument
;; m : a matrix
(defun trp (m) (apply 'mapcar (cons 'list m)))

;; MXV
;; Applies a transformation matrix to a vector -Vladimir Nesterovsky-
;;
;; Arguments-
;; m : a matrix
;; v : a vector
(defun mxv (m v)
  (mapcar (function (lambda (r) (apply '+ (mapcar '* r v))))
	  m
  )
)

;; MXM
;; Multiplies (combinates) to matrices -Vladimir Nesterovsky-
;;
;; Arguments
;; m : a matrix
;; q : a matrix
(defun mxm (m q)
  (mapcar (function (lambda (r) (mxv (trp q) r))) m)
)

;; gc:ScaleMatrix
;; Returns a scale matrix (4x4)
;;
;; Arguments
;; base : the base point
;; scl : the scale factor
(defun gc:ScaleMatrix (base scl)
  (append
    (mapcar
      (function
	(lambda	(v1 v2)
	  (append (mapcar '(lambda (x) (* x scl)) v1)
		  (list v2)
	  )
	)
      )
      '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
      (mapcar '(lambda (x) (- x (* x scl))) base)
    )
    '((0. 0. 0. 1.))
  )
)

;; gc:2dRotationMatrix
;; Retruns a rotation matrix (4x4) about Z axis
;;
;; Arguments
;; base : the base point
;; ang : the rotation angle (radians)
(defun gc:2dRotationMatrix (base ang / mat)
  (append
    (mapcar
      (function
	(lambda	(v1 v2)
	  (append v1 (list v2))
	)
      )
      (setq mat	(list (list (cos ang) (- (sin ang)) 0.)
		      (list (sin ang) (cos ang) 0.)
		      '(0. 0. 1.)
		)
      )
      (mapcar '- base (mxv mat base))
    )
    '((0. 0. 0. 1.))
  )
)

(defun c:test (/ nent pe rot scl copy)
  (if
    (and
      (setq nent (nentselp "\nSelect nested object to copy: "))
      (setq pt (getpoint "\nSpecify base point: "))
      (setq rot (getangle "\nSpecify rotation: "))
      (setq scl (getreal "\nEnter scale: "))
    )
     (progn
       (setq pt (trans pt 1 0))
       (setq xform (caddr nent))
       (setq acdoc (vla-get-activeDocument (vlax-get-acad-object)))
       (setq
	 clone (car (vlax-invoke
		      acdoc
		      'CopyObjects
		      (list (vlax-ename->vla-object (car nent)))
		      (vla-get-ModelSpace acdoc)
		    )
	       )
       )
       (vla-TransformBy
	 clone
	 (vlax-TMatrix
	   (mxm	(gc:ScaleMatrix pt scl)
		(mxm (gc:2dRotationMatrix pt rot) xform)
	   )
	 )
       )
     )
  )
  (princ)
)

 

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 5

Moshe-A
Mentor
Mentor

@_gile  hi,

 

Thank you very much for this but in this program i select the nested object by iterating over the block objects

so no call to (nentselp) is made and can not have xform from it. the parent block is selected by (ssget) so need work around?

 

Moshe

 

 

 

0 Likes
Message 4 of 5

_gile
Consultant
Consultant

@Moshe-A  a écrit :

Thank you very much for this but in this program i select the nested object by iterating over the block objects

so no call to (nentselp) is made and can not have xform from it. the parent block is selected by (ssget) so need work around?


You can use the following function (from the same library).

;; gc:BlockTransform
;; Returns the transformation matrix of a block reference (insert)
;; 4x4 matrix as the one returned by nentselp
;;
;; Argument
;; ename : the block reference entity name
(defun gc:BlockTransform (ename / elst ang norm)
  (setq	elst (entget ename)
	ang  (cdr (assoc 50 elst))
	norm (cdr (assoc 210 elst))
  )
  (append
    (mapcar
      (function
	(lambda	(v1 v2)
	  (append v1 (list v2))
	)
      )
      (setq mat
	     (mxm
	       (mapcar (function (lambda (v) (trans v 0 norm T)))
		       '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
	       )
	       (mxm
		 (list (list (cos ang) (- (sin ang)) 0.)
		       (list (sin ang) (cos ang) 0.)
		       '(0. 0. 1.)
		 )
		 (list (list (cdr (assoc 41 elst)) 0. 0.)
		       (list 0. (cdr (assoc 42 elst)) 0.)
		       (list 0. 0. (cdr (assoc 43 elst)))
		 )
	       )
	     )
      )
      (mapcar
	'-
	(trans (cdr (assoc 10 elst)) norm 0)
	(mxv mat
	     (cdr (assoc 10 (tblsearch "BLOCK" (cdr (assoc 2 elst)))))
	)
      )
    )
    '((0. 0. 0. 1.))
  )
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 5

Moshe-A
Mentor
Mentor
Accepted solution

@_gile  hi,

 

Today you are my honored man, it works Amazing thank you very much  - you made my day 😀💪

 

Moshe

 

 

0 Likes