Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Stepping lwpoly with variable run.

22 REPLIES 22
Reply
Message 1 of 23
Strydaris2492
807 Views, 22 Replies

Stepping lwpoly with variable run.

Hi everyone.

 

I am trying to write a LISP that will draw a stepping polyline based on the angle from pt1 to pt2.

Pt1 and pt2 will always be on an angle.

The rise of the polyline should always be above the imaginary line between pt1 and pt2.

The stepping poyline should always be draw at no less than 6" above the red line shown below.

The result when finishing the LISP should look like the image below.

For the most part I have a bunch of the code prepared.

I was thinking about collecting the user selected points in a list, adding 6" to the X value, then using some right angle triangle calculations to get the run, then applying mapcar to calculate the stepping points and adding them to the list.

For the most part this sort of works but I am questioning whether or not this is a good approach to accomplish the task I want.

Right now it seems the more sloped areas I add, the more broken it gets.

I think combining the lists is a bit more difficult than I thought it would be.image.png

 

 

 

 

 

 

 

 

 

 

 

Can anyone help out with some ideas?

22 REPLIES 22
Message 2 of 23
Kent1Cooper
in reply to: Strydaris2492

I think [correct me if I'm wrong] you mean 'adding 6" to the Y value....'  That [I think] establishes the base-line of the "path" of stepping, but is the vertical step height also supposed to be 6"?  Or should the horizontal step length be 6"?  In other words, at an angle not so close to 45° as it looks in your image, should it be stepped as at left or right here?

Kent1Cooper_0-1733168533020.png

Or is there some other criterion for the size of the steps, independent of the 6" general vertical up-shift?

Kent Cooper, AIA
Message 3 of 23

Hi @Kent1Cooper 

The vertical step should always be 6". I might make this a user defined height, but it should be constant throughout.

The horizontal length is the variable, which would be based on the slope of the line.

I have been using this bit of code to determine the steps. Pardon the weird (princ "\n....").... I use them to make sure the lisp is running how I think it should run.

(defun fl_step-calcs (lst / ang2 pi2 hyp dist) ;n int1 int2 step-list ang vert-dist horiz-dist hyp div adj opp pt5 pt6)
    (setq n 0)
    (while (< n (1- (length lst))); Loop through pairs of points in the list
	(setq ang2 (abs (angle (nth n int-list) (nth (1+ n) int-list))))
	(if (and (not (equal ang2 (Degrees->Radians 0 ) 0.001)) (not (equal ang2 (Degrees->Radians 180.0) 0.001)) (not (equal ang2 (Degrees->Radians 360.0) 0.001)))
	    (progn
		(princ "\nSTEPS ")
		(setq tmp-lst '())
		(setq pi2 (/ pi 2.0))
		(setq adj (/ opp (/ (sin ang2) (cos ang2))))
		(setq hyp (sqrt (+ (expt opp 2) (expt adj 2))))
		(setq dist (distance (nth n lst)(nth (1+ n) lst)))
		(setq div (rtos (fix (/ dist hyp)) 2 0))
		(setq vert-dist (- (cadr (nth n lst)) (cadr(nth (1+ n) lst))));x axis Xs should be equal
		(setq vert-lftover (float (- (abs vert-dist) (* (atof div) (abs opp)))))
		(setq horiz-dist (abs (- (car (nth n lst)) (car (nth (1+ n) lst)))));y axis Ys should be equal
		(setq horiz-lftover (float (- (abs horiz-dist) (* (atof div) (abs adj)))))
			(if (and (> ang2 (degrees->radians 0)) (< ang2 (degrees->radians 180)))
				(setq pt4 (nth n lst))
				(setq pt4 (nth (1+ n) lst))
			);_if
	    	(repeat (atoi div)
			(setq pt5 (mapcar '+ pt4 (list 0.0 6.0 0.0)))
			(setq tmp-lst (cons pt5 tmp-lst))
			(setq pt4 pt5)
			(setq pt5 (mapcar '+ pt4 (list adj 0.0 0.0)))
			(setq tmp-lst (cons pt5 tmp-lst))
			(setq pt4 pt5)
		); _repeat
		;;;Maybe removed below to marker
		(setq tmp-lst (cons (polar pt5 (degrees->radians 90) vert-lftover) tmp-lst))
		(setq tmplstlen (1+ n))
		
		(if (and (> ang2 (degrees->radians 0)) (< ang2 (degrees->radians 180)));; if the angle of the 2 points in the list are....
			(progn
			    (princ "\nThis is angled up & Finding the spot in the list")
			    	(if (= new-int-list nil)
					(progn
					;(setq tmplstlen (+ (length tmp-lst) 3))
					(setq new-int-list (add-list-in-list int-list (reverse tmp-lst) tmplstlen))
					);_ progn
					(progn
						(princ "\nEGGS EGGS EGGS")
						(setq tmplstlen (+ tmplstlen (length tmp-lst) ))
						(setq new-int-list (add-list-in-list new-int-list (reverse tmp-lst) tmplstlen)); 2 after 2nd item in list to work properly
					); -progn
				); -if
			); _progn
		    
		    	(progn
			    (princ "\nThis is angled down & find the spot")
			    (if (= new-int-list nil)
				(progn
				    	(princ "\nSTEAK STEAK STEAK")
					;(setq tmplstlen (+ (length tmp-lst) 3))
					(setq new-int-list (add-list-in-list int-list tmp-lst (1+ n)))
				); -progn
				(progn
				    	(princ "\nBACON BACON BACON")
					(setq tmplstlen (+ tmplstlen (length tmp-lst) ))
					(setq new-int-list (add-list-in-list new-int-list tmp-lst tmplstlen)); 2 after 2nd item in list to work properly
				);_progn
			    ); -if
			);_progn
		);_ if
	); _progn
	(princ "\nNO STEPS- Flashing is flat at this section")
); _if
	(setq n (1+ n))
	); _while
	(setq new-int-list (vl-remove nil new-int-list))
    ;(setq new-int-list (add-item-to-list (reverse int-list) tmp-lst n))
    )

 

I feel the section above is a bit of overkill for some reason, but I cant think of another way to approach this.

Basically I need the steps to work in any direction and if the 2 points are flat, just draw the line 6" above the picked points.

Here is the whole piece of code. I was trying something a bit different and trying to keep the actions separated so I can see  what the code is doing better.

I took inspiration on this from the DLine Lisp.

(defun fl_sys ( / );pt1 pt2 pt3 npt1 npt2 npt3 ) ; Set system varibles

	(setq pt-list nil
		  npt-list nil
		  int-list nil
		  fl-inters nil
	      	  new-int-list nil
		  ntp nil
		  npt1 nil
		  npt2 nil
		  npt3 nil
		  int-list nil
		  i nil
		  final-list nil
		  ang nil
		  pt1 nil
		  pt2 nil
		  pt3 nil
		  notfirst nil
	)
	
    (setq flsh_ver "0.5")
	
	;;Check if layers exist, if not create it
	(if (not (tblsearch "Layer" "WD-Flashing"))
		(entmake
			(list (cons 0 "LAYER")
				(cons 100 "AcDbSymbolTableRecord")
				(cons 100 "AcDbLayerTableRecord")
				(cons 2 "WD-Flashing");;Layer Name
				(cons 70 1);;Printable 0=No 1=Yes
				(cons 6 "Continuous");;Linetype
				(cons 62 14);;Colour
				(cons 290 0)
				(list -3 (list "AcAecLayerStandard" '(1000 . "") (cons 1000 "Working Drawing ONLY -Elevation Flashing. Use background colour 255,255,255 in hatching over brick")))
		    )
	    )
    )

 ;;;Settings the system variables and layers	
    (setq lay "WD-Flashing"
		  flsh_osm  (getvar "osmode")
		  flsh_cmde (getvar "cmdecho")
		  flsh_clay  (getvar "clayer")
	  opp 6.0
    ) ;_ setq
	(setvar "clayer" lay)
    (setvar "osmode" 33)
    (setvar "cmdecho" 0)
    (princ (strcat "\nMasonry Flashing, Version " flsh_ver ", (c) 2024-2025 by Richard Peterson. "
	   ) ;_ strcat
    ) ;_ princ
;;; ==================== Set Globals ===========================	
	(if (null global:fl_hgt)
		(setq global:fl_hgt 6)
	)
;;; ==================== End Globals ===========================	
	
	(fl_pt1)
	(fl_pt2)
)

(defun fl_pt1 ( / );Collect the data to start other sub functions.
	(setq temp T
		pt2 T
	)
	(while temp
		(initget "Height Step Undo eXit")
			(setq pt1 (getpoint "\nPick start point for flashing or [flashing Height / Step height / Undo / eXit] "))
			(cond
				((= pt1 "Height")
					(fl_height)
				)
				((= pt1 "Step")
					(fl_step)
				)
				((= pt1 "Undo")
					(princ "\nAll segments already undone. ")
					(setq temp T)
				)
				((= pt1 "eXit")
					(quit)
				)
				((null pt1)
					(if v:stpt
					(setq pt1 v:stpt
						  temp   nil
					) ;_ setq
					(progn
					(princ "\nNo continuation point -- please pick a point. ") ;_ princ
					) ;_ progn
					) ;_ if
				)
				(T
					(setq v:stpt pt1
						  temp	 nil
					) ;_ setq
				)
			) ;_ cond
	) ;_ while
	(setq svdpt1 pt1)
);_ defun

(defun fl_pt2 ( / temp)
	;(setq notfirst T)	
	(while (and pt2 (/= pt2 "eXit"))
		(if (/= pt2 "Quit")
			(progn 
				(initget "Height Step Undo eXit")
				(setq pt2 (getpoint pt1 "\nPick next point or [flashing Height / Step height / Undo / eXit]: "))
			)
		)
		(cond
			((= pt2 "Height")
				(fl_height)
			)
			((= pt2 "Step")
				(fl_step)
			)
			((= pt2 "Undo")
				(fl_undo)
			)
			((= pt2 "eXit")
				(fl_step)
			)
			((= (type pt2) 'list)
				(fl_pt-list);Create the user selected point list
				(fl_npt-list);Create the select point list
				;(fl_inter-list);Creates the intersection list
			)
		) ;_ cond
		(setq pt1 pt2)
		(if (/= pt2 nil)
			(setq pt3 pt2)
		)
	)

	(fl_endcap)
)
		;;;;;;;;; (while (setq pt2 (getpoint pt1 "\nNext Point: "))
		; (setq pt-list (append pt-list (list pt2)))
		; (setq ang (angle pt1 pt2))
		; (setq npt (polar pt1 (degrees->radians 90) (/ 6 (cos ang)))) ;(+ (fl_chgAng ang)) 6))
		; (setq npt-list (append npt-list (list npt)))
		; (fl_pt2lst)
		; (setq pt1 pt2)
	; )	
	; (fl_endpt)
; )

(defun fl_pt-list () ;;; Creates the user selected Point list.
	(if (= (fl_member pt1 pt-list 0.001) nil)
		(setq pt-list (append pt-list (list pt1)))
		(princ "\nPoint ONE is in the list");;;Add an error here to pick a different point
	)
	(if (= (fl_member pt2 pt-list 0.001) nil)
		(setq pt-list (append pt-list (list pt2)))
		(princ "\nPoint TWO is in the list");;;Add an error here to pick a different point
	)		
)

(defun fl_npt-list ( / );; Creates the new points list
	(setq ang (angle pt1 pt2))
	(cond 
		((= svdpt1 pt1)
			(princ "\nThis is the FIRST npt-point")
			(setq npt1 (polar pt1 (Degrees->Radians 90) (abs (/ global:fl_hgt (cos ang))))
				  npt2 (polar pt2 (fl_chgAng ang) global:fl_hgt)
				  npt-list (append npt-list (list npt1))
				  npt-list (append npt-list (list npt2))
				  notfirst T
			)
		)
		((or (= ang (Degrees->Radians 0 )) (= ang (Degrees->Radians 180)) (= ang (Degrees->Radians 360)))
			(princ "\nThis is with the flat")
			(setq npt1 (polar pt1 (fl_chgAng ang) global:fl_hgt)) ;(/ 6 (cos ang))))
			(setq npt2 (polar pt2 (fl_chgAng ang) global:fl_hgt))
			(setq npt-list (append npt-list (list npt1)))
			(setq npt-list (append npt-list (list npt2)))
		)
		((or (/= ang (Degrees->Radians 0 )) (/= ang (Degrees->Radians 180)) (/= ang (Degrees->Radians 360)))
			(princ "\nThis is with an angle")
			(setq npt1 (polar pt1 (fl_chgAng ang) global:fl_hgt)) ;(/ 6 (cos ang))))
			(setq npt2 (polar pt2 (fl_chgAng ang) global:fl_hgt))
			(setq npt-list (append npt-list (list npt1)))
			(setq npt-list (append npt-list (list npt2)))
			;;;;DO I PUT THE STEP CALCS HERE? I DONT THINK SO BUT MAYBE
		)
		((= pt2 nil)
			(princ "\nThis is the END npt-point")
		)
	)
)


