Author Topic: Point inside a closed polyline, joining splines  (Read 3209 times)

0 Members and 1 Guest are viewing this topic.

jaiganesh

  • Guest
Point inside a closed polyline, joining splines
« on: September 19, 2009, 08:04:29 AM »
Hi all,
Greetings from a newbie. I have three questions.
 
1. Is there any way to get a point inside a closed polyline / region, just by selecting the polyline / region? (When you offset the polyline by a value, it asks a point on the side to offset- Can this be automated? Centroids don't necessarily be inside - Eg: Boomerang-like sections) AutoCAD does this when you select a region for hatching.- It hatches the inside without you specifying an inside point. How does it do this?
 
2. Any way to get the bounding box of a very random selection of objects. (I thought of making regions out of everything I selected, get the Bounding Box co-ordinates from the massprop command and then exploding the original selection- but how to get the BB co-ordinates of these, let alone the BB of a block?
 
3. Any way of joining a spline with an open polyline? The spline should be divided into a no. of very small straight lines - which is within an user-specified tolerance (possibly by MEASURE command) and the resulting points should be joined to make a spline-like series of lines, which in turn would be joined to the original polyline.
 
Any ideas?
Thanks in advance.

Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: Point inside a closed polyline, joining splines
« Reply #1 on: September 19, 2009, 08:05:52 AM »
Number 2:

Code: [Select]
(defun c:bigbox (/ xlst ylst ss sel doc MiP MaP pts
                   xlst ylst xmin xmax ymin ymax)
  (vl-load-com)
  (if (setq xlst '() ylst '() ss (ssget "_X"))
    (progn
      (vlax-for Obj (setq sel (vla-get-ActiveSelectionSet
                                (setq doc
                                  (vla-get-ActiveDocument
                                    (vlax-get-acad-object)))))
        (vla-getBoundingBox Obj 'MiP 'MaP)
        (setq pts (mapcar 'vlax-safearray->list (list MiP MaP))
              xlst (append (mapcar 'car pts) xlst)
              ylst (append (mapcar 'cadr pts) ylst)))
      (setq xmin (apply 'min xlst) xmax (apply 'max xlst)
            ymin (apply 'min ylst) ymax (apply 'max ylst))
      (vlax-put-property
        (vla-addLightWeightPolyline
          (vla-get-ModelSpace doc)
            (vlax-make-variant
              (vlax-safearray-fill
                (vlax-make-safearray
                  vlax-vbdouble '(0 . 7))
                (list xmin ymin xmin ymax xmax ymax xmax ymin))))
        'Closed :vlax-true)
      (vla-delete sel)))
  (princ))

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Point inside a closed polyline, joining splines
« Reply #2 on: September 19, 2009, 08:52:56 AM »
Hi,

1. You can see this thread

2. A sub routine and a testing example
Code: [Select]
;;; gc:MBoundingBox (gile)
;;; Returns a list of the lower left corner an upper right corner
;;; of the bounding box  of a list of objects
;;;
;;; Argument
;;; OjectList: a list of vla-objects

(defun gc:MBoundingBox (ObjectList / CoordList)
  (foreach o ObjectList
    (vla-getBoundingBox o 'minPt 'maxPt)
    (setq CoordList (cons (vlax-safearray->list minPt)
                          (cons (vlax-safearray->list maxPt) CoordList)
                    )
    )
  )
  (list (apply 'mapcar (cons 'min CoordList))
        (apply 'mapcar (cons 'max CoordList))
  )
)

;; testing function
(defun c:test (/ ss lst pts)
  (vl-load-com)
  (if (ssget)
    (progn
      (vlax-for o (setq ss (vla-get-ActiveSelectionSet
                             (vla-get-ActiveDocument (vlax-get-acad-object))
                           )
                  )
        (setq lst (cons o lst))
      )
      (vla-Delete ss)
      (setq pts (gc:MBoundingBox lst))
      (command "_.rectang" "_non" (car pts) "_non" (cadr pts))
    )
  )
  (princ)
)

3. A2010 provides a spline to pline command, for previous versions there're many LISP you can find which convert a spline into a 'multi staright segment' polyline.
By my side I tried to wrote one which creates a 'multi polyarc segments' polyline to match closer the spline.
The user specify the minimal length for segments.
(I only translated prompts)
Code: [Select]
;; SplineToPline (gile) 10/02/08
;; Crée une polyligne à partir d'une spline.
;; La polyligne est constituée exclusivement de segments en arc de cercle.
;; La longueur de chaque segment est calculée en fonction des changements
;; de courbure de la spline et de la longueur minimale des segments.
;;
;; Arguments
;; spl : le nom d'entité de la spline (ename)
;; seg : la longueur minimale des segments (entier ou réel)

(defun SplineToPline (spl    seg    /    ent   dis nor len    ptg1
      pto1   elv    lsto   deriv1 n loop ptg2   pto2
      deriv2 ang    blst   pl
     )
  (vl-load-com)
  (or *acdoc*
      (setq *acdoc* (vla-get-ActiveDocument (vlax-get-acad-object)))
  )
  (and (= (type spl) 'VLA-OBJECT)
       (setq spl (vlax-vla-object->ename spl)
     ent T
       )
  )
  (setq nor    (cdr (assoc 210 (entget spl)))
len    (vlax-curve-getDistAtParam spl (vlax-curve-getEndParam spl))
seg    (/ len (fix (/ len seg)))
dis    seg
ptg1   (vlax-curve-getPointAtDist spl 0)
pto1   (trans ptg1 0 nor)
elv    (caddr pto1)
lsto   (cons pto1 lsto)
deriv1 (angle '(0 0)
      (trans (vlax-curve-getFirstDeriv
       spl
       (vlax-curve-getParamAtPoint spl ptg1)
     )
     0
     nor
      )
       )
n      0
  )
  (while (< dis len)
    (setq loop T)
    (while loop
      (if (and (< dis len)
       (setq ptg2 (vlax-curve-getPointAtDist spl dis))
       (setq pto2 (trans ptg2 0 nor))
       (equal (- (setq deriv2
(angle
  '(0 0)
  (trans (vlax-curve-getFirstDeriv
   spl
   (vlax-curve-getParamAtPoint spl ptg2)
)
0
nor
  )
)
)
(setq ang (angle pto1 pto2))
      )
      (- ang deriv1)
      0.01
       )
  )
(setq dis (+ dis seg))
(setq loop nil)
      )
    )
    (setq lsto (cons pto2 lsto)
  blst (cons (cons n (tan (/ (- ang deriv1) 2.0))) blst)
  ptg1 ptg2
  pto1 pto2
  deriv1 deriv2
  dis (+ dis seg)
  n (1+ n)
    )
  )
  (setq lsto (cons (trans (vlax-curve-getEndPoint spl) 0 nor) lsto)
blst (cons
       (cons
n
(tan
   (/ (- (angle (cadr lsto) (car lsto))
(angle '(0 0)
(trans
  (vlax-curve-getFirstDeriv
    spl
    (vlax-curve-getParamAtPoint spl ptg1)
  )
  0
  nor
)
)
      )
      2.0
   )
)
       )
       blst
     )
lsto (reverse (mapcar '(lambda (p) (list (car p) (cadr p)))
      (if (vlax-curve-isClosed spl)
(cdr lsto)
lsto
      )
      )
     )
  )
  (setq pl (vlax-invoke
     (vla-get-ModelSpace *acdoc*)
     'addLightWeightPolyline
     (apply 'append lsto)
   )
  )
  (mapcar '(lambda (x) (vla-setBulge pl (car x) (cdr x)))
  blst
  )
  (if (vlax-curve-IsClosed spl)
    (vla-put-Closed pl :vlax-true)
  )
  (vla-put-Normal pl (vlax-3d-point nor))
  (vla-put-Elevation pl elv)
  (vla-getXData (vlax-ename->vla-object spl) "" 'typ 'val)
  (and typ (vla-setXData pl typ val))
  (if (not ent)
    (vlax-vla-object->ename pl)
    pl
  )
)

;; Tan
;; Retourne la tangente de l'angle

(defun tan (a) (/ (sin a) (cos a)))

;; SPL2PL
;; Fonction principale

(defun c:spl2pl (/ spl seg loop)
  (vl-load-com)
  (while (not
   (and
     (setq spl (car (entsel "\nSelect a spline: ")))
     (= (cdr (assoc 0 (entget spl))) "SPLINE")
     (vlax-curve-IsPlanar spl)
   )
)
    (princ "\nSelected object is not a planar spline")
  )
  (setq loop T)
  (while loop
    (initget 7)
    (setq seg (getdist "\nSpecify the minimum length for segments: "))
    (SplineToPline spl seg)
    (initget "Yes No")
    (if (= (getkword "\nKeep the result ? [Yes/No] <Y>: ")
   "No"
)
      (entdel (entlast))
      (setq loop nil)
    )
  )
  (initget "Yes No")
  (if (/= (getkword "\nDelete the spline ? [Yes/No] <Y>: ")
  "No"
      )
    (entdel spl)
  )
  (princ)
)
Speaking English as a French Frog

Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: Point inside a closed polyline, joining splines
« Reply #3 on: September 19, 2009, 09:15:03 AM »
Code: [Select]
(apply 'mapcar (cons 'min...)

^^ Much better than what I had  8-)

Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: Point inside a closed polyline, joining splines
« Reply #4 on: September 19, 2009, 09:37:34 AM »
Would this perhaps be quicker, with one less loop to go through  :-)

Used some of your code  ;-)

Code: [Select]
(defun LM::BBox (ss / i ent MiP MaP ptLst)
  ;; With a lot of code from Gile
  (setq i -1)
  (while (setq ent (ssname ss (setq i (1+ i))))
    (vla-getBoundingBox
      (vlax-ename->vla-object ent) 'MiP 'MaP)
    (setq ptLst (cons (vlax-safearray->list MiP)
                      (cons (vlax-safearray->list MaP) ptLst))))
  (list (apply 'mapcar (cons 'min ptLst))
        (apply 'mapcar (cons 'max ptLst))))


(defun c:test (/ spc ss ptLst)
  (vl-load-com)
  (setq spc (vla-get-ModelSpace
              (vla-get-ActiveDocument
                (vlax-get-acad-object))))
 
  (if (setq ss (ssget))
    (progn
      (setq ptLst (LM::BBox ss))
      (vla-put-Closed
        (vla-addLightWeightPolyline spc
          (vlax-make-variant
            (vlax-safearray-fill
              (vlax-make-safearray
                vlax-VbDouble '(0 . 7))
              (list (caar  ptLst) (cadar  ptLst)
                    (caar  ptLst) (cadadr ptLst)
                    (caadr ptLst) (cadadr ptLst)
                    (caadr ptLst) (cadar  ptLst))))) :vlax-true)))
  (princ))


CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Point inside a closed polyline, joining splines
« Reply #5 on: September 19, 2009, 10:15:12 AM »
Welcome to the Swamp jaiganesh. 8-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Point inside a closed polyline, joining splines
« Reply #6 on: September 19, 2009, 11:16:07 AM »
I put this together the other day after reading the thread Gile linked. I was just curious and wanted to see if it would work. It will give you a point within the pline.
Code: [Select]
(defun AT:PointInsidePline (#Obj / #Offset #PointList)
  (and (eq (type #Obj) 'VLA-OBJECT)
       (setq
         #Offset (car (vlax-safearray->list
                        (vlax-variant-value (vla-offset #Obj -0.000001))
                      ) ;_ vlax-safearray->list
                 ) ;_ car
       ) ;_ setq
       (or (< (vla-get-area #Offset) (vla-get-area #Obj))
           (progn
             (vla-delete #Offset)
             (setq #Offset
                    (car (vlax-safearray->list
                           (vlax-variant-value (vla-offset #Obj 0.000001))
                         ) ;_ vlax-safearray->list
                    ) ;_ car
             ) ;_ setq
           ) ;_ progn
       ) ;_ or
       (setq #PointList (vlax-safearray->list
                          (vlax-variant-value
                            (vla-get-coordinates #Offset)
                          ) ;_ vlax-variant-value
                        ) ;_ vlax-safearray->list
             #PointList (list (car #PointList) (cadr #PointList))
       ) ;_ setq
       (vla-delete #Offset)
  ) ;_ and
  #PointList
) ;_ defun
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

jaiganesh

  • Guest
Re: Point inside a closed polyline, joining splines
« Reply #7 on: September 19, 2009, 12:48:28 PM »
thanks. i am trying to develop a basic cnc lisp (not the ones that converts a polyline to G code), kind of towers, pockets etc. within a region. Also are there any alternatives to the rolling ball theorum used to calculate the "spine" of two open polylines? This, I am asking bcoz I think I have stumbled upon another way to find the "spine" of polylines (works on closed or open polylines) thru multiple offsets. Any ideas and insights?

Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: Point inside a closed polyline, joining splines
« Reply #8 on: September 19, 2009, 01:26:16 PM »
I did something like a "spine" here:

http://www.cadtutor.net/forum/showthread.php?t=40271