I am dying to find an easy way to draw an arc that is tangent between two lines. There has to be an easier way in autoCAD....drawing a circle and then trimming seems so complex and slow. I am on autocad 11, does anyone know how to do this?
Thanks.
I forget -- does AutoCAD 11 have the option in Fillet to turn off the trimming of the Filleted objects, or did that come later? If you can't do that, doing it with Circle's Tangent-Tangent-Radius option [you only need to give it one T to get that] doesn't seem all that complex. You're going to have to give it at least that much information [the two things you want it tangent to, and the radius], anyway -- the only real added "complexity" is the trimming of the part of the Circle you don't want. But if that's really too much, I suppose a Lisp routine could be built that would emulate non-trimming Fillet.
Kent1Cooper a écrit :
I suppose a Lisp routine could be built that would emulate non-trimming Fillet.
I reinvented the wheel
It is sure imperfect, but it's for fun
Remove ";" (semi-colon) in code for adjust line
(defun z_dir (p1 p2 / )
(trans
'(0.0 1.0 0.0)
(mapcar
'(lambda (k)
(/ k
(sqrt
(apply '+
(mapcar
'(lambda (x) (* x x))
(mapcar '- p2 p1)
)
)
)
)
)
(mapcar '- p2 p1)
)
0
)
)
(defun ang_x (px p1 p2 / l_pt l_d p ang)
(setq
l_pt (mapcar '(lambda (x) (list (car x) (cadr x) (caddr x))) (list px p1 p2))
l_d (mapcar 'distance l_pt (append (cdr l_pt) (list (car l_pt))))
p (/ (apply '+ l_d) 2.0)
ang (* (atan (sqrt (/ (* (- p (car l_d)) (- p (caddr l_d))) (* p (- p (cadr l_d)))))) 2.0)
)
)
(defun det_wh (px p1 p2 / v1 v2 det_or)
(setq
v1 (mapcar '- p2 p1)
v2 (mapcar '- px p1)
)
(if (> (apply '(lambda (x1 y1 z1 x2 y2 z2) (- (* x1 y2) (* y1 x2))) (append v1 v2)) 0.0) 1 -1)
)
(defun k_th (p1 p2 c / k)
(setq k (/ c (distance p1 p2)))
(mapcar '+ (mapcar '* (mapcar '- p2 p1) (list k k k)) p1)
)
(defun c:my_filletrad ( / js1 js2 ps1 ps2 pt_lst pt l3 key_fillet alpha chord p_o a1 a2)
(princ "\nSelect first line: ")
(while (or (null (setq js1 (entsel))) (/= (cdr (assoc 0 (entget (car js1)))) "LINE")))
(princ "\nSelect second line: ")
(while (or (null (setq js2 (entsel))) (/= (cdr (assoc 0 (entget (car js2)))) "LINE")))
(setq
ps1 (trans (cadr js1) 1 0)
ps2 (trans (cadr js2) 1 0)
js1 (entget (car js1))
js2 (entget (car js2))
pt_lst (list (cdr (assoc 10 js1)) (cdr (assoc 11 js1)) (cdr (assoc 10 js2)) (cdr (assoc 11 js2)))
pt (inters (car pt_lst) (cadr pt_lst) (caddr pt_lst) (cadddr pt_lst) nil)
)
(cond
(pt
(if (eq (det_wh (cadddr pt_lst) (car pt_lst) (cadr pt_lst)) (det_wh (caddr pt_lst) (car pt_lst) (cadr pt_lst)))
(if (> (distance pt (caddr pt_lst)) (distance pt (cadddr pt_lst)))
(setq l3 (list pt (caddr pt_lst)))
(setq l3 (list pt (cadddr pt_lst)))
)
(if (eq (det_wh ps2 (car pt_lst) (cadr pt_lst)) (det_wh (caddr pt_lst) (car pt_lst) (cadr pt_lst)))
(setq l3 (list pt (caddr pt_lst)))
(setq l3 (list pt (cadddr pt_lst)))
)
)
(if (eq (det_wh (cadr pt_lst) (caddr pt_lst) (cadddr pt_lst)) (det_wh (car pt_lst) (caddr pt_lst) (cadddr pt_lst)))
(if (> (distance pt (car pt_lst)) (distance pt (cadr pt_lst)))
(setq l3 (cons (car pt_lst) l3))
(setq l3 (cons (cadr pt_lst) l3))
)
(if (eq (det_wh ps1 (caddr pt_lst) (cadddr pt_lst)) (det_wh (car pt_lst) (caddr pt_lst) (cadddr pt_lst)))
(setq l3 (cons (car pt_lst) l3))
(setq l3 (cons (cadr pt_lst) l3))
)
)
(initget 4)
(setq key_fillet
(getdist
(strcat
"\nSpecify radius fillet <"
(rtos (getvar "FILLETRAD"))
">:"
)
)
)
(if (null key_fillet) (setq key_fillet (getvar "FILLETRAD")) (setvar "FILLETRAD" key_fillet))
(setq
alpha (ang_x (cadr l3) (car l3) (caddr l3))
l_tg (* (getvar "FILLETRAD") (/ 1.0 (/ (sin (* alpha 0.5)) (cos (* alpha 0.5)))))
js1 (subst (cons 10 (car l3)) (assoc 10 js1) js1)
js2 (subst (cons 10 (caddr l3)) (assoc 10 js2) js2)
)
; (entmod
(setq js1 (subst (cons 11 (k_th pt (car l3) l_tg)) (assoc 11 js1) js1))
; )
; (entmod
(setq js2 (subst (cons 11 (k_th pt (caddr l3) l_tg)) (assoc 11 js2) js2))
; )
(setq
p_o (k_th pt (mapcar '* (mapcar '+ (cdr (assoc 11 js1)) (cdr (assoc 11 js2))) '(0.5 0.5 0.5)) (+ (getvar "FILLETRAD") (* (getvar "FILLETRAD") (1- (/ 1.0 (sin (* alpha 0.5)))))))
a1 (angle p_o (cdr (assoc 11 js1)))
a2 (angle p_o (cdr (assoc 11 js2)))
dxf_210 (z_dir p_o (cdr (assoc 11 js1)))
)
(entmake
(list
(cons 0 "ARC")
(cons 100 "AcDbEntity")
(assoc 67 js1)
(assoc 410 js1)
(cons 8 (getvar "CLAYER"))
(if (assoc 62 js1) (assoc 62 js1) (cons 62 256))
(if (assoc 6 js1) (assoc 6 js1) (cons 6 "BYLAYER"))
(cons 38 (+ (cadddr (assoc 10 js1)) (getvar "ELEVATION")))
(cons 39 (getvar "THICKNESS"))
(cons 100 "AcDbCircle")
(cons 10 (trans p_o 0 dxf_210))
(cons 40 (getvar "FILLETRAD"))
(cons 210 dxf_210)
(cons 100 "AcDbArc")
(cons 50
(if (equal (* (+ (max a1 a2) (min a1 a2)) 0.5) (angle p_o pt) 1E-8)
(min a1 a2)
(max a1 a2)
)
)
(cons 51
(if (equal (* (+ (max a1 a2) (min a1 a2)) 0.5) (angle p_o pt) 1E-8)
(max a1 a2)
(min a1 a2)
)
)
)
)
)
(T
(princ "\nCannot fillet line in different plane!")
)
)
(prin1)
)
Thanks all. Yes you can set fillets to 'no trim' in 11, so that is what I am doing. It still seems unnecessarily complex. I primarily use it to draw trails, walk ways etc....and in vectorworks it was so easy to just pick the arc command start it at one line and it would snap at a tangent point on the next line - done, you didn't have to put in a specific radius, yet you could adjust the radius later if needed (ie to make layout easier for contractors)...it was way faster than this. But it looks like fillet is really the only way to do this for autoCAD, oh-well.
@Anonymous wrote:... in vectorworks it was so easy to just pick the arc command start it at one line and it would snap at a tangent point on the next line .... you didn't have to put in a specific radius....
I'm having trouble imagining how that works. The only thing I can picture is that the location at which you "start it at one line" [presumably, in AutoCAD terms, applying Osnap NEArest] must become the point of tangency of the arc on that line. Is that correct?
yes, that's how it worked...it would adjust the radius as needed to make it tangent where you wanted to click. seemed easier for more freestyle type drafting. I got it worked out in autoCAD though with the fillet. I am just having frustration issues in switching from a longtime vectorworks user back to autoCAD.
The wheel hasn't been reinvented enough times in this thread, so here's my version. I am curious if this thing would work in R11. It's sure been a while since I used that version!
LLARC.LSP defines the command LLARC. When you run LLARC, it prompts you to select a first LINE entity, then it prompts you to select a second different LINE entity. It then draws that arc with an included angle of less than or equal to 180 degrees tangent to the two lines, which ends at the point you picked when you selected the second LINE. There are two possibilities here: the first is that the two LINEs, if extended, intersect, and the second is that they do not intersect. For the case where the two lines intersect, there will be two solutions (see two-solution-1.gif) and LLARC chooses the solution where the arc is on the same side of the intersection point as the two pick points. For the case where they do not intersect, it could be that the two LINEs are colinear or nearly so (I arbitrarily chose a distance of less than 1e-10 drawing units apart as the cutoff) but if the two lines are an appeciable distance apart, you can draw an arc with an included angle of 180 degrees between them, but you don't know which way it goes, so LLARC prompts you to select the direction the arc goes.
You might prefer to have the arc start at the point where you picked the first line instead of the second.
rbacmf21 a écrit :yes, that's how it worked...it would adjust the radius as needed to make it tangent where you wanted to click. seemed easier for more freestyle type drafting. I got it worked out in autoCAD though with the fillet. I am just having frustration issues in switching from a longtime vectorworks user back to autoCAD.
And if you try to change in my code ?
(initget 4) (setq key_fillet (getdist (strcat "\nSpecify radius fillet <" (rtos (getvar "FILLETRAD")) ">:" ) ) ) (if (null key_fillet) (setq key_fillet (getvar "FILLETRAD")) (setvar "FILLETRAD" key_fillet))
by only
(setvar "FILLETRAD" (distance pt ps1))
or ps2 for radius whith second line
Glad you liked it, but I think you might want to add the lines
(setq oldosm (getvar "osmode"))
(setvar "osmode" 0)
immediately after the first line
(defun-q C:LLARC()
and add
(setvar "osmode" oldosm)
immediately before the final (prin1) statement. This turns off running endpoint smnaps until the LLARC command is finished. If I had created the ARC the classy way using (entmake), like CADaStroumph did, rather than using the (command) function it wouldn't have that problem, but when you use the (command) function it's more or less as though you were actually picking points on the screen with your cursor. So if OSMODE is set to 1 (endpoint snap) when you do (command "arc" p5 p6 lpick) it's as though you positioned your cursor at p5, which falls on the first line, and then the endpoint snap will send the arc command not the coordinates in p6 but the coordinates of the endpoint of the first line nearest to p6.
Pretty cool.... The parallel-lines capability is something neither Fillet nor Circle's T option can do for you [except Fillet at the ends of the Lines]. I guess you could do it with Circle's 2P option, though, if you knew for sure that the Lines were actually parallel, but the resulting Circle would still need to be trimmed.
I would suggest adding at least Osnap control [Edit: I started this reply before your latest post came in, so I see you've noticed that], if not also the other usual bells and whistles [error handling, localizing of variables, maybe set the Layer to that of one of the Lines, etc.].
And for the OP: Would you ever need to do this with Polyline line segments, or perhaps Xlines or Rays, rather than always and only with Lines? Or perhaps some combination? Or even with Arcs or Polyline arc segments? I think changing it to be able to work with the various straight-line things wouldn't be hard, using (vlax-curve-getFirstDeriv) to find the directions of things, rather than entity data points. But getting it to work with actually-curving things could be a real challenge.
@Kent1Cooper wrote:.... Would you ever need to do this with Polyline line segments, or perhaps Xlines or Rays, rather than always and only with Lines? Or perhaps some combination? Or even with Arcs or Polyline arc segments? I think changing it to be able to work with the various straight-line things wouldn't be hard, using (vlax-curve-getFirstDeriv) to find the directions of things, rather than entity data points. But getting it to work with actually-curving things could be a real challenge.
Well, I've been puttering with that challenge for over a month now, off and on, and I think I've got it pretty well licked. The attached makes an Arc tangent to virtually any objects with linearity, including curved ones and nested and sub-entities, subject to a few limitations described at the top of the file.
Based on my question in Message 9 and the affirmative response, I built it so that the fixed tangency point is where you select on the first object, and it works out where to meet the second one; I suppose that could be reversed easily enough, if needed.
Next stop, if I putter further, would be to account for non-World Coordinate Systems, and possibly for something to do with things at different elevations, but in the WCS, it seems to work pretty well.
@Anonymous wrote:
no
Welcome to these Forums! But that seems a peculiar answer on a thread with how-to's suggested using basic AutoCAD commands, and at least 3 custom routines to do just what @a7v1n was asking, and more significantly in response to @Anonymous's later request for the same. @a7v1n never responded to any of it, and their latest participation here was about 6-1/2 years ago, so they may not see your answer, anyway, but can you elaborate? Do the routines offered not work for you? What brought you to this thread? Are you looking for a way to do something similar but not quite the same?
You're right.
"no" could mean nothing. And it could also mean anything.
A better practice would be giving more details with your comment(s). Please tell what is your concern/issue so people here can help.