How to draw Pline by giving a total Cumulative length and selecting vertices.

How to draw Pline by giving a total Cumulative length and selecting vertices.

Anonymous
Not applicable
1,259 Views
7 Replies
Message 1 of 8

How to draw Pline by giving a total Cumulative length and selecting vertices.

Anonymous
Not applicable

Hello, everyone.

 

Can anyone help me with this situation that I need to draw a Plines with X length which Pline consists of multiple vertices. I'll give the length X only and will select the vertices manually using a mouse. 

0 Likes
Accepted solutions (2)
1,260 Views
7 Replies
Replies (7)
Message 2 of 8

_gile
Consultant
Consultant
Accepted solution

Hi,

 

You can try this:

 

(defun c:LLP (/ *error* drawSegment drawPline makePline segLen point loop points input gr maxPt dist)

  (defun *error* (msg)
    (and msg
         (/= msg "Function cancelled")
         (prompt (strcat "\nError: " msg))
    )
    (redraw)
    (princ)
  )

  (defun drawPline (points)
    (mapcar
      '(lambda (p1 p2) (grdraw p1 p2 -1))
      points
      (cdr points)
    )
  )

  (defun drawSegment (basePt dragPt segLen)
    (setq maxPt (polar basePt (angle basePt dragPt) segLen))
    (if (< (distance basePt dragPt) segLen)
      (progn
        (grdraw basePt dragPt -1)
        (grdraw dragPt maxPt 8 1)
      )
      (grdraw basePt maxPt -1)
    )
  )

  (defun makePline (points / echo)
    (setq echo (getvar 'cmdecho))
    (setvar 'cmdecho 0)
    (command "_.pline")
    (foreach p (reverse points) (command "_non" p))
    (command "")
    (setvar 'cmdecho echo)
  )

  (defun isValidPoint (str / relative pt)
    (if (= (substr str 1 1) "@")
      (setq relative T
            str      (substr str 2)
      )
    )
    (setq pt (read (strcat "(" (vl-string-translate "," " " str) ")")))
    (if (and (vl-consp pt)
             (< 1 (length pt) 4)
             (vl-every 'numberp pt)
        )
      (if relative
        (mapcar '+ pt (car points))
        pt
      )
    )
  )

  (sssetfirst nil nil)
  (or (numberp *PlineMaxLength*) (setq *PlineMaxLength* 5000.0))
  (if
    (and
      (or
        (and
          (setq segLen (getdist (strcat "\nMaximum length <" (rtos *PlineMaxLength*) ">: ")))
          (setq *PlineMaxLength* segLen)
        )
        (setq segLen *PlineMaxLength*)
      )
      (setq basePt (getpoint "\nFirst point: "))
      (setq points (cons basePt points)
            input  ""
            loop   T
      )
    )
     (progn
       (prompt "\nNext point: ")
       (while
         (and (setq gr (grread T 4 0)) loop)
          (cond
            ((= (car gr) 5)
             (setq point (cadr gr))
             (redraw)
             (drawPline points)
             (drawSegment (car points) point segLen)
            )
            ((= 3 (car gr))
             (setq dist (distance (car points) point))
             (if (< dist segLen)
               (setq points (cons point points)
                     segLen (- segLen dist)
               )
               (progn
                 (makePline (cons maxPt points))
                 (setq loop nil)
               )
             )
            )
            ((or (equal gr '(2 13))
                 (equal gr '(2 32))
                 (= (car gr) 25)
             )
             (cond
               ((= input "")
                (makePline points)
                (setq loop nil)
               )
               ((setq point (isValidPoint input))
                (setq dist (distance (car points) point))
                (if (< dist segLen)
                  (progn
                    (setq points (cons point points)
                          segLen (- segLen dist)
                          input  ""
                    )
                    (prompt "\nNext point: ")
                  )
                  (progn
                    (setq maxPt (polar (car points) (angle (car points) point) segLen))
                    (makePline (cons maxPt points))
                    (setq loop nil)
                  )
                )
               )
               (T
                (prompt (strcat "\n'" input "' is not a valid point.\nNext point: "))
                (setq input "")
               )
             )
            )
            (T
             (if (= (cadr gr) 8)
               (progn
                 (setq input (substr input 1 (1- (strlen input))))
                 (princ (chr 8))
                 (princ (chr 32))
               )
               (setq input (strcat input (chr (cadr gr))))
             )
             (princ (chr (cadr gr)))
            )
          )
       )
     )
  )
  (*error* nil)
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 8

Anonymous
Not applicable

Thanks a lot sir, it is going to save me a lot of time

0 Likes
Message 4 of 8

Anonymous
Not applicable

One small addition if possible that object snapping is not working form the second vertice, prompts only for the first time one only.

0 Likes
Message 5 of 8

ВeekeeCZ
Consultant
Consultant
Accepted solution

Not sure if @_gile want to add to this quickie the snapping feature because its not really easy thing to do...

So I post the link to THIS Lee's routine which use the same approach and snapping is included.

Message 6 of 8

Anonymous
Not applicable

Its ok. Thanks for the help.

0 Likes
Message 7 of 8

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... to draw a Plines with X length which Pline consists of multiple vertices. I'll give the length X only and will select the vertices manually using a mouse. 


Those other routines are great, but:

1.  they are both restricted to line segments only;

2.  neither honors any PLINE options while underway;

3.  the resulting Polyline from Lee Mac's TLPLINE command can't have width at all;

4.  the resulting Polyline from @_gile's LLP command will have width if the PLINEWID System Variable is set beforehand, but only constant width, and you don't see it as you draw, but only afterwards;

5.  TLPLINE honors some Osnap modes if you have them set, but not all [at least not PERpendicular that I usually have set, under my Acad2016 here, though in quick perusal the code looks like it's intended  to honor any];

6.  LLP doesn't honor Osnap modes at all.

7.  TLPLINE doesn't remember your maximum length to offer as default for subsequent use.

 

SO, I came up with the attached PlineMax.lsp with its PLML command [= PolyLine limited to Maximum Length].  It overcomes all those listed limitations.  See the comments at the top of the file.

 

The one thing PLML doesn't  do that both those others do [in different ways] is to show you where the maximum-length end will be [constantly in anticipation in LLP, where you're exceeding it in TLPLINE].  PLML simply ends the command if and when you've met or exceeded the maximum, and if you've exceeded it, takes the end back to that maximum overall length.

 

Many thanks to @CodeDing for the (terpri) suggestion, which got it to work as intended, and to @ВeekeeCZ for another suggestion that may end up in a revision, on this thread.

Kent Cooper, AIA
Message 8 of 8

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

....

Many thanks ... to @ВeekeeCZ for another suggestion that may end up in a revision, on this thread.


That suggestion contained the kernel of what, used in a different way, made the whole routine very much simpler.  Here's the revised version, in which [the main reason for the suggestion] sub-options within the Pline command can all be picked in the prompt [bold-blue abbreviation letter(s)] -- some required typing in the option letter(s) before.

 

Two things I've noticed that don't work as they do outside the routine:  flipping the direction of arc segments under some options by holding Ctrl;  and getting options up in-screen with the keyboard down arrow.

 

{I changed the file name, to differentiate, but not the command name.}

Kent Cooper, AIA
0 Likes