# Thread: Arc Segmenting with Lines to Center

1. ## Arc Segmenting with Lines to Center

Registered forum members do not see this ad.

So I have been searching the forums for a LISP that can divide an arc while adding mortar joints.

The cast stone company I work for manufactures window surrounds and when I draw them, they have to be seperated into equal lengths with a 1/4" mortar joint. Currently what I do is use the DIVIDE command, then a little MLINE macro I wrote drawing an MLINE from the arc node to the center point of said arc.

Back in 2006 a CADTutor.net member (CAB) and again in 2009 (SteveK) helped me in converting a qbasic formula into a LISP that I use for horizontal and vertical pieces, and I was wanting to see if something like that could be created for arc pieces as well.

I have attached an example of a window surround.

2. Also for background, here are the two posts I was referring to for the original development of the LISP.

3. If you take the total arc length put a rule what is maximum stone length user ? then get a number of blocks you should be able to work out arc length = no of joints + block length. Once you have this worked out its pretty easy to convert arclength to chords and draw stone blocks.

Say something like 4 blocks = block length 23" is this ok NO try 5 then draw blocks.

Arclength=rad*theta so can work out lengths etc simple maths chords are simple formula also if not sure just google circular formulas.

4. No real need to do curve calculations. Let the vlax-curve-* functions do that for you. Here's a sample:
Code:
```(vl-load-com)

(setq *SegmentPath:Gap* 0.
*SegmentPath:GapStart* t
*SegmentPath:GapEnd* t
*SegmentPath:MaxLength* 10.)

(defun c:SegmentPath  (/ en space len pos dist)
(setq space (apply (if (> (getvar 'cvport) 1)
'vla-get-ModelSpace
'vla-get-PaperSpace)
(while (progn (princ (strcat "\nGap Size: "
(rtos *SegmentPath:Gap*)
"; Max Length: "
(rtos *SegmentPath:MaxLength*)
"; "
(if *SegmentPath:GapStart*
"Gap at start; "
"")
(if *SegmentPath:GapEnd*
"Gap at end; "
"")))
(initget "Gap Max Start End")
(setq en (entsel "\nPick Path [Gap/Max/Start/End]: ")))
(cond ((eq en "Gap")
(if (setq en (getdist (strcat "\nEnter gap size <" (rtos *SegmentPath:Gap*) ": ")))
(setq *SegmentPath:Gap* en)))
((eq en "Max")
(if (setq en (getdist (strcat "\nEnter max length <" (rtos *SegmentPath:MaxLength*) ": ")))
(setq *SegmentPath:MaxLength* en)))
((eq en "Start") (setq *SegmentPath:GapStart* (not *SegmentPath:GapStart*)))
((eq en "End") (setq *SegmentPath:GapEnd* (not *SegmentPath:GapEnd*)))
(t
(setq en  (car en)
len (vlax-curve-getDistAtParam en (vlax-curve-getEndParam en))
pos 0.)
(if *SegmentPath:GapStart*
(setq pos *SegmentPath:Gap*)
(setq len (+ len *SegmentPath:Gap*)))
(if *SegmentPath:GapEnd*
(setq len (- len *SegmentPath:Gap*)))
(setq dist (/ len (1+ (fix (/ len (+ *SegmentPath:Gap* *SegmentPath:MaxLength*))))))
(while (< pos len)
space
(vlax-3d-point (vlax-curve-getPointAtDist en pos))
(vlax-3d-point (vlax-curve-getPointAtDist en (+ pos (- dist *SegmentPath:Gap*)))))
(setq pos (+ pos dist))))))
(princ))```
It works on anything, not just arcs, but even polylines / splines.

One prob though, the length is the length along the curve. Not the straight line length. For that you'd need to temporarily create a circle with radius length, then find the intersection along the curve.

