TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Adesu on March 06, 2007, 01:15:55 AM

Title: How to get bigger and smaller distance
Post by: Adesu on March 06, 2007, 01:15:55 AM
Hi Alls,
I just got this drawing from others forum,I got difficult to get bigger and smaller distance,yes that is not ellipse,my question is it possible to get as like ellipse to find major axis and minor axis distance.  :angel:
Code: [Select]
(defun massoc (key alist / x nlist)          ; Jaysen Long
  (foreach x alist
    (if
      (eq key (car x))
      (setq nlist (cons (cdr x) nlist))
      )
    )
  (reverse nlist)
  )

(defun cl3p (pcs lst / len div cnt xlst nlst)
  (setq len (length lst))
  (setq div (/ len pcs))
  (setq cnt 0)
  (repeat div
    (if
      (= pcs 3)
      (progn
(setq xlst (list (nth cnt lst)
(nth (1+ cnt) lst)
(nth (+ 2 cnt) lst)))
(setq nlst (append nlst (list xlst)))
(setq cnt (+ 3 cnt))
)                    ; progn
      )                      ; if
    )                        ; repeat
    nlst
    )                        ; defun

(defun c:test ( / ss vevo area leng obj)
  (vl-load-com)
  (if
    (setq ss (car (entsel "\nSelect an object"))) 
    (progn
      (setq vevo (vlax-ename->vla-object ss))     
      ;(vlax-dump-object vevo)
      (setq area (rtos (vla-get-area vevo)))
      (setq leng (rtos (vla-get-length vevo)))
      (setq obj (substr (vla-get-ObjectName vevo) 5 10))
      (setq co (vla-get-Coordinates vevo))         
      (setq coo (vlax-safearray->list (vlax-variant-value co)))
      (setq 3p (cl3p 3 coo))
      ; ????????
     
      (alert (strcat "\nThis object is"
     "\n"
     "\nObject name is " obj
     "\n"
     "\nArea object is " area
     "\n"
     "\nLength is " leng
     "\n"
     "\nBigger distance is" big
     "\n"
     "\nSmaller distance is" small
      )       ; progn
    (alert "\nInvalid selected object,try again")
    )         ; if
  (princ)
  )           ; defun
Title: Re: How to get bigger and smaller distance
Post by: ElpanovEvgeniy on March 06, 2007, 01:34:17 AM
To find all is possible!
After yours to the drawing, I have not understood, that you name the big distance and that small...
Add in the drawing the dimension which need to be found.
Title: Re: How to get bigger and smaller distance
Post by: Adesu on March 06, 2007, 01:59:38 AM
To find all is possible!
After yours to the drawing, I have not understood, that you name the big distance and that small...
Add in the drawing the dimension which need to be found.


Hi Elpanov,
Look at attach file,that line is approximately
Title: Re: How to get bigger and smaller distance
Post by: ElpanovEvgeniy on March 06, 2007, 02:06:14 AM
To me again it is not clear...
It is probably necessary to find the minimal dimensional container?
Title: Re: How to get bigger and smaller distance
Post by: Adesu on March 06, 2007, 02:13:43 AM
To me again it is not clear...
It is probably necessary to find the minimal dimensional container?

Yes.
Title: Re: How to get bigger and smaller distance
Post by: ElpanovEvgeniy on March 06, 2007, 06:32:01 AM
Code: [Select]
(defun c:test (/ E LST MA MI)
 (if (setq e (car (entsel "\n Select object: ")))
  (progn (setq e   (vla-copy (vlax-ename->vla-object e))
               lst nil
         ) ;_  setq
         (repeat 1000
          (vla-GetBoundingBox e 'mi 'ma)
          (setq
           lst (cons (mapcar (function -) (vlax-safearray->list ma) (vlax-safearray->list mi))
                     lst
               ) ;_  cons
          ) ;_  setq
          (vla-rotate e (vlax-3d-point 0. 0.) (/ pi 1000.))
         ) ;_  repeat
         (vla-Delete e)
   (princ "\n Bounding box object with minimal length: ")
   (princ (assoc (car (apply 'mapcar (cons 'min lst))) lst))
   (princ)
  ) ;_  progn
 ) ;_  if
) ;_  defun

test function:
Code: [Select]
Command: TEST
 Select object:
 Bounding box object with minimal length: (12462.0 0.0 15617.0)
Title: Re: How to get bigger and smaller distance
Post by: Adesu on March 06, 2007, 07:03:42 PM
Hi Elpanov,
This code is great and simple,but I'm not yet understand,and I think not minimal only,it should include maximal too.
Thanks for your spend time for solve this problem.
Code: [Select]
Select object:
 Bounding box object with minimal length: (12462.0 0.0 15617.0)

Code: [Select]
(defun c:test (/ E LST MA MI)
 (if (setq e (car (entsel "\n Select object: ")))
  (progn (setq e   (vla-copy (vlax-ename->vla-object e))
               lst nil
         ) ;_  setq
         (repeat 1000
          (vla-GetBoundingBox e 'mi 'ma)
          (setq
           lst (cons (mapcar (function -) (vlax-safearray->list ma) (vlax-safearray->list mi))
                     lst
               ) ;_  cons
          ) ;_  setq
          (vla-rotate e (vlax-3d-point 0. 0.) (/ pi 1000.))
         ) ;_  repeat
         (vla-Delete e)
   (princ "\n Bounding box object with minimal length: ")
   (princ (assoc (car (apply 'mapcar (cons 'min lst))) lst))
   (princ)
  ) ;_  progn
 ) ;_  if
) ;_  defun

