Jump to content

# 3D rotate block from the base point and the other point of the blok ?

## Recommended Posts

hello

Â

does anyone knows, if is it possible to 3d rotate a 3d bloc from its base point and the other point of the block ? for sure in LISP.

Â

thank you

Â

Â

• Replies 22
• Created
• Last Reply

• 9

• 7

• 5

• 1

#### Popular Posts

If you are working in 3D you will need to specify two angles to define the location of the second point. For example, an angle in the XY plane and an angle about the z axis. The distance is not import

#### Posted Images

I dont use 3D for my work but can't you use ALIGN command for this? Should work for 2 & 3D transformations. First point would be block insertionpoint from and 2nd point is whatever point (on the block) you feed to align command , then press enter , et voila...done

Â

Maybe post a picture and someone with more 3D knowledge can give you a more intelligent answer.

##### Share on other sites

With the rotate3d command (not to be confused with 3drotate) you can specify 2 points to define an axis of rotation at any 3d orientation you wish.

##### Share on other sites
Posted (edited)
```hello everyone

I found that but I want to change the second point which will be defined with the angle, one meter from the first point.```

Â

```(defun c:3rtx ( / *error* obj tmppoint)
;3D rotate texts mtexts and blocks aound an axis aligned
;on the x axis, passing by their individual insertion points.
;made by Jef! 2015-12-11.
(defun *error* ( msg )
(if (not (member msg '("Function cancelled" "quit / exit abort")))
(princ (strcat "\nError: " msg))
)
(princ)
)
(princ "\nSelect objects to rotate")
(if (ssget)
(progn
(vlax-for obj (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object)))
(if (or (eq (vla-get-objectname obj) "AcDbMText")
(eq (vla-get-objectname obj) "AcDbText")
(eq (vla-get-objectname obj) "AcDbBlockReference")
)
(progn
(vla-Rotate3D obj (vlax-3d-point (setq tmppoint (vlax-get obj 'InsertionPoint))) (vlax-3d-point (mapcar '+ tmppoint '(1 0 0))) (/ pi 2))
(if (and (eq (vla-get-objectname obj) "AcDbBlockReference")
(= (vlax-get-property obj 'HasAttributes) :vlax-true)
)
(vl-cmdf "_.AttSync" "Name" (vla-get-name obj))
)
)
)
)
)
(princ "nothing selected")
)
(princ)
) ```

Â

Â

Â

Edited by CADTutor
Moved code to code block
##### Share on other sites
Quote
```
I found that but I want to change the second point which will be defined with the angle, one meter from the first point.```

If you are working in 3D you will need to specify two angles to define the location of the second point. For example, an angle in the XY plane and an angle about the z axis. The distance is not important as the two points are defining anÂ axis of rotation and it doesn't matter how far apart they are.Â  It's not clear what you are trying to do.Â  Your first post indicated that you want to rotate a block in 3D space but your last post seems to imply that you really just want to rotate in a plane.

##### Share on other sites

Sorry i was not clear, i agree with you, i know that to rotate ( 3Drotate and not rotate 3d ) you need to select two points and define an angle, but the thing is i have a lot of block so i dont want to select for each block two points. the idea is that i wanted to use formula trigonometry ( cosinus angle something like this) to select automatically the second point.

see the picture

##### Share on other sites

It is still not clear to me what is your goal.Â  Perhaps someone else would like to jump in and help.Â Â

Could you clarify the following?

1.Â  DoÂ you want a vlisp program that will allow you to select many blocks at one time and have them all rotate to some specifiedÂ orientation or do you want to work on a single block?

2. Do you realize that the angle specified in the Properties panel is the angle of rotation in the WCS and does not reflect the current UCS nor the fact the the block may be rotated out of the WCS XY plane?

3. If you want to rotate an object so that it is oriented from a base point to a reference point you can use the Reference option with the rotate command.Â  For example,Â Â the block MyBox is oriented at an angle of 30Â°.Â  Let's say we would like the long side of the box to point from the base point to the point at right.

Give the rotate command, select the block and then the base point.

Now input R (reference)Â  and specify the base point (1)Â  and a second point (2) for theÂ reference direction and a point for the new direction (3).

Â

The result is the following.

Â

Is this what you want to do?

Â

Â

##### Share on other sites

thank you for your help lrm

Â

yes i want to select many block at one time and rotate at 90Â°

Â

Â

##### Share on other sites

The following command rot90x,Â  will rotate a block by 90Â° about its x axis but will only do one at a time.Â  Perhaps someone else can enhance it for multiple blocks or has another approach.

```(defun c:rot90x (/)
; rotates a block by 90Â° about its x axis.
(setq	blk    (cdr (nentsel))
xdir   (nth 0 (nth 1 blk))
basept (nth 3 (nth 1 blk))
refpt  (mapcar '+ basept xdir)
)
(command "_rotate3d" basept "" "2" basept refpt 90.0)
(princ)
)```

Â

##### Share on other sites
Posted (edited)

