TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: mariolino0099 on October 28, 2021, 11:14:07 AM
-
Hi everyone,
I have searched through the old posts but have not found the solution. I'm looking for the possibility to apply to a selection (or to all the objects of a drawing) a 3x3 matrix + 1x3 displacement vector (or a 4x4 matrix) inserted by the user to transform all the coordinates of all the objects or vertices.
thanks
Mario
https://www.brainvoyager.com/bv/doc/UsersGuide/CoordsAndTransforms/SpatialTransformationMatrices.html
-
Simple trans function should do the trick. but I am a bit confused on what you want to do maybe attach a drawing.
-
Example demo attached and matrix 4x4:
0.95 8.25E-06 0 999987.5731
-6.5E-06 1.2 0 -13.23376278
0 0 1 0
0 0 0 1
Thanks
-
Look at what Lee Mac posted a few threads down.
https://www.theswamp.org/index.php?topic=57101.0
maybe modify that to your matrix?
-
hi,
transformed all object into a block and applied the command:
this is the result ....
Select objects: 1 found
Select objects: ; error: Automation Error. Cannot scale nonuniformly
Thanks
-
If you want to apply a non-uniform matrix transformation, you'll need to apply the transformation on a pointwise basis (as I demonstrate here (http://lee-mac.com/2dprojection.html)), since the result of a non-uniform transformation will typically change the primitive type of an object (e.g. a non-uniformly scaled ARC entity would necessarily need to become either an ELLIPSE or SPLINE entity), and such a conversion is not possible using only the ActiveX transformby method.
-
many thanks,
I tried the program "2d projection", it is a bit different from the concept x' = M x, in fact the matrix generated by "2d projection" is not familiar to me....
I understand well that objects are deformed by this transfomation (like circles, ellipses, spline.....), but my idea was to see if it was possible to iterate on all selected objects, and if there is even one coordinate (for example a text) apply the matrix M to the insertion point of the text, for a circle the transfomation is only for the center of the circle, for a pline (or 3dpoly) all the vertices, ...... In this way a bit of everything is transformed.
It is necessary to see the result of the transformation in a real case.
-
many thanks,
I tried the program "2d projection", it is a bit different from the concept x' = M x, in fact the matrix generated by "2d projection" is not familiar to me....
I understand well that objects are deformed by this transfomation (like circles, ellipses, spline.....), but my idea was to see if it was possible to iterate on all selected objects, and if there is even one coordinate (for example a text) apply the matrix M to the insertion point of the text, for a circle the transfomation is only for the center of the circle, for a pline (or 3dpoly) all the vertices, ...... In this way a bit of everything is transformed.
It is necessary to see the result of the transformation in a real case.
Then you shouldn't use (vla-tranformby) function, but (entmod) applied to transformed points (pt' = M-3x3*pt + 4th-dimension-of-M4x4-[translation]+pt)...
-
hi, is possibile to explain betten this expression
pt' = M-3x3*pt + 4th-dimension-of-M4x4-[translation] ?
-
hi, is possibile to explain betten this expression
pt' = M-3x3*pt + 4th-dimension-of-M4x4-[translation] ?
These 2 are identical, but for your situation, you shouldn't use (vla-transformby) as it can't be applied to objects without deformation - non-uniform scale is not supported...
(defun c:mat2pts ( / applymatrix2pt mxv mat ss i pt ptx )
(defun applymatrix2pt ( mat pt / 3x3mat vector )
(setq 3x3mat (reverse (cdr (reverse (mapcar '(lambda ( x ) (mapcar '+ '(0 0 0) x)) mat)))))
(setq vector (mapcar '+ '(0 0 0) (last (apply 'mapcar (cons 'list mat)))))
(mapcar '+ (mxv mat pt) vector)
)
(defun mxv ( m v )
(mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
)
;|
(setq mat
(list
(list 0.95 8.25E-06 0 999987.5731)
(list -6.5E-06 1.2 0 -13.23376278)
(list 0 0 1 0)
(list 0 0 0 1)
)
)
|;
(setq mat
(list
(list 1 0 0 10.0)
(list 0 1 0 5.0)
(list 0 0 1 0)
(list 0 0 0 1)
)
)
(setq ss (ssget "_:L" '((0 . "POINT"))))
(repeat (setq i (sslength ss))
(setq pt (ssname ss (setq i (1- i))))
(entupd (cdr (assoc -1 (entmod (subst (cons 10 (applymatrix2pt mat (cdr (assoc 10 (setq ptx (entget pt)))))) (assoc 10 ptx) ptx)))))
)
(princ)
)
(defun c:mat2pts-vla ( / mat ss i pt )
(vl-load-com)
;|
(setq mat
(list
(list 0.95 8.25E-06 0 999987.5731)
(list -6.5E-06 1.2 0 -13.23376278)
(list 0 0 1 0)
(list 0 0 0 1)
)
)
|;
(setq mat
(list
(list 1 0 0 10.0)
(list 0 1 0 5.0)
(list 0 0 1 0)
(list 0 0 0 1)
)
)
(setq ss (ssget "_:L" '((0 . "POINT"))))
(repeat (setq i (sslength ss))
(setq pt (ssname ss (setq i (1- i))))
(vla-transformby (vlax-ename->vla-object pt) (vlax-tmatrix mat))
)
(princ)
)
-
Hi, it's an amazing and elegant solution, :-)
is it possible to apply the matrix to all the coordinates of a whole drawing
(regardless of the objects type lines, circles, points, texts, 3dface,...) ?
Thanks