test function:
Code: [Select]
Command: TEST
 Select object:
 Bounding box object with minimal length: (12462.0 0.0 15617.0)
Title: Re: How to get bigger and smaller distance
Post by: zemleroi on March 06, 2007, 09:40:32 PM
Здравствуйте!

Мне adesu на другом форуме посоветовал задать вопрос насчёт обмеров вам. Фигуры, которые мне необходимо замерить - это многоугольники яйцеобразной (иногда - эллиптической) формы (в моём случае это сечения сурчиных нор). Интересуют меня два измерения: большая ось и перпендикулярная ей малая ось. Для простоты измерений можно рассматривать только расстояния между вершинами многоугольника, а не все точки на нём.
Мне казалось, что это должна быть несложная задача, но на форуме Autodesk'a мне никто не смог помочь. Я прилагаю чертёж с примером фигур и их замеров.

Буду очень благодарен за помощь
Дмитрий
Title: Re: How to get bigger and smaller distance
Post by: zemleroi on March 06, 2007, 09:48:50 PM
(По какой-то причине код, данный выше, не работает. У меня программа выдаёт:  Select object: ; error: no function definition: VLAX-ENAME->VLA-OBJECT)
Title: Re: How to get bigger and smaller distance
Post by: Kerry on March 06, 2007, 10:05:21 PM
Quote
How do you do! To me adesu on other forum advised to present the question about the measurements to you. The figures, which I should measure - these are the polygons of egg-shaped (sometimes - elliptical) form (in my case this of the section of surchinykh burrows). Two measurements interest me: major axis and perpendicular to it minor axis. It is possible to examine the distances between the apexes of polygon, but not all points on it only for simplicity of measurements. It seemed me that this must be the simple task, but to me no one not smog soak on forum Autodesk'a. I apply drawing with an example of figures and their measurements. I will be very grateful for help
Dmitriy

Quote
(on some to reason the code, given above, does not work. In me the program issues: ; error: no function definition: VLAX-ENAME->VLA-OBJECT)

Added :
using http://babelfish.altavista.com/
Title: Re: How to get bigger and smaller distance
Post by: Kerry on March 06, 2007, 10:16:25 PM
Dmitriy

Sorry. I don't understand the question.
In that drawing .
What do you mean by Minimal ?
What do you mean by Maximal ?

What are the rules ?

//-------

Which version of AutoCAD do you use. ?

//---------

This is a guess .

Do you want the center of gravity for the object ..

Then

Calculate the minimun and maximum length lines that can pass through the center and are contained within the object ?
///------------