untested but assuming Irm's code works I hope this also works :

[code]

Â

(defun t1 ( / ss i blk xdir basept refpt)
Â  (if (setq ss (ssget '((0 . "INSERT"))))
Â Â Â  (repeat (setq i (sslength ss))
Â Â Â Â Â  (setq blk (ssname ss (setq i (1- i))))
Â Â Â Â Â  (setq xdir (nth 0 (nth 1 blk)) basept (nth 3 (nth 1 blk)) refpt (mapcar '+ basept xdir))
Â Â Â Â Â  (command "_rotate3d" basept "" "2" basept refpt 90.0)
Â Â Â  )
Â  )
Â  (princ (strcat "\nRotated " (if ss (itoa (sslength ss)) "0") " blocks"))
Â  (princ)
)

Â

[/code]

Â

Edited by rlx
has [code] tags changed?
##### Share on other sites

@rlx, mine works for one block, yours does not forÂ multipleÂ blocks.

Â

Error "; error: bad argument type: consp <Entity name: 238f0cb2930>" with:Â

`      (setq xdir (nth 0 (nth 1 blk)) basept (nth 3 (nth 1 blk)) refpt (mapcar '+ basept xdir))`

Â

I'm not sure what you are trying to do with xdir.Â  It's the direction vector of the x axis in WCS of the block.Â  The challenge is going on to the next object in a selection set.Â  It's not clear to me how, or if,Â  you can do that with nentsel.Â  blk via nentsel contains the block's transformation matrix.Â  blk via ssget in your program is just the entity name.

##### Share on other sites
1 hour ago, rlx said:

has [code] tags changed?

Â

Yes, I'm afraid so. The new forum software no longer supports BBcode. It's now considered a legacy feature. However, the editor code blocks work in the same way as before.

##### Share on other sites

@lrm , ah , yes I see what you mean , hence the untested , didn't take into account entsel returns matrix , probably have to replace this with retrieve inspoint for each block with nentselp or get matrix from block itself. Will have to look at this later because has been very long day for me / very short night.

Â

@david , ok , understood , will use editor code blocks from now on

Â

##### Share on other sites

Hello evryone thank you all

Â

but it does not work. i tested and see the result in the picture

Â

Â

##### Share on other sites

maybe like this (stolen & adapted from master Lee)

Â

```;;; https://www.cadtutor.net/forum/topic/50653-rotate3d-lisp-need-help/
(defun c:3drblk ( / ang axs idx lst obj sel )
(setq ang (/ pi 2.0))
(if (setq sel (ssget "_:L" '((0 . "INSERT"))))
(progn
(repeat (setq idx (sslength sel))
(setq lst
(cons
(cons (setq obj (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))))
(vlax-get obj 'insertionpoint)
)
lst
)
)
)
(princ "\nRotate about [X/Y/Z] <Exit>: ")
(while
(setq axs
(cdr
(assoc (grread nil 10)
'(
((2 120) 1.0 0.0 0.0)
((2 088) 1.0 0.0 0.0)
((2 121) 0.0 1.0 0.0)
((2 089) 0.0 1.0 0.0)
((2 122) 0.0 0.0 1.0)
((2 090) 0.0 0.0 1.0)
)
)
)
)
(foreach itm lst
(vlax-invoke (car itm) 'rotate3d (cdr itm) (mapcar '+ (cdr itm) axs) ang)
)
)
)
)
(princ)
)```

Â

##### Share on other sites

@dr.hybrideplease post a copy of the block you are using.

##### Share on other sites

@rlxÂ  The program 3drblk appears to rotate the blocks about an axis parallel to the world x, y, or z axis.Â  I think the OP wants the blocks to rotated about the block's local axis but he hasn't made thatÂ clear.Â  He may in fact may want to define a local axis with 2 points.Â  Having a copy of the block would helpÂ  to understand the requirements.

##### Share on other sites
`Â `

@lrm , you maybe right , only tested it on a flog of flat-world symbols because I have no 3D symbols. They all fell over at the x-axis so was kinda hoping this is it... awell it was worth a shot. Just not experiece with 3D I'm afraid

Â

I was about to experiment with this when I saw Lee's code , hoping I could retrieve entmatrix for each item in selectionset and then feed this to your command. But I guess , beeing somewhat of a resident of flat-world , better leave this to the inhabitants of 3D-world

Â

```; Transpose a matrix Doug Wilson
(defun trp ( m )   (apply 'mapcar (cons 'list m)))
; Apply a transformation matrix to a vector by Vladimir Nesterovsky
(defun mxm ( m n ) ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n)))
; Multiply two matrices by Vladimir Nesterovsky
(defun mxv ( m v ) (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m))

; RefGeom (gile)
; test : (setq pl (RefGeom (car (entsel)))) only blocks?
(defun RefGeom ( ename / elst ang norm mat )
(setq elst (entget ename)  ang  (cdr (assoc 50 elst)) norm (cdr (assoc 210 elst)))
(list (setq mat (mxm (mapcar '(lambda ( v ) (trans v 0 norm t)) '((1.0 0.0 0.0)(0.0 1.0 0.0)(0.0 0.0 1.0)))
(mxm (list (list (cos ang) (- (sin ang)) 0.0) (list (sin ang) (cos ang) 0.0) '(0.0 0.0 1.0))
(list (list (cdr (assoc 41 elst)) 0.0 0.0) (list 0.0 (cdr (assoc 42 elst)) 0.0)
(list 0.0 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)))))))
)
)

; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/get-entities-inside-a-block/td-p/2644829
; Entmatrix returns a list which first item is the 3X3 tranformation matrix and second item the insertion point
; of a block refernce in its owner (space or block definition)
(defun EntMatrix ( ename / e a n)
(setq    e (entget ename) a (cdr (assoc 50 e)) n (cdr (assoc 210 e)))
(list (mxm (mapcar (function (lambda (v) (trans v 0 n T))) '((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0)))
(mxm (list (list (cos a) (- (sin a)) 0.0) (list (sin a) (cos a) 0.0) '(0.0 0.0 1.0))
(list (list (cdr (assoc 41 e)) 0.0 0.0) (list 0.0 (cdr (assoc 42 e)) 0.0)
(list 0.0 0.0 (cdr (assoc 43 e))))))    (trans (cdr (assoc 10 e)) n 0)))```

Â

##### Share on other sites
Posted (edited)

hello everyone thank you all

i'm more confortable in VBA, this why i did in VBA , if someone can to translate in lisp.

Â

``` Public Sub Rotate3D_Exp()
Dim ent As AcadEntity
Dim vPt As Variant

On Error Resume Next

' Get the object to rotate
ThisDrawing.Utility.GetEntity ent, vPt, vbLf + "Select the block to rotate: "

' Make sure an object was selected
If Err = 0 Then
' Check to see if the selected object was a block reference
If ent.ObjectName = "AcDbBlockReference" Then
Dim blkRef As AcadBlockReference
Set blkRef = ent

' Check to see if the block reference was an instance of the MYBLOCK definition
If blkRef.EffectiveName = "Portique shematique" Then

' Define the rotation axis
Dim rotatePt1(0 To 2) As Double
Dim rotatePt2 As Variant
Dim rotateAngle As Double

anglebloc = blkRef.Rotation
'anglebloc = blkRef.Rotation * 3.141592 / 180

'rotatePt1 = -3: rotatePt1(1) = 4: rotatePt1(2) = 0
rotatePt1(0) = blkRef.InsertionPoint(0)
rotatePt1(1) = blkRef.InsertionPoint(1)
rotatePt1(2) = blkRef.InsertionPoint(2)

rotatePt2 = ThisDrawing.Utility.PolarPoint(blkRef.InsertionPoint, anglebloc, 1)

rotateAngle = 90
rotateAngle = rotateAngle * 3.141592 / 180#

' Rotate the block reference
blkRef.Rotate3D rotatePt1, rotatePt2, rotateAngle
End If
End If
End If
End Sub ```

Â

Â

Edited by CADTutor
Moved code to code block
##### Share on other sites

It looks like your VBA code rotates the block by 90Â° about an axis defined by a line from the basepointÂ  to a point define by the the angle of the block.Â  As noted earlier, the angle parameter is the angle defined by theÂ projection of the x-axis of the block onto the xy plane.Â

Â

Here are two versions of a vlisp program to rotate a block by 90Â° about an axis define by two points.

Â

rot90x rotates aÂ block by 90Â° about the x axis of the block.

rot90ang rotates a block by 90Â° about the line define by the x axis of the block projected to the XY plane.Â  This should be similar to your VBA program.

Â

```(defun c:rot90x	(/ blk xdir basept refpt)
; rotates a block by 90Â° about its x axis.
(setq blk (cdr (nentsel)))
(if (= (length blk) 1)
(princ "\nError, object not a block.")
(progn
(setq xdir   (nth 0 (nth 1 blk))
basept (nth 3 (nth 1 blk))
refpt  (mapcar '+ basept xdir)
)
(command "_rotate3d" basept "" "2" basept "_non" refpt 90.0)
)
)
(princ)
)

(defun c:rot90ang (/ blk xdir basept refpt)
; rotates a block by 90Â° about its x axis prject to the WCS xy plane.
(setq blk (cdr (nentsel)))
(if (= (length blk) 1)
(princ "\nError, object not a block.")
(progn
(setq xdir   (nth 0 (nth 1 blk))
basept (nth 3 (nth 1 blk))
refpt  (mapcar '+ basept xdir)
refpt  (list (nth 0 refpt) (nth 1 refpt) (nth 2 basept))
)
(command "_rotate3d" basept "" "2" basept "_non" refpt 90.0)
)
)
(princ)
)```

Â

## 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.

Reply to this topic...

×   Pasted as rich text.   Restore formatting

Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×

×
×
• Create New...