5. Try this code just for arc segment:
Code:
```
;;__________________________________________Amort.lsp________________________________________________;;
;; math by Juergen Menzi
(abs (/ (distance p1 p2) 2 (sin (/ (* 4 (atan (abs bulge))) 2))
)
)
)
;;--------------------------------------;;
(defun ang-tangent (curve pnt)
(angle
'(0 0 0)
(trans
(vlax-curve-getFirstDeriv
curve
(vlax-curve-getParamAtPoint curve (trans (vlax-curve-getClosestPointTo curve pnt) 1 0))
)
0 1 T
)
)
)
;;--------------------------------------;;
(defun get-segments (en pnt / par)
(setq par (vlax-curve-getParamAtPoint
en
(vlax-curve-getClosestPointTo en pnt))
)
(list (vlax-curve-getPointAtParam en (fix par))
(vlax-curve-getPointAtParam en (1+ (fix par)))
)
)
;;----------------------- main part ----------------------------;;
(defun C:Amort(/ *error* adoc ang clay curve da en gap i joint leg num p1 p1e p2 par pe1 pe2 pn ps1 ps2 rad segs sset step stleg th)
(defun *error* (msg)
(vla-endundomark (vla-get-activedocument
)
(cond ((or (not msg)
(member msg '("console break" "Function cancelled" "quit / exit abort"))
)
)
((princ (strcat "\nError: " msg)))
)
(setvar "nomutt" 0)
(if clay (setvar "clayer" clay))
(princ)
)

(setq clay (getvar "clayer"))
(setvar "clayer" "Mortar");<-- must be exist
(or *num* (setq *num* 4));<-- hard coded
(setq gap 0.25);<-- hard coded
(setvar "nomutt" 0)
(princ "\nSelect Shortest Arc Segment")
(setvar "nomutt" 1)
(if (setq sset (ssget "_:S:E" '((0 . "*LINE"))))

(progn
(setvar "nomutt" 0)
(setq en (ssname sset 0))
(initget 6)
(setq num (getint (strcat "\nEnter the number of segments <" (rtos *num* 2 0) ">: ")))
(cond (num) ((setq num 4)))
(setq curve (vlax-ename->vla-object en))
(setvar "osmode" 512)
(setq p1 (getpoint "\nPick point on shortest arc segment: "))
(setvar "osmode" 128)
(setq p2 (getpoint p1 "\nPick point on longest arc segment: "))
(setq joint (distance p1 p2))
(setq p1e (vlax-curve-getclosestpointto curve p1))
(setq par (fix (vlax-curve-getParamAtPoint
curve
(vlax-curve-getclosestpointto curve p1e)))
)
;; get segment points
(setq segs (get-segments curve p1e))
;; get radius of an arc
;; get angle between gap points
(setq da (* (atan (/ (/ gap 2) (sqrt (- (expt rad 2.0) (expt (/ gap 2.0) 2.0)))))2.0))
;; swap gap value
;; get the start length of segment
(setq stleg (vlax-curve-getdistatparam curve par))
;; get arc length
(setq leg (- (vlax-curve-getdistatparam curve (1+ par))
(vlax-curve-getdistatparam curve par))
)
(setq step (/ leg num))
(setq i 1)
(repeat (1- num)
(setq pn (vlax-curve-getpointatdist curve (+ stleg (* i step)))
pn (vlax-curve-getclosestpointto curve pn))

(setq ang (ang-tangent curve pn))

(setq ps1 (vlax-curve-getpointatdist curve (- (vlax-curve-getdistatpoint curve pn) (/ th 2)))
ps2 (vlax-curve-getpointatdist curve (+ (vlax-curve-getdistatpoint curve pn) (/ th 2))))

(setq pe1 (polar ps1 (- ang (/ pi 2)) joint)
pe2 (polar ps2 (- ang (/ pi 2)) joint))
(command "_.line" "_non" ps1 "_non" pe1 "")
(command "_.line" "_non" ps2 "_non" pe2 "")

(setq i (1+ i)))

)

)
( *error* nil)
(princ)
)```
~'J'~

6. Ok. Sorry for my extremely late reply. It has been busy!

fixo: Thank you very much for your LISP. It is very close to what I need, but there was one thing I cannot figure out how to correct. After the LISP is completed, It clears out all OSNAPS except PER. Can you guide me on how to fix that?

irneb: What I like about your routine is that you can set your gap and add a gap to the beginning and end of the division. Is there a way that you can change the Start and Stop gap to be half of what the user inputted Gap number? (i.e. 0.25/2). I like that yours is adjustable to a max dimension. That would come in handy for the Stone Segments.LSP I initially submitted.

So, if I could actually understand both of these routines, I would merge them together and then it would be great.
1. Mortar Joints drawn in.
2. The ability to set a max ceiling distance and gap diistance.
3. The option to include half the gap dimension at the start and end of the arch.

Thanks so much for your help guys. If either of you can steer me in the right direction to combine these LISPS that would be great, and if not, they will still be helpful!

7. Re osnaps pretty simple the variable osmode holds current snap value so

Code:
```At start of code do
(setq oldsnap (getvar "osmode"))

at end of code do
(setvar "osmode" oldsnap)```