Title: Re: How to get bigger and smaller distance -translation of the last post
Post by: zemleroi on March 06, 2007, 10:20:22 PM
Sorry, here is the translation of my previous post into English:

Hello!
Adesu advised me to consult this forum with a question about automating measurements. I am using AutoCAD 2004. The objects that I am trying to measure are egg-shaped (sometimes elliptical) polygons (these are sections of woodchuck burrows). The measurements that I am looking for are the major (longer) axis and the minor (shorter) axis perpendicular to it. For simplicity's sake, it is possible to only consider the vertices of the polygons, not all the points on the object. I am attaching a file with examples of objects I am measuring and example measurements of the two axes on these objects.

I would very much appreciate any help on this
Dmitri

P.S. (For some to reason the code that Yevgeny gave above, does not work for me. The message I get is: ; error: no function definition: VLAX-ENAME->VLA-OBJECT).

Title: Re: How to get bigger and smaller distance -translation of the last post
Post by: Adesu on March 06, 2007, 11:35:50 PM
Hi zemleroi,
Add that code with "(vl-load-com) "
Quote
P.S. (For some to reason the code that Yevgeny gave above, does not work for me. The message I get is: ; error: no function definition: VLAX-ENAME->VLA-OBJECT).
Title: Re: How to get bigger and smaller distance
Post by: zemleroi on March 06, 2007, 11:48:36 PM
Thank you Adesu! It now works. Wow, that's magic!
Is it possible to export these measurements into a txt file? I could then select multiple objects...
Title: Re: How to get bigger and smaller distance
Post by: Kerry on March 07, 2007, 12:16:36 AM
Ahhhhh I see,

The question was "what size box will this fit in"  .. yes ?
Title: Re: How to get bigger and smaller distance
Post by: fools on March 07, 2007, 12:17:43 AM
Code: [Select]
(DEFUN c:test (/ CURPA ENDPA ENT PTLST)
  ;;For SPLINE & POLYLINE
  (SETQ ent (CAR (ENTSEL)))
  (SETQ ptlst (list (vlax-curve-getStartPoint ent)))
  (SETQ EndPa (VLAX-CURVE-GETENDPARAM ent))
  (SETQ CurPa 0)
  (REPEAT 500
    (SETQ ptlst (CONS (VLAX-CURVE-GETPOINTATPARAM
      ent
      (SETQ CurPa (+ CurPa (* EndPa 0.002)))
    )
    ptlst
      )
    )
  )
  (MaxDist ptlst)
)

(DEFUN MaxDist (pts / pt dist maxd maxl)
  (SETQ maxd 0)
  (WHILE (SETQ pt  (CAR pts)
       pts (CDR pts)
)
    (FOREACH item pts     
      (COND ((< maxd (SETQ dist (DISTANCE item pt)))
     (SETQ maxd dist
   maxl (LIST pt item dist)
     )
    )
      )
    )
  )
  (list (trans (car maxl) 0 1) (trans (cadr maxl) 0 1) (caddr dist))
)

Code: [Select]
Command: TEST
 Select object:
  ((-2332.33 1544.77 137220.0) (-9607.41 -12451.1 137220.0) 15773.8)
Title: Re: How to get bigger and smaller distance
Post by: fools on March 07, 2007, 12:36:57 AM
max
Title: Re: How to get bigger and smaller distance
Post by: Kerry on March 07, 2007, 12:38:57 AM
Ahhhhh I see,

The question was "what size box will this fit in"  .. yes ?

or perhaps it isn't  :lol:
Title: Re: How to get bigger and smaller distance
Post by: zemleroi on March 07, 2007, 12:42:01 AM
Ahhhhh I see,

The question was "what size box will this fit in"  .. yes ?

Yes, that is it.
Title: Re: How to get bigger and smaller distance
Post by: Adesu on March 07, 2007, 12:55:00 AM
Hi fools,
it's great too,thanks.
Title: Re: How to get bigger and smaller distance
Post by: fools on March 07, 2007, 01:28:00 AM
 :-) Hi Adesu , you are welcome.
Change for minor axis:
Code: [Select]
(DEFUN c:test (/ CURPA ENDPA ENT PTLST LST MAXPTS)
  ;;For SPLINE & POLYLINE
  (SETQ ent (CAR (ENTSEL)))
  (SETQ ptlst (LIST (VLAX-CURVE-GETSTARTPOINT ent)))
  (SETQ EndPa (VLAX-CURVE-GETENDPARAM ent))
  (SETQ CurPa 0)
  (REPEAT 500
    (SETQ ptlst (CONS (VLAX-CURVE-GETPOINTATPARAM
ent
(SETQ CurPa (+ CurPa (* EndPa 0.002)))
      )
      ptlst
)
    )
  )
  (SETQ MaxPts (MaxDist ptlst))
  ;;Major Line
  (COMMAND "line"
   (TRANS (CAR MaxPts) 0 2)
   (TRANS (CADR MaxPts) 0 2)
   ""
  )
  (SETQ lst nil)
  (FOREACH item ptlst
    (SETQ lst (CONS (LIST (PtOnLine (TRANS (CAR MaxPts) 0 2)
    (TRANS (CADR MaxPts) 0 2)
    (TRANS item 0 2)
  )
  item
    )
    lst
      )
    )
  )
  (SETQ lst (VL-SORT lst
     (FUNCTION (LAMBDA (p1 p2) (< (CAR p1) (CAR p2))))
    )
  )
  ;;Minor Axis
  (COMMAND "line"
   (TRANS (CADAR lst) 0 2)
   (TRANS (CADR (LAST lst)) 0 2)
   ""
  )
)

(DEFUN MaxDist (pts / pt dist maxd maxl)
  (SETQ maxd 0)
  (WHILE (SETQ pt  (CAR pts)
       pts (CDR pts)
)
    (FOREACH item pts     
      (COND ((< maxd (SETQ dist (DISTANCE item pt)))
     (SETQ maxd dist
   maxl (LIST pt item dist)
     )
    )
      )
    )
  )
  maxl
)

(defun PtOnLine (p1 p2 p3 / p c)
  (setq p p3)
  (apply '+
(mapcar '(lambda (b)
    (setq c (- (* (car p) (cadr b)) (* (cadr p) (car b)))
  p b
    )
    c
  )
(list p1 p2 p3)
)
  )
)
Title: Re: How to get bigger and smaller distance
Post by: Adesu on March 07, 2007, 01:44:26 AM
Hi fools ,
Wow........it's fantastic and great.
Thanks a milions.
Title: Re: How to get bigger and smaller distance
Post by: ElpanovEvgeniy on March 07, 2007, 02:08:41 AM

Hi fools!
Your program finds not the smallest external container...
Title: Re: How to get bigger and smaller distance
Post by: fools on March 07, 2007, 02:52:31 AM
 :-) HI  Evgeniy , you are right!
The minor axis isn't the smallest external container.
Because I got the major axis, I want to draw a line perpendicular to it.
It's only for make a rectangle,not the smallest external container.

Title: Re: How to get bigger and smaller distance
Post by: Adesu on March 07, 2007, 07:01:15 PM
:-) HI  Evgeniy , you are right!
The minor axis isn't the smallest external container.
Because I got the major axis, I want to draw a line perpendicular to it.
It's only for make a rectangle,not the smallest external container.



I'm not yet understand,how you both create a drawing rectangular out from object.
Title: Re: How to get bigger and smaller distance
Post by: fools on March 13, 2007, 07:50:26 AM
I'm not yet understand,how you both create a drawing rectangular out from object.
The rectangular isn't made by my code.I draw it after got the four points.
Title: Re: How to get bigger and smaller distance
Post by: Adesu on March 13, 2007, 07:52:27 PM
I'm not yet understand,how you both create a drawing rectangular out from object.
The rectangular isn't made by my code.I draw it after got the four points.

Oh....I see,my question now become clear,thanks for your info.
Title: Re: How to get bigger and smaller distance
Post by: zemleroi on March 19, 2007, 02:04:53 PM
Hello

When I try to use this code on a 3-dimensional polyline (a polyline on an inclined plane: see attached file), the function gives the size of the bounding box with 3 dimensions. Is it possible to measure a two dimensional bounding box on the plane that the object is on?