(defun fl_inter-list ( lst / );cycle through the npt-list to get the intersections
	(setq int-list (append int-list (list (car npt-list))))
		(if (= i nil)
			(setq i 0)
		)
		(repeat (abs (/ (- (length npt-list) 2) 2));The amount of times this needs to repeat.
			(setq fl-inters (inters (nth i npt-list)(nth (+ i 1) npt-list)(nth (+ i 2) npt-list)(nth (+ i 3) npt-list) nil)
				  int-list (append int-list (list fl-inters))
			)
			(setq i (+ i 2))
		);repeat
	(setq int-list (append int-list (list (last npt-list ))))
	(fl_step-calcs int-list)
);_ defun

(defun fl_step-calcs (lst / ang2 pi2 hyp dist) ;n int1 int2 step-list ang vert-dist horiz-dist hyp div adj opp pt5 pt6)
    (setq n 0)
    (while (< n (1- (length lst))); Loop through pairs of points in the list
	(setq ang2 (abs (angle (nth n int-list) (nth (1+ n) int-list))))
	(if (and (not (equal ang2 (Degrees->Radians 0 ) 0.001)) (not (equal ang2 (Degrees->Radians 180.0) 0.001)) (not (equal ang2 (Degrees->Radians 360.0) 0.001)))
	    (progn
		(princ "\nSTEPS ")
		(setq tmp-lst '())
		(setq pi2 (/ pi 2.0))
		(setq adj (/ opp (/ (sin ang2) (cos ang2))))
		(setq hyp (sqrt (+ (expt opp 2) (expt adj 2))))
		(setq dist (distance (nth n lst)(nth (1+ n) lst)))
		(setq div (rtos (fix (/ dist hyp)) 2 0))
		(setq vert-dist (- (cadr (nth n lst)) (cadr(nth (1+ n) lst))));x axis Xs should be equal
		(setq vert-lftover (float (- (abs vert-dist) (* (atof div) (abs opp)))))
		(setq horiz-dist (abs (- (car (nth n lst)) (car (nth (1+ n) lst)))));y axis Ys should be equal
		(setq horiz-lftover (float (- (abs horiz-dist) (* (atof div) (abs adj)))))
			(if (and (> ang2 (degrees->radians 0)) (< ang2 (degrees->radians 180)))
				(setq pt4 (nth n lst))
				(setq pt4 (nth (1+ n) lst))
			);_if
	    	(repeat (atoi div)
			(setq pt5 (mapcar '+ pt4 (list 0.0 6.0 0.0)))
			(setq tmp-lst (cons pt5 tmp-lst))
			(setq pt4 pt5)
			(setq pt5 (mapcar '+ pt4 (list adj 0.0 0.0)))
			(setq tmp-lst (cons pt5 tmp-lst))
			(setq pt4 pt5)
		); _repeat
		;;;Maybe removed below to marker
		(setq tmp-lst (cons (polar pt5 (degrees->radians 90) vert-lftover) tmp-lst))
		(setq tmplstlen (1+ n))
		
		(if (and (> ang2 (degrees->radians 0)) (< ang2 (degrees->radians 180)));; if the angle of the 2 points in the list are....
			(progn
			    (princ "\nThis is angled up & Finding the spot in the list")
			    	(if (= new-int-list nil)
					(progn
					;(setq tmplstlen (+ (length tmp-lst) 3))
					(setq new-int-list (add-list-in-list int-list (reverse tmp-lst) tmplstlen))
					);_ progn
					(progn
						(princ "\nEGGS EGGS EGGS")
						(setq tmplstlen (+ tmplstlen (length tmp-lst) ))
						(setq new-int-list (add-list-in-list new-int-list (reverse tmp-lst) tmplstlen)); 2 after 2nd item in list to work properly
					); -progn
				); -if
			); _progn
		    
		    	(progn
			    (princ "\nThis is angled down & find the spot")
			    (if (= new-int-list nil)
				(progn
				    	(princ "\nSTEAK STEAK STEAK")
					;(setq tmplstlen (+ (length tmp-lst) 3))
					(setq new-int-list (add-list-in-list int-list tmp-lst (1+ n)))
				); -progn
				(progn
				    	(princ "\nBACON BACON BACON")
					(setq tmplstlen (+ tmplstlen (length tmp-lst) ))
					(setq new-int-list (add-list-in-list new-int-list tmp-lst tmplstlen)); 2 after 2nd item in list to work properly
				);_progn
			    ); -if
			);_progn
		);_ if
	); _progn
	(princ "\nNO STEPS- Flashing is flat at this section")
); _if
	(setq n (1+ n))
	); _while
	(setq new-int-list (vl-remove nil new-int-list))
    ;(setq new-int-list (add-item-to-list (reverse int-list) tmp-lst n))
    )

(defun fl_chgAng (ang / )

	(if (or (and (>= ang (degrees->radians 0)) (< ang (degrees->radians 90)))(and (> ang (degrees->radians 270)) (<= ang (degrees->radians 360))))
		(+ ang 1.5708)
		(- ang 1.5708)
		)
)
		
(defun fl_endcap ()
	(princ "\nThis is the end point cap")
		(if (or (= ang (Degrees->Radians 0 )) (= ang (Degrees->Radians 180)) (= ang (Degrees->Radians 360)))
			(setq npt3 (polar pt3 (fl_chgAng ang) global:fl_hgt )) ;If the section is straight at the end, put a 6" tall flashing at the last point.
			(setq npt3 (polar pt3 (Degrees->Radians 90) (abs (/ global:fl_hgt (cos ang)))));If the section is angled put a straight up piece at the appropriate height
		)
		(if (> (length npt-list) 1)
			(setq npt-list (subst npt3 (last npt-list) npt-list))
			(setq npt-list (append npt-list (list npt3)))
		)
	(fl_inter-list npt-list);Creates the intersection list
    	(if (= new-int-list nil)
		(setq final-list (append pt-list (reverse int-list)))
		(setq final-list (append pt-list (reverse new-int-list)))
	)
	;(lwpoly npt-list)
	;(lwpoly pt-list)
	;(lwpoly int-list)
	;(lwpoly new-int-list)
	(lwpoly final-list)
	(command "-hatch" "_s" (entlast) "" "_p" "_u" "90" "1" "_n" "_co" "" "_t" "255,255,255" "")
	(setvar "osmode" flsh_osm)
    (setvar "cmdecho" flsh_cmde)
	(princ)
)
		
(defun Degrees->Radians	(numberOfDegrees)
  (* pi (/ numberOfDegrees 180.0))
)

;;; ========================================================================
;;; ==================== Start option operations ===========================
;;; ========================================================================

(defun fl_height ()
  	(initget 6)
  	(if (setq fl_hgt (getreal (strcat "\nEnter flashing height <" (rtos global:fl_hgt 2 0) "> : ")))
	  (setq global:fl_hgt fl_hgt)
	  )
);_ defun

;;; ========================================================================
;;; ==================== END option operations =============================
;;; ========================================================================

(defun lwpoly (lst) ; LM's entmake functions
    (entmakex
		(append
			(list
			(cons 0 "LWPOLYLINE")
			(cons 100 "AcDbEntity")
			(cons 100 "AcDbPolyline")
			(cons 90 (length lst))
			(cons 70 1)
			) ;_ list
			(mapcar (function (lambda (p) (cons 10 p))) lst)
			) ;_ append
	) ;_ entmakex
) ;_ defun
	
(defun fl_member (item lst fuzz)
 (if (car lst)
   (if (equal (car lst) item fuzz)
     lst
     (fl_member item (cdr lst) fuzz)
   )
 )
)

(defun add-list-in-list (listOuter listInner after / tmp)
  (if
    (and
      (= (type listOuter) 'LIST)
      (= (type listInner) 'LIST)
      (= (type after) 'INT)
      (not (minusp after))
    ); and
    (progn
      (repeat after
        (setq
          tmp (cons (car listOuter) tmp)
          listOuter (cdr listOuter)
        ); setq
      ); repeat
      (append (reverse tmp) listInner listOuter)
    ); progn
  ); if
); defun

(defun c:flashing () (fl_sys))

 

 

Message 4 of 23

I figured what I would do is create a list with the user selected points. (pt-list)

Then I would create another list 6" above the first. If there is an angle within the list ((pt1 to pt2) and (pt2 to pt3) are on an angle) then find the inters point and create (int-list)

Then create a third list of the steps and add this to the int-list, BUT if I have a second set of steps, thats where things start to break down.

And now I am stuck on what to do next.

Message 5 of 23
Sea-Haven
in reply to: Strydaris2492

This was asked elsewhere will try to find I did start doing something and I used 6" as rise control. 

 

https://www.cadtutor.net/forum/topic/93964-create-stepping-lwpolyline-with-getpoint-along-lines/

 

I just started again easier than trying to fix some ones code. This is where I got to next step was is there a next pt so do end correct and continue onto next pt.

 

SeaHaven_0-1733183871353.png

 

Keep trying to remember to go back to it. In my to do list.

 

Message 6 of 23
Strydaris2492
in reply to: Sea-Haven

Hi @Sea-Haven

 

Yup. I asked over at CadTutor. I usually ask about things in a couple places, especially if I am really stuck. I find there are different locals to each forum. And sometimes ask on one gives different answers from the other.

 

I also appreciate the help on any forum. 

Message 7 of 23

@Kent1Cooper 

 

Also sorry Kent, I missed your question.

The 6" is for the rise only.

It also must work in both directions. pt1 to pt5 OR pt5 to pt1 See image below.

image.png

I have a lot of it figured out, just not sure if there is a better approach.

Someone mentioned using vector for all the points, but I havent done that kind of math since might school (30+ years).

Message 8 of 23

Jus for fun and can be a start...

(defun step ( p_o p_n / res p0 p1)
	(setq res (if (> (cadr p_n) (cadr p_o)) 6.0 -6.0))
	(cond
		((> (abs (- (cadr p_n) (cadr p_o))) (abs res))
			(setq p0 p_o)
			(repeat (fix (/ (- (cadr p_n) (cadr p_o)) res))
				(grdraw p0 (list (car p0) (+ (cadr p0) res)) 3)
				(setq p1 (inters p_o p_n (list (car p0) (+ (cadr p0) res)) (list (+ (car p0) res) (+ (cadr p0) res)) nil))
				(grdraw (list (car p0) (+ (cadr p0) res)) p1 3)
				(setq p0 p1)
			)
			(grdraw p0 (list (car p0) (+ (cadr p0) (- (cadr p_n) (cadr p0)))) 3)
			(grdraw (list (car p0) (+ (cadr p0) (- (cadr p_n) (cadr p0)))) p_n 3)
		)
		(T
			(grdraw p_o (list (car p_o) (cadr p_n)) 3)
			(grdraw (list (car p_o) (cadr p_n)) p_n 3)
		)
	)
)
(defun c:foo ( / p_o key p_n)
	(initget 9)
	(setq p_o (getpoint "\nFirst point: "))
	(princ "\nNext point: ")
	(while (and (setq key (grread T 4 0)) (/= (car key) 3))
		(cond
			((eq (car key) 5)
				(setq p_n (cadr key))
				(redraw)
				(step p_o p_n)
			)
		)
	)
	(prin1)
)
Message 9 of 23

Ha!

CADaSchtroumpf.

I like that and it is a good starting point.

One can almost say its .... POPN' (p_o p_n)

Message 10 of 23
Moshe-A
in reply to: Strydaris2492

@Strydaris2492  hi,

 

check this STEPPING command.

 

enjoy

Moshe

 

(defun c:stepping (/ green_frame _isRangle _geometric _tangent _tread _treadAng stair_run ; local functions
		     RISER pick0 ename0 ename1 elist0 t0 t1 t2 t3 data^ item0 item1 v0 v1 p0 p1)

 (defun green_frame (t0 t1)
  (command "._line" t0 t1 "")
  (command "._chprop" "_si" "_Last" "_Color" 3 "")
 ); green_frame
  
 ; anonymous functions
 (setq _isRangle (lambda (a0) (vl-some (function (lambda (a1) (equal a0 a1 1e-4))) (list 0.0 pi (* pi 0.5) (* pi 1.5))))) 
 ; return tangent of angle
 (setq _tangent (lambda (a0) (/ (sin a0) (cos a0))))

 (defun _geometric (elist / i lst item0 item1 l2)
  (setq i -1)
  (foreach item0 elist
   (setq i (1+ i))
   (if (and
	 (= (car item0) 10)
         (setq item1 (nth (+ i 3) elist))
       )
    (setq lst (cons (list (cdr item0) (cdr item1)) lst))
   )
  ); foreach

  (setq lst (reverse lst))

  (append
   (mapcar
    (function
      (lambda (item0 item1)
       (if (and
	    (= (cadr item0) 0.0)
	    (not (_isRangle (angle (car item0) (car item1))))
	  )
	(append item0 (list :vlax-true))
	(append item0 (list :vlax-false))
       )
      ); lambda
    ); function
    (reverse (cdr (reverse lst))) (cdr lst)
   ); mapcar
   (list (append (last lst) (list :vlax-false))) ; append lat point
  ); append
 ); _geometric
  
 ; return stair tread
 (defun _tread (t0 t1 / a0 a1 a2)
  (setq a0 (/ pi 2))
  (setq a1 (angle t0 t1))

  (if (> a0 a1)
   (setq a2 (- a0 a1))
   (setq a2 (- a1 a0))
  )

  (if (> a2 (* pi 1.5))
   (setq a3 (- (* pi 2) a2))
   (setq a3 a2)
  )
   
  (* (_tangent a3) RISER)
 ); _tread


 (defun _treadAng (t0 t1)
  (if (> (car t1) (car t0)) 0.0 pi)
 ); _treadAng

 (defun stair_run (/ cumulative pad ang)
  (setq cumulative (cadr p0) pad (_tread v0 v1) ang (_treadAng v0 v1))
  (command "._pline" "_none" p0 "_width" 0 0)
  (while (<= (+ cumulative RISER) (cadr v1))
   (setq p1 (polar p0 (/ pi 2) RISER))
   (setq p0 (polar p1 ang pad))
   (command "_none" p1 "_none" p0)
   (setq cumulative (+ cumulative RISER))
  ); while

  ; finish run
  (if (< (cadr p0) (cadr v1))
   (command p0 (list (car p0) (cadr v1)) v1 "")
   (command "")
  ); if
   
  (command "._chprop" "_si" "_Last" "_Color" 3 "")
 ); stair_run
  
 ; here start c:stepping
 (setvar "cmdecho" 0)
 (command "._undo" "_begin")
 (setq RISER 6.0) ; const
  
 (if (and
       (setq pick0 (entsel "\npick pline: "))
       (setq ename0 (car pick0))
       (setq elist0 (entget ename0))
       (eq (cdr (assoc '0 elist0)) "LWPOLYLINE")
       (= (cdr (assoc '70 elist0)) 0)
     )
  (progn
   (setq t0 (vlax-curve-getStartPoint ename0))
   (setq t1 (vlax-curve-getEndPoint ename0))
   (command "._offset" RISER "_none" pick0 "_none" (polar t0 (/ pi 2) RISER) "")
   (setvar "ltscale" 15)
   (command "._chprop" "_si" "_Last" "_LType" "dashed" "")
   (setq ename1 (entlast))

   (command "._chprop" "_si" ename0 "_Color" 1 "")
   (setq t2 (vlax-curve-getStartPoint ename1))
   (setq t3 (vlax-curve-getEndPoint ename1))

   (green_frame t0 t2) ; starting cap
   (green_frame t1 t3) ; closing  cap 

   (setq data^ (_geometric (entget ename1)))
   (setq item0 (car data^) v0 (car item0))

   (foreach item1 (cdr data^)
    (setq v1 (car item1))
    
    (if (= (caddr item0) :vlax-true)
     (cond
      ((and
	 (< (car  v0) (car  v1))
	 (< (cadr v0) (cadr v1))
       )
       (setq p0 v0)
       (stair_run)
      ); case
      ((and
	 (< (car  v0) (car  v1))
	 (< (cadr v1) (cadr v0))
       )
       (setq tmp v0 v0 v1 v1 tmp) ; swap points
       (setq p0 v0)
       (stair_run)
      ); case
     ); cond
     ; else
     (green_frame v0 v1)
    ); if
   
    (setq item0 item1 v0 (car item0))
   ); foreach

   (command "_draworder" "_si" ename1 "_Front") ; bring to front dashed line
  ); progn
 ); if

 (command "._undo" "_end")
 (setvar "cmdecho" 1)
  
 (princ)
); c:stepping

 

 

Message 11 of 23
Moshe-A
in reply to: Strydaris2492

@Strydaris2492 ,

 

Made some fine tuning.

 

Moshe

Message 12 of 23

hey there. mm?)

to work it both ways the lower step should always be full in height or?

Message 13 of 23

Hey Komo,

Ideally it would be great to have the leftovers at the top regardless of direction.

That way the drafter can decide if they want to clean it up in one place or just leave it.

The way how we typically draw this stuff is subjective to the user, but there are some "MUST DOs" as I show in the image above.

I have a few more ideas on how to tackle this, but I wont have time to try them out until next week sometime.

Any other ideas are appreciated.

Message 14 of 23

there is some omega.

komondormrex_0-1734015442814.gif

 

Message 15 of 23

@komondormrex 

You guys never cease to amaze me.

Where did you learn LISP? Is it all self taught or did you learn it in school?

 

That is essentially what I want returned. What the overall goal is to have it draw everything as I pick points along a roof line.

The image below shows a possible order in which the user picks points along the roof line. I added the yellow polyline with thickness just for clarity.

Strydaris2492_0-1734020040629.png

 

After finishing the routine the results would like this for each segment / use of the LISP.

 

Strydaris2492_1-1734020495948.png

 

The straight section in the middle is simple for me. And adding the hatch is easy enough if I use (entlast) into a command call.

I can also seem to get things to work if I have a straight section, then an angle section. Where things start to get weird is when I have more than 1 angle sections.

Message 16 of 23
Sea-Haven
in reply to: Strydaris2492

There is answer in the latest image that I was not sure about in that you match vertically to the segment last point, then the new segment has a full width as a starting point. This will help in working out multi line plines.

 

@komondormrex wow looks great the dynamic version.

Message 17 of 23

Hi @Sea-Haven

Hopefully I can answer your inquiry. 

So imagine the yellow pline being offset 6". This is the minimum distance that is allowed for the stepping part. As the step comes back down it will do its last step down by 6", then do the remainder, which is the length of the hypotenuse of a right angle triangle.

The reason why this is 6" + hyp is that the step comes down then the flashing will wrap around a side of the building.

 

As for Komos work, yes that looks awesome. Correct me if I am wrong but it looks as though you might be using 2 conditions. 1 to draw it one way between 1-179 degrees and to draw it another way from 181 - 359 degrees. 

Message 18 of 23


@Strydaris2492 wrote:

Where things start to get weird is when I have more than 1 angle sections.


that's true. i did not think yet that far as i said it is quick written code. but i really would prefer a dynamic version over say static and i think (and i am fully aware that you want to cut out and fine tune your own version) that algorithm to insert list of vertices into list of vertices is a dead end imho.

Message 19 of 23


@Strydaris2492 wrote:

Correct me if I am wrong but it looks as though you might be using 2 conditions. 1 to draw it one way between 1-179 degrees and to draw it another way from 181 - 359 degrees. 


well yes, in a way. 

Message 20 of 23


@Strydaris2492 wrote:

Where did you learn LISP? Is it all self taught or did you learn it in school?

lisp is a tool to make you cut short tedious laboring routines, so you grab that very tool and make the world brighter.

 


@Strydaris2492 wrote:

That is essentially what I want returned. What the overall goal is to have it draw everything as I pick points along a roof line.


you mean the user will pick points 1-10 (or 10-1) in successive to get that whole selected hatch or there is three hatches selected (whilst the user made three different picks 1-5, 6-7, 8-10?

komondormrex_0-1734072405869.png

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report