Creating polyline with a right angle

Creating polyline with a right angle

Browning_Zed
Advocate Advocate
3,009 Views
10 Replies
Message 1 of 11

Creating polyline with a right angle

Browning_Zed
Advocate
Advocate

Hi,

Is there a lisp with which can draw a polyline with a right angle snapping to existing primitives? About the same as it was done in Lee Mac's 3-Point Rectangle program, but instead of a rectangle, a polyline should be built. As an example: there are several points. The first segment of the polyline is drawn relative to any two points. All other segments of the polyline will be built relative to the first segment at an angle of 90 or 180 degrees, while the direction of drawing can be set using snapping to other primitives. Like as shown in the video.

0 Likes
Accepted solutions (1)
3,010 Views
10 Replies
Replies (10)
Message 2 of 11

dlanorh
Advisor
Advisor

What video 🤔

I am not one of the robots you're looking for

0 Likes
Message 3 of 11

doaiena
Collaborator
Collaborator

Is this the functionality, you are looking for.

(defun c:test ( / p0 p1 ang lastSeg ptList nextPt)

(if (and (setq p0 (getpoint "\nPick first point")) (setq p1 (getpoint "\nPick second point")))
(progn

(setq ang (angle p0 p1))
(setq lastSeg (list p0 p1))
(setq ptList lastSeg)

(while (setq nextPt (getpoint "\nPick next point"))

(setq nextPt (inters (cadr lastSeg) (polar (cadr lastSeg) (- ang (/ pi 2)) 100)
		     nextPt (polar nextPt ang 100) nil))

(setq ptList (append ptList (list nextPt)))
(setq lastSeg (append (cdr lastSeg) (list nextPt)))
(setq ang (apply 'angle lastSeg))
);while

(entmake (append (list (cons 0 "LWPOLYLINE")
		       (cons 100 "AcDbEntity")
		       (cons 100 "AcDbPolyline")
		       (cons 90 (length ptList))
		       (cons 70 0))
		 (mapcar (function (lambda (p) (cons 10 p))) ptList)))
))

(princ)
);defun
Message 4 of 11

Browning_Zed
Advocate
Advocate

Thanks, this is what I need. Is it possible that a line is displayed during the drawing process?

0 Likes
Message 5 of 11

doaiena
Collaborator
Collaborator

Something like this?

(defun c:test ( / p0 p1 ang lastSeg ptList nextPt)

(if (and (setq p0 (getpoint "\nPick first point")) (setq p1 (getpoint p0 "\nPick second point")))
(progn

(command "pline" p0 p1)
(setq ang (angle p0 p1))
(setq lastSeg (list p0 p1))

(while (setq nextPt (getpoint "\nPick next point"))

(setq nextPt (inters (cadr lastSeg) (polar (cadr lastSeg) (- ang (/ pi 2)) 100)
		     nextPt (polar nextPt ang 100) nil))
(command nextPt)
(setq lastSeg (append (cdr lastSeg) (list nextPt)))
(setq ang (apply 'angle lastSeg))
);while

(command)
))

(princ "Done!")
(princ)
);defun
0 Likes
Message 6 of 11

Browning_Zed
Advocate
Advocate

Yes, lines like this. But in the last lisp version, such a line appears only when drawing the first segment, and then disappears. I need such lines to be displayed along the entire path of the polyline. Also in the first lisp version, polyline is not drawn at points primitives having different z-coordinates.

0 Likes
Message 7 of 11

Kent1Cooper
Consultant
Consultant

@Browning_Zed wrote:

.... in the first lisp version, polyline is not drawn at points primitives having different z-coordinates.


That raises the question in my mind -- do you want  it to follow different Z coordinates?  If so, you can't do it with a PLINE command, but would need 3DPOLY, and then what would the concept of a right angle mean?  What looks  like a right angle from the point of view of the current viewing direction?  It won't always be one in absolute terms.  And it couldn't use simple (polar) functions, whose results are projected onto the current construction plane, though it could presumably use them to get some  of the coordinates of a next point.

Kent Cooper, AIA
0 Likes
Message 8 of 11

Browning_Zed
Advocate
Advocate

Follow the Z coordinates is not necessary. It is enough that the polyline was placed at zero Z coordinate.

0 Likes
Message 9 of 11

doaiena
Collaborator
Collaborator
Accepted solution

Try out this one

(defun c:test ( / p0 p1 osm ang lastSeg ptList nextPt)

(if (and (setq p0 (getpoint "\nPick first point")) (setq p1 (getpoint p0 "\nPick second point")))
(progn

(setq osm (getvar "osmode"))
(setq ang (angle (setq p0 (list (car p0) (cadr p0) 0.0)) (setq p1 (list (car p1) (cadr p1) 0.0))))
(setq lastSeg (list p0 p1))
(command "pline" p0 p1)

(while (setq nextPt (getpoint (cadr lastSeg) "\nPick next point"))

(setq nextPt (list (car nextPt) (cadr nextPt) 0.0))
(setq nextPt (inters (cadr lastSeg) (polar (cadr lastSeg) (- ang (/ pi 2)) 100)
		     nextPt (polar nextPt ang 100) nil))

(setvar "osmode" 0)
(command nextPt)
(setvar "osmode" osm)
(setq lastSeg (append (cdr lastSeg) (list nextPt)))
(setq ang (apply 'angle lastSeg))
);while

(command)
))

(princ "Done!")
(princ)
);defun
Message 10 of 11

Browning_Zed
Advocate
Advocate

Thank you so much! This is what I needed.

0 Likes
Message 11 of 11

Kent1Cooper
Consultant
Consultant

Another way [lightly tested]:

(defun C:PLOD ; = PolyLine at Orthogonal Directions [relative to 1st segment]
  (/ svn svv pl pt1 pt2)
  (setq
    svn '(orthomode ucsfollow peditaccept osnapz); System Variable Names
    svv (mapcar 'getvar svn); System Variable Values
  ); setq
  (mapcar 'setvar svn '(0 0 1 1))
    ; turn off Ortho & UCS following, accept Lines in Pedit, force to Z=0
  (command
    "_.pline" pause pause ""
    "_.ucs" "_object" "_last"
    "_.ortho" "_on" ; for rubber-band lines & Change command
  ); command
  (setq pl (entlast))
  (while
    (setq pt2
      (getpoint
        (setq pt1 (trans (vlax-curve-getEndPoint pl) 0 1))
        "\nNext reference point: "
      ); getpoint
    ); setq
    (command
      "_.line" "_none" pt1 "_none" pt2 "" ; needs to be Line for next command:
      "_.change" "_last" "" pt2 ; make it orthogonal in current UCS
      "_.pedit" pl "_join" "_last" "" ""
    ); command
  ); while
  (command "_.ucs" "_previous")
  (mapcar 'setvar svn svv); reset
  (princ)
); defun

A couple of differences from @doaiena 's latest:

The "rubber-banding" when asking for a next point [after the 1st segment] is always orthogonal ;

If the next point is more in the direction of a continuation of the previous direction than perpendicular to that, it uses the continuation direction [I'm not sure whether your intent was always for each segment to be perpendicular  to the previous one, regardless of geometric relationship, or simply to be orthogonal  relative to it].

 

[It could use the addition of *error* handling to ensure that the System Variables get reset, and maybe some other typical enhancements.]

 

Kent Cooper, AIA