Dmitri

Code: [Select]
(defun c:test (/ E LST MA MI)
 (if (setq e (car (entsel "\n Select object: ")))
  (progn (setq e   (vla-copy (vlax-ename->vla-object e))
               lst nil
         ) ;_  setq
         (repeat 1000
          (vla-GetBoundingBox e 'mi 'ma)
          (setq
           lst (cons (mapcar (function -) (vlax-safearray->list ma) (vlax-safearray->list mi))
                     lst
               ) ;_  cons
          ) ;_  setq
          (vla-rotate e (vlax-3d-point 0. 0.) (/ pi 1000.))
         ) ;_  repeat
         (vla-Delete e)
   (princ "\n Bounding box object with minimal length: ")
   (princ (assoc (car (apply 'mapcar (cons 'min lst))) lst))
   (princ)
  ) ;_  progn
 ) ;_  if
) ;_  defun

test function:
Code: [Select]
Command: test
 Select object:
 Bounding box object with minimal length: (2427.69 12609.7 13950.0)
[/quote]
Title: Re: How to get bigger and smaller distance
Post by: gile on March 19, 2007, 04:15:12 PM
Hi,

Vla-getBoundingBox always returns the bounding-box about WCS.
I wrote a routine to draw the bounding-box of an object about current UCS (see attached file)
Adapted from it here's one to get the coordinates of the bounding-box of a 2D object about its OCS (if different from WCS)
Thanks again to Doug Broad for matrix handling

Edit: change 'norm' from variable to argument.