8. Registered forum members do not see this ad.

@BIGAL That worked. Thanks!

Oddly enough, when I loaded the AMORT.LSP today into a new drawing, the program would initialize but after "Select Longest Arc Segment:" the program terminates with no error report... I was able to get it to work yesterday, in a different drawing. The only change I actually made to the LSP is the "Select (long/short) Arc Segment:" was verbally backwards. Also I added a SETVAR for turning osnaps back on. Am I missing something?

Code:
```;;__________________________________________Amort.lsp________________________________________________;;
;; math by Juergen Menzi
(abs (/ (distance p1 p2) 2 (sin (/ (* 4 (atan (abs bulge))) 2))
)
)
)
;;--------------------------------------;;
(defun ang-tangent (curve pnt)
(angle
'(0 0 0)
(trans
(vlax-curve-getFirstDeriv
curve
(vlax-curve-getParamAtPoint curve (trans (vlax-curve-getClosestPointTo curve pnt) 1 0))
)
0 1 T
)
)
)
;;--------------------------------------;;
(defun get-segments (en pnt / par)
(setq par (vlax-curve-getParamAtPoint
en
(vlax-curve-getClosestPointTo en pnt))
)
(list (vlax-curve-getPointAtParam en (fix par))
(vlax-curve-getPointAtParam en (1+ (fix par)))
)
)
;;----------------------- main part ----------------------------;;
(defun C:Amort(/ *error* adoc ang clay curve da en gap i joint leg num p1 p1e p2 par pe1 pe2 pn ps1 ps2 rad segs

sset step stleg th)
(defun *error* (msg)
(vla-endundomark (vla-get-activedocument
)
(cond ((or (not msg)
(member msg '("console break" "Function cancelled" "quit / exit abort"))
)
)
((princ (strcat "\nError: " msg)))
)
(setvar "nomutt" 0)
(if clay (setvar "clayer" clay))
(princ)
)

(setq clay (getvar "clayer"))
(setvar "clayer" "Mortar");<-- must be exist
(or *num* (setq *num* 4));<-- hard coded
(setq gap 0.25);<-- hard coded
(setvar "nomutt" 0)
(princ "\nSelect Longest Arc Segment")
(setvar "nomutt" 1)
(if (setq sset (ssget "_:S:E" '((0 . "*LINE"))))

(progn
(setvar "nomutt" 0)
(setq en (ssname sset 0))
(initget 6)
(setq num (getint (strcat "\nEnter the number of segments <" (rtos *num* 2 0) ">: ")))
(cond (num) ((setq num 4)))
(setq curve (vlax-ename->vla-object en))
(setvar "osmode" 512)
(setq p1 (getpoint "\nPick point on Longest arc segment: "))
(setvar "osmode" 128)
(setq p2 (getpoint p1 "\nPick point on Shortest arc segment: "))
(setq joint (distance p1 p2))
(setq p1e (vlax-curve-getclosestpointto curve p1))
(setq par (fix (vlax-curve-getParamAtPoint
curve
(vlax-curve-getclosestpointto curve p1e)))
)
;; get segment points
(setq segs (get-segments curve p1e))
;; get radius of an arc
;; get angle between gap points
(setq da (* (atan (/ (/ gap 2) (sqrt (- (expt rad 2.0) (expt (/ gap 2.0) 2.0)))))2.0))
;; swap gap value
;; get the start length of segment
(setq stleg (vlax-curve-getdistatparam curve par))
;; get arc length
(setq leg (- (vlax-curve-getdistatparam curve (1+ par))
(vlax-curve-getdistatparam curve par))
)
(setq step (/ leg num))
(setq i 1)
(repeat (1- num)
(setq pn (vlax-curve-getpointatdist curve (+ stleg (* i step)))
pn (vlax-curve-getclosestpointto curve pn))

(setq ang (ang-tangent curve pn))

(setq ps1 (vlax-curve-getpointatdist curve (- (vlax-curve-getdistatpoint curve pn) (/ th 2)))
ps2 (vlax-curve-getpointatdist curve (+ (vlax-curve-getdistatpoint curve pn) (/ th 2))))

(setq pe1 (polar ps1 (- ang (/ pi 2)) joint)
pe2 (polar ps2 (- ang (/ pi 2)) joint))
(command "_.line" "_non" ps1 "_non" pe1 "")
(command "_.line" "_non" ps2 "_non" pe2 "")

(setq i (1+ i)))

)

)
( *error* nil)
(setvar "osmode" 4211)
(princ)
)```

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts