Jump to content

how to find diameter from 3D SOLID (cylinder)


Arin9916

Recommended Posts

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.

Link to comment
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 )
 (vl-load-com)
 (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.

Link to comment
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

Link to comment
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.

Link to comment
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.

 

http://www.cadtutor.net/forum/showthread.php?37494

Link to comment
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)
)

Link to comment
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

Link to comment
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. ;)

Link to comment
Share on other sites

  • 7 years later...

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

Link to comment
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!

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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...