how to find diameter from 3D SOLID (cylinder)

Recommended Posts

i want diameter from 3DSOLID using lisp.

is it possible to get diameter?

Sample.dwg

Share on other sites

Seems that there were proposed some solutions that you may want to test.

Share on other sites

thanks MSasu.

but that lisp is error in my test.

(vlax-get o 'position) value = nil (see my attachment DWG)

Share on other sites

Get bounding box of 3d solid cylinder, see witch 2 edges of bounding box are with the same length, and that length is your diameter - radius is half of that...

M.R.

Share on other sites

Very nice and concise solution Marko!

Share on other sites

Is the bounding box always in the cylinder's axis? Or would you need to acommodate a cylinder which is not parallel to the XYZ axes of the WCS?

Share on other sites

So, I figured out that you may need 3d bounding box... Here is the code to get it :

```(defun UCS2WCSMatrix ()
(vlax-tmatrix
(append
(mapcar
'(lambda (vector origin)
(append (trans vector 1 0 t) (list origin))
)
(list '(1 0 0) '(0 1 0) '(0 0 1))
(trans '(0 0 0) 0 1)
)
(list '(0 0 0 1))
)
)
)

(defun WCS2UCSMatrix ()
(vlax-tmatrix
(append
(mapcar
'(lambda (vector origin)
(append (trans vector 0 1 t) (list origin))
)
(list '(1 0 0) '(0 1 0) '(0 0 1))
(trans '(0 0 0) 1 0)
)
(list '(0 0 0 1))
)
)
)

(defun c:bbsolid ( / echocmd oscmd sn entActivX dir v1 v2 v3 cents bmin bmax )
(setq echocmd (getvar "cmdecho"))
(setvar "cmdecho" 0)
(setq oscmd (getvar "osmode"))
(setvar "osmode" 0)
(command "ucs" "w")
(setq sn (car (entsel "\nPick 3d solid to find its 3d bounding box")))
(setq entActivX (vlax-ename->vla-object sn))
(setq dir (vlax-safearray->list (vlax-variant-value (vla-get-PrincipalDirections entActivX))))
(setq v1 (list (nth 0 dir) (nth 1 dir) (nth 2 dir)))
(setq v2 (list (nth 3 dir) (nth 4 dir) (nth 5 dir)))
(setq v3 (list (nth 6 dir) (nth 7 dir) (nth 8 dir)))
(setq cents (vlax-safearray->list (vlax-variant-value (vla-get-Centroid entActivX))) )
(command "ucs" "3p" cents (mapcar '+ cents v1) (mapcar '+ cents v2))
(vla-TransformBy entActivX (UCS2WCSMatrix))
(vla-getboundingbox entActivX 'minpoint 'maxpoint)
(vla-TransformBy entActivX (WCS2UCSMatrix))
(setq bmin (vlax-safearray->list minpoint))
(setq bmax (vlax-safearray->list maxpoint))
(command "box" bmin bmax)
(prompt "\n3d Bounding box min point is : ")(princ (trans bmin 1 0))
(prompt "\n3d Bounding box max point is : ")(princ (trans bmax 1 0))
(terpri)
(command "ucs" "p")
(command "ucs" "p")
(prompt "\nFirst dimension of 3d bounding box is : ")(princ (- (car bmax) (car bmin)))
(prompt "\nSecond dimension of 3d bounding box is : ")(princ (- (cadr bmax) (cadr bmin)))
(prompt "\nThird dimension of 3d bounding box is : ")(princ (- (caddr bmax) (caddr bmin)))
(textscr)
(setvar "cmdecho" echocmd)
(setvar "osmode" oscmd)
(princ)
)
```

M.R.

Share on other sites

Marko, nicely done.

The PrincipalDirection(PD) is a good shortcut to help realign the geometry. The PD is almost too precise, though, and becomes erratic when less regular solids are in question.

For instance, if the cylinder has a slice at top (see attached) the alignment is skewed. Any thoughts on how to adjust for this?

CutCylinders.dwg

Share on other sites

Sean, there is nothing wrong with PD... CAD calculates them based on 3DSOLID geometry... Since you sliced base cylinder primitive a little, PD are little different than for real cylinder (Moments are also different)... This 3d bounding box is only helper object - if geometry is base primitive than data extracted from it are useful, otherwise if geometry is complex the data will be in relation to complexity of geometry (you can't calculate radius or something similar)...

M.R.

Share on other sites
Sean, there is nothing wrong with PD... CAD calculates them based on 3DSOLID geometry... Since you sliced base cylinder primitive a little, PD are little different than for real cylinder (Moments are also different)... This 3d bounding box is only helper object - if geometry is base primitive than data extracted from it are useful, otherwise if geometry is complex the data will be in relation to complexity of geometry (you can't calculate radius or something similar)...

M.R.

Quite true.

I didn’t mean to imply that the calculations were wrong, just that the returned vectors were not immediately useful for orienting the “cut cylinder” as it would for a base primitive.

Essentially, my post was an attempt to resurrect a comprehensive Oriented Bounding Box discussion similar to this thread.

Share on other sites

I know Sean, my friend... Also you may want to look to this posted on http://www.theswamp.org

http://www.theswamp.org/index.php?topic=42632.0

(Maybe use ucs -> face option - pick bottom face of cylinder with sliced top and apply BBB.lsp from link I just typed)

M.R.

Share on other sites

Since we are dealing with a regular solid (a cylinder), just use the inherent relationships between the solid properties, e.g.:

```(defun cylrad ( obj )
(sqrt (/ (last (vlax-get obj 'principalmoments)) (vla-get-volume obj) 0.5))
)```

Test function:

```(defun c:test ( / e o )
(if
(and
(setq e (car (entsel "\nSelect Cylinder: ")))
(setq o (vlax-ename->vla-object e))
(= "AcDb3dSolid" (vla-get-objectname o))
)
(princ (strcat "\nCylinder Radius: " (rtos (cylrad o))))
)
(princ)
)```

Share on other sites

Thanks For every.. :)

but thses is some problum...

marko `s solution is a little bit of error occurs.

Your source is perpect but, i know that these is minor error incase using getboudingbox method. right?

and i want get radius not length... is it possible only get radius value

and lee-mac`s solution is also error occurs.

I think .. Need to take into account the variation in the axis

both lisp is very great but i Can not be modified due to a lack of skills.

I'm sorry, but Is it possible to modify the Lisp?

Sample2.dwg

Share on other sites

```(defun cylrad ( obj )
(sqrt (/ (apply 'min (vlax-get obj 'principalmoments)) (vla-get-volume obj) 0.5))
)```

```(defun c:test ( / e o )
(if
(and
(setq e (car (entsel "\nSelect Cylinder: ")))
(setq o (vlax-ename->vla-object e))
(= "AcDb3dSolid" (vla-get-objectname o))
)
(princ (strcat "\nCylinder Radius: " (rtos (cylrad o))))
)
(princ)
)```

Assumes cylinder is longer than it is wide.

Share on other sites

I know this was all posted long ago, but fortunately I found it years later when looking for a solution. Great stuff!

@marko_ribar posted his bbsolid routine above, and it gives me (almost) exactly what I need.

I'm trying to process the whole model, get each of marko's 5 values for each solid, add their layer, and write it all to a csv file.

But I'm not having much luck. It's been a lot of years since I wrote any autolisp. Can anyone show how to add those elements to bbsolid?

Cheers!

RR

Share on other sites

Oops, I should have said 9 values...

Share on other sites

Never mind, I got it!  Whew that was a fun ride on the way-back machine.

Stay well y'all.

Share on other sites
1 hour ago, rapper said:

Never mind, I got it!  Whew that was a fun ride on the way-back machine.

Stay well y'all.

Glad you got it sorted. Maybe post your solution? Welcome!

Share on other sites

just to have any news

Share on other sites

Here is my attempt and some other solutions on the topic.

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.   Paste as plain text instead

Only 75 emoji are allowed.