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))