Code: [Select]
(defun OCS-Bbox (obj norm / minpt maxpt)
  (vl-load-com)
  (vla-TransformBy
    obj
    (vlax-Tmatrix
      (append
(mapcar
  '(lambda (v o)
     (append (trans v norm 0 t) (list o))
   )
  (list '(1 0 0) '(0 1 0) '(0 0 1))
  (trans '(0 0 0) 0 norm)
)
(list '(0 0 0 1))
      )
    )
  )
  (vla-getBoundingBox obj 'minpt 'maxpt)
  (vla-TransformBy
    obj
    (vlax-tmatrix
      (append
(mapcar
  '(lambda (vector origin)
     (append (trans vector 0 norm t) (list origin))
   )
  (list '(1 0 0) '(0 1 0) '(0 0 1))
  (trans '(0 0 0) norm 0)
)
(list '(0 0 0 1))
      )
    )
  )
  (list (vlax-safearray->list minpt)
(vlax-safearray->list maxpt)
  )
)
Title: Re: How to get bigger and smaller distance
Post by: CAB on March 20, 2007, 11:19:08 AM
Gile,
I was trying to get this to work with your routine but the spline has no Normal property.
Did i miss something?

Code: [Select]
(defun c:test (/ E LST MA MI cnt ang)
  (if (setq e (car (entsel "\n Select object: ")))
    (progn
      (setq e   (vla-copy (vlax-ename->vla-object e))
            cnt 1000
            ang (/ pi cnt)
      )
      (repeat cnt
        (setq lst (cons (OCS-Bbox e) lst))
        (vla-rotate e (vlax-3d-point 0. 0.) ang)
      )
      (vla-delete e)
      (princ "\n Bounding box object with minimal length: ")
      (princ (assoc (car (apply 'mapcar (cons 'min lst))) lst))
      (princ)
    )
  )
)
Title: Re: How to get bigger and smaller distance
Post by: gile on March 20, 2007, 01:40:24 PM
Hi,

Quote
the spline has no Normal property.

Here's a way to get the Normal of a planar spline.

Code: [Select]
;;; Ang<2pi Returns the angle between 0 and 2*pi

(defun ang<2pi (ang)
  (if (and (<= 0 ang) (< ang (* 2 pi)))
    ang
    (ang<2pi (rem (+ ang (* 2 pi)) (* 2 pi)))
  )
)

;;; Clockwisep Returns T if p1 p2 et p3 are turning clockwise

(defun Clockwisep (p1 p2 p3)
  (< pi (ang<2pi (- (angle p2 p3) (angle p1 p2))) (* 2 pi))
)

;;; NORM_3PTS returns the normal vector of a 3 points defined plane

(defun norm_3pts (org xdir ydir)
  ((lambda (n)
     (if (inters org xdir org ydir)
       (mapcar '(lambda (x) (/ x (distance '(0 0 0) n))) n)
     )
   )
    ((lambda (x y)
       (list (- (* (cadr x) (caddr y))
(* (caddr x) (cadr y))
     )
     (- (* (caddr x) (car y))
(* (car x) (caddr y))
     )
     (- (* (car x) (cadr y))
(* (cadr x) (car y))
     )
       )
     )
      (mapcar '- xdir org)
      (mapcar '- ydir org)
    )
  )
)


;; GetSplineNormal Returns the Normal vector of a planar spline (ename or vla-object)

(defun getSplineNormal (spline / len p1 p2 p3)
  (if (= (type spline) 'ENAME)
    (setq spline (vlax-ename->vla-object spline))
  )
  (if (and
(= (vla-get-ObjectName spline) "AcDbSpline")
(= (vla-get-IsPlanar spline) :vlax-true)
(setq len (vlax-curve-getDistAtParam
    spline
    (vlax-curve-getEndParam spline)
  )
)
(setq p1 (vlax-curve-getStartPoint spline))
(setq p2 (vlax-curve-getPointAtDist spline (* len 0.25)))
(setq p3 (vlax-curve-getPointAtDist spline (* len 0.5)))
      )
    (if (clockwisep p1 p2 p2)
      (Norm_3pts p1 p3 p2)
      (Norm_3pts p1 p2 p3)
    )
  )
)
Title: Re: How to get bigger and smaller distance
Post by: zemleroi on March 22, 2007, 09:10:32 PM
I am sorry, I am not sure how to incorporate this code into the "test" routine by Yevgeni Elpanov that measures the bounding box... Could you help me, please?

Dimitri
Title: Re: How to get bigger and smaller distance
Post by: gile on March 23, 2007, 05:35:54 PM
Hi,

Here's a way to use it.
OCS-Bbox have to be loaded too (I edited it)

Code: [Select]
(defun c:test (/ E LST MA MI NO BB)
 (if (setq e (car (entsel "\n Select object: ")))
  (progn (setq e   (vla-copy (vlax-ename->vla-object e))
               lst nil
         ) ;_  setq
   (if (and (= (vla-get-ObjectName e) "AcDbSpline")
    (setq no (getSplineNormal e))
    (not (equal no '(0 0 1) 1e-9))
       )
     (repeat 1000
       (setq bb (ocs-bbox e no)
     lst (cons (mapcar (function -) (cadr bb) (car bb)) lst)
       )
       (vla-rotate3d e (vlax-3d-point 0. 0.) (vlax-3d-point no) (/ pi 1000.))
     )
     (repeat 1000
       (vla-GetBoundingBox e 'mi 'ma)
       (setq
lst (cons (mapcar (function -)
   (vlax-safearray->list ma)
   (vlax-safearray->list mi)
   )
   lst
     ) ;_  cons
       ) ;_  setq
       (vla-rotate e (vlax-3d-point 0. 0.) (/ pi 1000.))
     ) ;_  repeat
   ) ;_  if
         (vla-Delete e)
   (princ "\n Bounding box object with minimal length: ")
   (princ (assoc (car (apply 'mapcar (cons 'min lst))) lst))
   (princ)
  ) ;_  progn
 ) ;_  if
) ;_  defun
Title: Re: How to get bigger and smaller distance
Post by: sinc on March 23, 2007, 06:00:11 PM
Here's a way to get the Normal of a planar spline.

You can also just use vlax-curve-FirstDeriv, and then add or subtract 90°.  The first deriv is a direction vector that indicates the direction of the spline at any point.
Title: Re: How to get bigger and smaller distance
Post by: gile on March 24, 2007, 04:19:43 AM
Quote
You can also just use vlax-curve-FirstDeriv, and then add or subtract 90°.  The first deriv is a direction vector that indicates the direction of the spline at any point.

My explaination shouldn't be clear (excuse my English).
I was meaning the 'Plane Normal' of a planar spline (its extrusion direction).
It's needed to built matrices in OCS-Bbox.
OCS-Bbox returns a  list : MinPoint and MaxPoint of the "BoundingBox" of an object about a coordinates system defined by a Normal vector different from (0.0 0.0 1.0)

(http://xs113.xs.to/xs113/07126/SplineNormal.png)
Title: Re: How to get bigger and smaller distance
Post by: gile on March 24, 2007, 06:32:24 AM
Another version of Evgeny's Test routine.

Works only with objects for which the Normal property is available (2D objects as arcs, ellipses, lwpolylines, texts or mtexts, block references, and so on...) or planar splines.
The result is returned about object plane.
Note: ang<2pi, Clockwisep, Norm_3pts, GetSplineNormal and OCS-Bbox have to be loaded (see upper replies)

Code: [Select]
(defun c:test (/ E LST MA MI NO BB)
  (if (setq e (car (entsel "\n Select object: ")))
    (progn
      (setq e (vla-copy (vlax-ename->vla-object e))
    lst nil
      ) ;_  setq
      (if (vlax-property-available-p e 'Normal)
(setq no (vlax-get e 'Normal))
(if (and (= (vla-get-ObjectName e) "AcDbSpline")
(= (vla-get-IsPlanar e) :vlax-true)
    ) ;_  and
  (setq no (getSplineNormal e))
) ;_  if
      ) ;_  if
      (if no
(progn
  (repeat 1000
    (setq bb  (ocs-bbox e no)
  lst (cons (mapcar (function -) (cadr bb) (car bb)) lst)
    ) ;_  setq
    (vla-rotate3d
      e
      (vlax-3d-point 0. 0.)
      (vlax-3d-point no)
      (/ pi 1000.)
    )
  ) ;_  repeat
  (princ "\n Bounding box object with minimal length: ")
  (princ (assoc (car (apply 'mapcar (cons 'min lst))) lst))
)
(princ "\n No Normal property for this object.")
      ) ;_  if
      (vla-Delete e)
      (princ)
    ) ;_  progn
  ) ;_  if
) ;_  defun
Title: Re: How to get bigger and smaller distance
Post by: zemleroi on March 24, 2007, 02:09:11 PM
The objects I have are closed polylines. I tried converting them to lwpolylines (using convertpoly), but the code still returns:

Command: test
 Select object: ; error: no function definition: OCS-BBOX

I am attaching a sample file with objects I am trying to measure.
Title: Re: How to get bigger and smaller distance
Post by: gile on March 24, 2007, 02:56:13 PM
Hi

The code works with 2dPolylines (Normal Property is available).
OCS-BBOX routine have to be loaded, see « Reply #28 on: March 19, 2007, 03:15:12 pm » in this topic.

I tried with your drawing :
Quote
Commande: test

 Select object:
 Bounding box object with minimal length: (18681.5 23614.6 0.0)

Commande:
Commande:
TEST
 Select object:
 Bounding box object with minimal length: (21359.3 21691.1 0.0)

Commande:
Commande:
TEST
 Select object:
 Bounding box object with minimal length: (17524.6 23726.3 0.0)

Here's the complete set :

Code: [Select]
(defun c:test (/ E LST MA MI NO BB)
  (if (setq e (car (entsel "\n Select object: ")))
    (progn
      (setq e (vla-copy (vlax-ename->vla-object e))
    lst nil
      ) ;_  setq
      (if (vlax-property-available-p e 'Normal)
(setq no (vlax-get e 'Normal))
(if (and (= (vla-get-ObjectName e) "AcDbSpline")
(= (vla-get-IsPlanar e) :vlax-true)
    ) ;_  and
  (setq no (getSplineNormal e))
) ;_  if
      ) ;_  if
      (if no
(progn
  (repeat 1000
    (setq bb  (ocs-bbox e no)
  lst (cons (mapcar (function -) (cadr bb) (car bb)) lst)
    ) ;_  setq
    (vla-rotate3d
      e
      (vlax-3d-point 0. 0.)
      (vlax-3d-point no)
      (/ pi 1000.)
    )
  ) ;_  repeat
  (princ "\n Bounding box object with minimal length: ")
  (princ (assoc (car (apply 'mapcar (cons 'min lst))) lst))
)
(princ "\n No Normal property for this object.")
      ) ;_  if
      (vla-Delete e)
      (princ)
    ) ;_  progn
  ) ;_  if
) ;_  defun

;;; Ang<2pi Returns the angle between 0 and 2*pi

(defun ang<2pi (ang)
  (if (and (<= 0 ang) (< ang (* 2 pi)))
    ang
    (ang<2pi (rem (+ ang (* 2 pi)) (* 2 pi)))
  )
)

;;; Clockwisep Returns T if p1 p2 et p3 are turning clockwise

(defun Clockwisep (p1 p2 p3)
  (< pi (ang<2pi (- (angle p2 p3) (angle p1 p2))) (* 2 pi))
)

;;; NORM_3PTS returns the normal vector of a 3 points defined plane

(defun norm_3pts (org xdir ydir)
  ((lambda (n)
     (if (inters org xdir org ydir)
       (mapcar '(lambda (x) (/ x (distance '(0 0 0) n))) n)
     )
   )
    ((lambda (x y)
       (list (- (* (cadr x) (caddr y))
(* (caddr x) (cadr y))
     )
     (- (* (caddr x) (car y))
(* (car x) (caddr y))
     )
     (- (* (car x) (cadr y))
(* (cadr x) (car y))
     )
       )
     )
      (mapcar '- xdir org)
      (mapcar '- ydir org)
    )
  )
)


;; GetSplineNormal Returns the Normal vector of a planar spline (ename or vla-object)

(defun getSplineNormal (spline / len p1 p2 p3)
  (if (= (type spline) 'ENAME)
    (setq spline (vlax-ename->vla-object spline))
  )
  (if (and
(= (vla-get-ObjectName spline) "AcDbSpline")
(= (vla-get-IsPlanar spline) :vlax-true)
(setq len (vlax-curve-getDistAtParam
    spline
    (vlax-curve-getEndParam spline)
  )
)
(setq p1 (vlax-curve-getStartPoint spline))
(setq p2 (vlax-curve-getPointAtDist spline (* len 0.25)))
(setq p3 (vlax-curve-getPointAtDist spline (* len 0.5)))
      )
    (if (clockwisep p1 p2 p2)
      (Norm_3pts p1 p3 p2)
      (Norm_3pts p1 p2 p3)
    )
  )
)

;;; Returns a list (max and min points of the bounding-box
;;; of an object about a plane defined by its normal)

(defun OCS-Bbox (obj norm / minpt maxpt)
  (vl-load-com)
  (vla-TransformBy
    obj
    (vlax-Tmatrix
      (append
(mapcar
  '(lambda (v o)
     (append (trans v norm 0 t) (list o))
   )
  (list '(1 0 0) '(0 1 0) '(0 0 1))
  (trans '(0 0 0) 0 norm)
)
(list '(0 0 0 1))
      )
    )
  )
  (vla-getBoundingBox obj 'minpt 'maxpt)
  (vla-TransformBy
    obj
    (vlax-tmatrix
      (append
(mapcar
  '(lambda (vector origin)
     (append (trans vector 0 norm t) (list origin))
   )
  (list '(1 0 0) '(0 1 0) '(0 0 1))
  (trans '(0 0 0) norm 0)
)
(list '(0 0 0 1))
      )
    )
  )
  (list (vlax-safearray->list minpt)
(vlax-safearray->list maxpt)
  )
)[code]
[/code]
Title: The routine is working now
Post by: zemleroi on March 24, 2007, 09:38:39 PM
Giles!

Je vous remercie, le script fonctionne très bien maintenant.

Dimitri
Title: Re: How to get bigger and smaller distance
Post by: Kerry on March 24, 2007, 10:04:07 PM
zemleroi, and others generally

Please don't change the Subject title .. it confuses old people like me :-)

Title: Re: How to get bigger and smaller distance
Post by: zemleroi on March 24, 2007, 10:21:28 PM
Sorry.