Author Topic: How to get bigger and smaller distance  (Read 21390 times)

0 Members and 1 Guest are viewing this topic.

gile

  • Gator
  • Posts: 2505
  • Marseille, France
Re: How to get bigger and smaller distance
« Reply #30 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)
    )
  )
)
Speaking English as a French Frog

zemleroi

  • Guest
Re: How to get bigger and smaller distance
« Reply #31 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

gile

  • Gator
  • Posts: 2505
  • Marseille, France
Re: How to get bigger and smaller distance
« Reply #32 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
Speaking English as a French Frog

sinc

  • Guest
Re: How to get bigger and smaller distance
« Reply #33 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.

gile

  • Gator
  • Posts: 2505
  • Marseille, France
Re: How to get bigger and smaller distance
« Reply #34 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)

Speaking English as a French Frog

gile

  • Gator
  • Posts: 2505
  • Marseille, France
Re: How to get bigger and smaller distance
« Reply #35 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
Speaking English as a French Frog

zemleroi

  • Guest
Re: How to get bigger and smaller distance
« Reply #36 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.

gile

  • Gator
  • Posts: 2505
  • Marseille, France
Re: How to get bigger and smaller distance
« Reply #37 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]
« Last Edit: March 24, 2007, 05:04:41 PM by gile »
Speaking English as a French Frog

zemleroi

  • Guest
The routine is working now
« Reply #38 on: March 24, 2007, 09:38:39 PM »
Giles!

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

Dimitri

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How to get bigger and smaller distance
« Reply #39 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 :-)

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

zemleroi

  • Guest
Re: How to get bigger and smaller distance
« Reply #40 on: March 24, 2007, 10:21:28 PM »
Sorry.