line divisions

line divisions

Anonymous
Not applicable
1,092 Views
4 Replies
Message 1 of 5

line divisions

Anonymous
Not applicable

hello everyone,

I have this code:

(defun c:LD  (/ f curlayer curosmode ent exit a b spaces spaces1 testlst vlaobj1 vlaobj2 x y z)
  (while (setq vlaObj1   (vlax-ename->vla-object (setq ent (car (entsel))))
               vlaObj2   (vlax-ename->vla-object (car (entsel)))
               curlayer  (getvar 'clayer)
               curosmode (getvar 'osmode)
               spaces1   (getreal "\nEnter number of spaces: "))
    (cond ((or (minusp spaces1) (< spaces1 1)) "Spaces should be greater than 1")
          (T
           (setvar 'clayer (cdr (assoc 8 (entget ent))))
           (setvar 'osmode 16384)
           (setq spaces  (test spaces1 ())
                 testlst (vl-sort
                           (apply
                             'append
                             (mapcar
                               '(lambda (y)
                                  (mapcar '(lambda (x) (append (append (list (distance x y)) (list x)) (list y)))
                                          (list (vlax-curve-getStartPoint vlaObj1)
                                                (vlax-curve-getEndPoint vlaObj1))))
                               (list (vlax-curve-getStartPoint vlaObj2)
                                     (vlax-curve-getEndPoint vlaObj2))))
                           '(lambda (x y) (< (car x) (car y))))
                 a       (cdar testlst)
                 b       (cdr (apply 'append
                                     (car (mapcar '(lambda (y)
                                                     (mapcar '(lambda (x)
                                                                (if (not (or (equal (cadar testlst) (cadr x) y)
                                                                             (equal (caddar testlst) (caddr x) y)
                                                                             (equal (cadar testlst) (caddr x) y)
                                                                             (equal (caddar testlst) (cadr x) y)))
                                                                  x))
                                                             testlst))
                                                  (list 1e-15))))))
           (command "._undo" "_begin")
           (test2 a b spaces1 spaces)
           (command "._undo" "_end")
           (initget "Yes No")
           (setq f (cond ((getkword "\nFLip lines [Yes/No] <No>: "))
                         ("No")))
           (cond ((wcmatch f "Yes,Y")
                  (command "._undo" 1)
                  (setq z (last a))
                  (setq a (cons (car a) (cdr b)))
                  (setq b (cons (car b) (list z)))
                  (test2 a b spaces1 spaces))
                 (T ())))))
  (setvar 'clayer curlayer)
  (setvar 'osmode curosmode))

(defun test  (x y)
  (cond ((< x 1) y)
        (T (test (fix (- x 1)) (cons (fix x) y)))))

(defun test2  (a b c d)
  (mapcar '(lambda (x y) (command-s "._pline" x y ""))
          (mapcar '(lambda (x) (polar (car a) (angle (car a) (cadr a)) (* (/ (distance (car a) (cadr a)) c) x)))
                  (if (not (zerop (rem c (fix c))))
                    d
                    (cdr (reverse d))))
          (mapcar '(lambda (x) (polar (car b) (angle (car b) (cadr b)) (* (/ (distance (car b) (cadr b)) c) x)))
                  (if (not (zerop (rem c (fix c))))
                    d
                    (cdr (reverse d))))))

It lets the user to pick 2 lines and enter the number of spaces and it makes lines between these two lines.

I want to make some amendments to it:

1. That this lisp will work also if you pick two lines of a rectangle,polyline or 2 xlines. it will devide them to the spaces the user enters , and will create xlines.

2. That it will create xlines instead of lines.

3. That the object snap will change to select all ( means that in Drafting setting when operating this lisp it will set it to select all).

 

Thanks in advance!

Eyal

 

0 Likes
Accepted solutions (1)
1,093 Views
4 Replies
Replies (4)
Message 2 of 5

Kent1Cooper
Consultant
Consultant

That does this kind of thing, given the two white Lines as selected objects, and when asked for 3 spaces, the two yellow Lines as result:

LD-lines.PNG

[The red Points and grey dashed Lines are not drawn by it, but are for discussion below.]

 

[Another routine that does the same, but doesn't  need to ask you whether to reverse them, and also has the option to pick four points rather than existing Line entities, so you can use it with Polyline line segments or any other elements, is SplitBetween.lsp, with its SLB command, >here<.  But it also only draws Lines.]

 

When the existing Lines are not parallel  like this, it divides the virtual Lines between their endpoints [the dashed grey above] into the number of spaces specified, and draws Lines between those virtual point locations [the red Points].  All well and good for Lines, and probably for Polyline line segments, but....

 

If the exsiting objects are Xlines, as the white in the next image, there are no endpoints  to find a virtual line between to divide along.  And you can't count on the location of the Xline's defining points to have any logic relative to the desired result.  It seems the only logical way to do it would be around the intersection  of those Xlines, splitting the angle  between them, with the green Xlines here as the result:

LD-xlines.PNG

The white Xlines are just extensions of the white Lines in the first image into Xlines, the grey Points are where their endpoints in the first image are, and the yellow Lines are the result from the first image, which are obviously in quite different places than the green Xlines.

 

So in a situation like the first image, with selection of non-parallel Lines, but wanting to split the space between them with Xlines, would you want the resulting Xlines to be extensions  of the yellow Lines in the first image into Xlines, which would be like this:

LD-xlines2.PNG

[with the dashed grey to show the Lines' virtual intersection], or to be radiating from the virtual intersection  as in the green Xlines in the second image?

 

For a routine that draws Xlines halfway between virtually any  straight objects or sub-objects, but only one Xline, see Bisector.lsp with its BI command, >here<.  That could presumably be altered to divide into any number of spaces, but when source objects are not parallel, it does it in the manner of the second image [angle-based around the intersection or virtual intersection], so I don't want to modify it for the purpose if that's not the result you would want.

 

The same kind of difference exists in a non-parallel but symmetrical  arrangement, such as this:

LD-xlines3.PNG

I imagine there are other configurations in which exactly what kind of result you want would be questionable.

 

Another thing you can do is to use your routine, and then convert the resulting Lines into Xlines  with RestoreXline.lsp and its REX command, >here<.  That will get you only  the yellow-variety results [where the yellow are Lines, extensions of them into Xlines] in the above images, never the green results.

Kent Cooper, AIA
Message 3 of 5

Anonymous
Not applicable

Thank you very much @Kent1Cooper , for your explanation,

the SplitBetween.lsp , will help me, but I wonder if there is a way to change the code so it will allow to pick two entities of a rectangle, and it will allow to split it for the spaces I want.

 

As you can see Bisector.lsp allow to pick two lines and make a line between them , can you change it so it will let me enter the number of spaces that I want.

Thank you!

Eyal

0 Likes
Message 4 of 5

dbhunia
Advisor
Advisor
Accepted solution

Hi,

 

As you asked ........

 


@Anonymous wrote:

Thank you very much @Kent1Cooper , for your explanation,

the SplitBetween.lsp , will help me, but I wonder if there is a way to change the code so it will allow to pick two entities of a rectangle, and it will allow to split it for the spaces I want.

 

As you can see Bisector.lsp allow to pick two lines and make a line between them , can you change it so it will let me enter the number of spaces that I want.

Thank you!

Eyal


 

I modified @Kent1Cooper "Bisector.LSP" only for parallel lines ...........

 

;;;  Bisector.LSP [Command name: BI]
;;;  To Bisect either:
;;;    1.  the angle between two straight non-parallel drawing entities or sub-entities;
;;;    2.  the distance between two straight parallel drawing entities or sub-entities.
;;;  Draws an Xline bisecting the angle or distance, in the case of angles in the
;;;    direction between picked locations, on the current Layer.
;;;  Kent Cooper, August 2011

(defun C:BI (/ *error* var ev getobj cmde aper)

  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (princ (strcat "\nError: " errmsg))
    ); if
    (setvar 'aperture aper)
    (setvar 'cmdecho cmde)
  ); defun - *error*

  (defun var (typ); build variable name with number
    (read (strcat typ num))
  ); defun - var

  (defun ev (typ); evaluate what's in variable name with number
    (eval (read (strcat typ num)))
  ); defun - ev

  (defun getobj (num / esel edata etype subedata subetype path)
    (while
      (not
        (and
          (setq
            esel (entsel (strcat "\nSelect linear object #" num " for Angle/Spacing Bisector: "))
            edata (if esel (entget (car esel)))
            etype (if esel (cdr (assoc 0 edata)))
          ); setq
          (set
            (var "pick"); = pick1 or pick2
            (osnap (cadr esel) "nea"); for (vlax-curve) later; also prohibits things like text elements of Dimensions
          ); set
          (wcmatch etype "LINE,*POLYLINE,@LINE,RAY,INSERT,HATCH,DIMENSION,LEADER,*SOLID,3DFACE,WIPEOUT,TRACE,REGION,IMAGE,VIEWPORT,TOLERANCE")
          (not (osnap (ev "pick") "cen"))
            ; if Polyline/Block/Region/3DSolid/angular Dimension, not on arc segment or circle/arc element
          (cond
            ((= etype "INSERT")
              (and ; then, use nested object -- same checks as above, except:
                  ; no center Osnap check [earlier check covers it]
                  ; no Insert or heavy Polyline object types [never returned by (nentselp)]
                  ; add Vertex type for heavy Polylines
                (setq
                  subedata (entget (car (nentselp (ev "pick"))))
                  subetype (cdr (assoc 0 subedata))
                ); setq
                (wcmatch subetype "LINE,LWPOLYLINE,VERTEX,@LINE,RAY,HATCH,DIMENSION,LEADER,*SOLID,3DFACE,WIPEOUT,TRACE,REGION,IMAGE,VIEWPORT,TOLERANCE")
                (if (= subetype "LEADER") (= (cdr (assoc 72 subedata)) 0) T); STraight, not Splined
                (if (= subetype "VERTEX") (= (boole 1 8 (cdr (assoc 70 subedata))) 0) T); not Splined 2DPolyline
              ); and
            ); Insert condition
            ((= etype "LEADER") (= (cdr (assoc 72 edata)) 0)); STraight, not Splined
            ((= etype "POLYLINE") (= (boole 1 4 (cdr (assoc 70 edata))) 0)); not Splined 2DPolyline
            (T) ; all other object types
          ); cond
        ); and
      ); not
      (prompt "\nNothing selected, or not a straight object with linearity --")
    ); while
    (if (wcmatch etype "LINE,*POLYLINE,XLINE,RAY"); vlax-curve-applicable types
      (progn ; then
        (setq path (car esel))
        (set
          (var "ang"); = ang1 or ang2
          (angle; then
            '(0 0 0)
            (vlax-curve-getFirstDeriv
              path
              (vlax-curve-getParamAtPoint path (ev "pick"))
            ); 1st deriv
          ); angle
        ); set
      ); progn - then
      (set ; else [other types]
        (var "ang"); = ang1 or ang2
        (angle ; [will return 0 if Ray picked AT end or Xline picked AT origin/midpoint]
          (osnap (ev "pick") (if (= subetype "RAY") "nea" "mid")); account for Ray in Block [no midpoint]
          (osnap (ev "pick") (if (= subetype "XLINE") "nea" "end")); account for Xline in Block [no endpoint]
            ; curiosity: Xlines/Rays in Blocks extend normally on-screen, but cannot be selected
            ; or snapped to beyond some limit slightly outside other finite Block elements.
        ); angle
      ); set - else
    ); if
  ); defun - getobj

  (vl-load-com)
  (setq
    cmde (getvar 'cmdecho)
    aper (getvar 'aperture)
  ); setq
  (setvar 'cmdecho 0)
  (setvar 'aperture (getvar 'pickbox))
  (getobj "1")
  (getobj "2")
  (setvar 'aperture aper)
  (if (or (equal ang1 ang2 1e-8) (equal (abs (- ang1 ang2)) pi 1e-8))
    (progn ; then
      (prompt "\nObjects are parallel; drawing Xline halfway between.")
      (setq NS (getint "\nNumber of Spaces between lines: "))
      (setq LS (/ (distance pick1 pick2) NS))
      (setq ang_1 (angle pick1 pick2))
      (setq P1 pick1)
   (repeat (- NS 1)
      (setq PT2 (polar P1 ang_1 LS))
      (command
        "_.xline"
        "_ang" (* (/ ang1 pi) 180)
	"_none" PT2
        ;"_none" (mapcar '/ (mapcar '+ pick1 pick2) '(2 2 2));;;;;;;;;;;;;;
        ""
      ); command
      (setq P1 PT2)
   )
    ); progn
    (progn ; else - not parallel
      (setq
        appint (inters pick1 (polar pick1 ang1 1) pick2 (polar pick2 ang2 1) nil)
        ang1 (angle appint pick1); both outward [may reverse either or both]
        ang2 (angle appint pick2)
      ); setq
      (command
        "_.xline"
        "_ang" (* (/ (+ ang1 ang2) 2 pi) 180)
        "_none" appint
        ""
      ); command
    ); progn
  ); if
  (setvar 'cmdecho cmde)
  (princ)
); defun
(prompt "\nType BI to draw the Bisector of an angle or parallel-object spacing.")
(princ)

 


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
Message 5 of 5

Anonymous
Not applicable

Good Job @dbhunia Thank you , it will be very helpfull!

Thank you @Kent1Cooper for your help!

 

 

0 Likes