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

draw an arc tangent to 2 lines

39 REPLIES 39
Reply
Message 1 of 40
Anonymous
30629 Views, 39 Replies

draw an arc tangent to 2 lines

Hi,
Is there any way to draw an arc tangent to 2 lines? thanks.
39 REPLIES 39
Message 21 of 40
stevor
in reply to: Anonymous

No Oh Well necessary: make a autolisp routine to do it your way.
S
Message 22 of 40
Kent1Cooper
in reply to: stevor


@stevor wrote:
No Oh Well necessary: make a autolisp routine to do it your way.

[See Post 14.]

Kent Cooper, AIA
Message 23 of 40
john.uhden
in reply to: Kent1Cooper

Kent:

 

Are you aware that you can Fillet;Radius,0 two parallel lines?  The command apparently computes the radius as being half the distance between the two lines.

 

This may be useful to someone:

(defun c:TTA ( / e ent1 ent2 p p1 p2 ip @delta @tan delta tan rad ba ea)
(vl-load-com) ;; TangentTangentArc (03-21-18) by John Uhden ;;----------------------------------------------------------- ;; This function returns the tangent of an angle in radians: (defun @tan (ang)(/ (sin ang)(cos ang))) ;;----------------------------------------------------------------------- ;; This function returns the deflection angle (in radians) of two angles: (defun @delta (a1 a2) (cond ((> a1 (+ a2 pi)) (- (+ a2 pi pi) a1) ) ((> a2 (+ a1 pi)) (- a2 (+ a1 pi pi)) ) (1 (- a2 a1)) ) ) (and (setq e (entsel "\nSelect first line at desired point of tangency: ")) (setq ent1 (entget (car e)) p (vlax-curve-getclosestpointto (car e) (cadr e))) (setq e (entsel "\nSelect 2nd line in vicinity of where you think 2nd tangent is: ")) (setq ent2 (entget (car e)) p2 (vlax-curve-getclosestpointto (car e) (cadr e))) (setq p1 (cdr (assoc 10 ent2))) (or (setq ip (inters (cdr (assoc 10 ent1)) p p1 p2 nil)) (alert "Lines do not intersect.") ) (setq tan (distance p ip)) (setq delta (@delta (angle p ip)(angle ip p2))) ;; T=R*tan(delta/2) ;; R=T/tan(delta/2) (setq rad (/ tan (@tan (abs (/ delta 2))))) (if (minusp delta) (setq rp (polar p (- (angle p ip)(* 0.5 pi)) rad) ba (+ (angle ip p2)(* 0.5 pi)) ea (angle rp p) ) (setq rp (polar p (+ (angle p ip)(* 0.5 pi)) rad) ba (angle rp p) ea (+ ba delta) ) ) (entmake (list '(0 . "ARC")(cons 10 rp)(cons 40 rad)(cons 50 ba)(cons 51 ea))) ) (princ) )

Of course it is currently lacking any error or undo controls.

John F. Uhden

Message 24 of 40
Kent1Cooper
in reply to: john.uhden


@john.uhden wrote:

.... 

Are you aware that you can Fillet;Radius,0 two parallel lines?  The command apparently computes the radius as being half the distance between the two lines.

....


Certainly, and not just with 0 radius.  You can do Fillet / Radius / anything-whatever, and if the two Lines are parallel, the result will be the same.  But it always puts one end of the Arc at the nearer endpoint of the first Line selected -- even in No-Trim mode, it won't put it at a somewhere-along-the-way selected location as routines here will.

Kent Cooper, AIA
Message 25 of 40
john.uhden
in reply to: Kent1Cooper

I didn't know about "anything-whatever."  Thanks for that.

Now that I think about it, my routine could be embellished to handle parallel lines, if anyone is interested.

It should also report the curve data.

John F. Uhden

Message 26 of 40
john.uhden
in reply to: john.uhden

Okay.

 

This one handles parallel lines, has error and undo controls, and reports the curve data...

(defun c:TTA ( / *error* e ent1 ent2 p p1 p2 ip @delta @tan  delta tan rad ba ea)
  ;; TangentTangentArc (03-21-18) by John Uhden
  (gc)
  (vl-load-com)
  (or *acad* (setq *acad* (vlax-get-acad-object)))
  (or *doc* (setq *doc* (vla-get-ActiveDocument *acad*)))
  (defun *error* (error)
    (if (vl-position cmdecho '(0 1))(setvar "cmdecho" cmdecho))
    (vla-endundomark *doc*)
    (cond
      ((not error))
      ((wcmatch (strcase error) "*QUIT*,*CANCEL*"))
      (1 (princ (strcat "\nERROR: " error)))
    )
    (princ)
  )
  (vla-endundomark *doc*)
  (vla-startundomark *doc*)
  (setq cmdecho (getvar "cmdecho"))
  (setvar "cmdecho" 0)
  (command "_.expert" (getvar "expert")) ;; dummy command
  ;;-------------------------------------------------------------------------------------------
  ;; This function returns the tangent of an angle in radiansa:
  (defun @tan (ang)(/ (sin ang)(cos ang)))
  ;;-----------------------------------------------------------------------------------------------------------
  ;; This function returns the deflection angle (in radians) of two angles:
  (defun @delta (a1 a2)
     (cond
       ((> a1 (+ a2 pi))
         (- (+ a2 pi pi) a1)
       )
       ((> a2 (+ a1 pi))
         (- a2 (+ a1 pi pi))
       )
       (1 (- a2 a1))
     )
  )
  (and
    (setq e (entsel "\nSelect first line at desired point of tangency: "))
    (setq ent1 (entget (car e)) p (vlax-curve-getclosestpointto (car e) (cadr e)))
    (setq e (entsel "\nSelect 2nd line in vicinity of where you think 2nd tangent is: "))
    (setq ent2 (entget (car e)) p2 (vlax-curve-getclosestpointto (car e) (cadr e)))
    (setq p1 (cdr (assoc 10 ent2)))
    (if
      (setq ip (inters (cdr (assoc 10 ent1)) p  p1  p2 nil))
      (progn
        (setq tan (distance p ip))
        (setq delta (@delta (angle p ip)(angle ip p2)))
        ;; T=R*tan(delta/2)
        ;; R=T/tan(delta/2)
        (setq rad (/ tan (@tan (abs (/ delta 2)))))
        (if (minusp delta)
          (setq rp (polar p (- (angle p ip)(* 0.5 pi)) rad)
                     ba (+ (angle ip p2)(* 0.5 pi))
                     ea (angle rp p)
          )
          (setq rp (polar p (+ (angle p ip)(* 0.5 pi)) rad)
                     ba (angle rp p)
                     ea (+ ba delta)
          )
        )
      )
      ;;  NOTE that when lines are parallel, this function always creates
      ;;  the arc CCW from the first pick point, because by definition
      ;;  arcs are always defined in a CCW direction.
      (setq p3 (polar p (+ (angle p (cdr (assoc 10 ent1))) (* 0.5 pi)) 100)
                 p2 (inters p p3 p1 p2 nil)
                 rad (* 0.5 (distance p p2))
                 rp (polar p (angle p p2) rad)
                 ba (angle rp p)
                 ea (angle rp p2)
                 delta pi
      )
    )
    (or
      (entmake (list '(0 . "ARC")(cons 10 rp)(cons 40 rad)(cons 50 ba)(cons 51 ea)))
      (alert "Arc creation failed.")
    )
    (princ
      (strcat
        "\nRadius = " (rtos rad (getvar "lunits") 3)
        "\nDelta = " (angtos delta 1 4)
        "\nLength = " (rtos (* delta rad)(getvar "lunits") 3)
      )
    )
  )
  (*error* nil)
)

John F. Uhden

Message 27 of 40
sean.mccready.ag
in reply to: Anonymous


@Anonymouswrote:
Hi,
Is there any way to draw an arc tangent to 2 lines? thanks.

 

Hello from 9 years in the future. (2018).

 

I was wanting to do the same thing in AutoCAD 2016, I was fairly sure I had done it before while learning AutoCAD in college, but had forgotten how to do so.

 

After some searching around I found an article by Auto Desk about working with splines: Draw a spline tangent to and connecting two lines or curves

In AutoCAD 2016 it is as easy as typing in "blend" and selecting both lines.

I hope this helps people like me for many years to come! 🙂

 

Message 28 of 40

I did not realize people were posting on this thread in 2018! I have replied to the OP's question after finding out about the "blend" command here:

 

https://knowledge.autodesk.com/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2016/ENU/AutoC...

 

In AutoCAD 2016 connecting two lines or curves that exist in 3D space is as easy as typing "blend" and selecting the two lines/curves in question. (I believe the lines/curves must be open on the end you are attempting to connect.)

I have just tested if blend works in 2 dimension space and it absolutely does.

 

 

Message 29 of 40

@Kent1Cooper, I found your lisp routine some time ago and me and my staff use it on a fairly regular basis. As a former MicroStation user, this is a God send. The only item I am hoping you could improve upon is when the second object is an arc or circle, I find the tangent arc being drawn seems to always go to the nearest side rather than near the point of selection that is, most of the time, on the far side of the arc or circle. Please let me know if you need a screenshot of my results. Thanks and good luck if you have time to explore this.

Message 30 of 40


@evietmeier_1207 wrote:

..... Please let me know if you need a screenshot of my results. ....


Yes, please.  I am not getting results like that, if I understand correctly what you mean, but maybe I don't.

Kent Cooper, AIA
Message 31 of 40

I was coming from a snap endpoint of two different arcs and tangent to two other arcs. See the screenshot. Thanks 

Message 32 of 40

What are you starting with, where are your pick locations, what in the image is the wrong result, and what do you want it to look like?  Could part of the problem be ambiguity about multiple objects at a pick location?  If so, can you use HIDEOBJECTS to take some of them out of consideration temporarily?

Kent Cooper, AIA
Message 33 of 40

Typically, I get in close enough, or the drawing field is not so cluttered. The screenshot show PT1 Endpoint and PT2 Tangent. The dashed arc is the desired result.

Thanks for taking the time to look at this.

Screenshot 2023-11-21 145607.png

Message 34 of 40

I set up a similar situation, and it did as expected, but there may be something very specific about the geometry.  Post a [small] sample drawing file containing a few things in that area that go wrong.

Kent Cooper, AIA
Message 35 of 40

Here's a small sample of what I encounter. I left enough line work for context. Again, the dashed arc is what gets drawn when trying to go from an arc endpoint to a tangent point on a second arc.

Thanks again

Message 36 of 40
evietmeier_1207
in reply to: Anonymous

@Kent1Cooper Maybe I have an outdated version? Here's what I've been using.

Message 37 of 40

It does the same for me.  And you have the latest, but since that's almost 13 years old, I'll have to re-familiarize myself with how it does its thing.

 

In the meantime, since it seems to be peculiar to the two-Arcs situation, you can do this:

Draw a temporary LINE from that endpoint of the first Arc to its CENter.  Rotate that Line 90° about that ENDpoint, so the new Line is tangent with the Arc at their shared endpoint.  Temporarily MOVE the first Arc out of the way.  Run the AT2 command from the ENDpoint of that temporary Line to the second Arc, which [for me] gives the correct resulting new Arc.  ERASE the temporary Line and MOVE the first Arc back to where it was.  [And in your sample situation, Trim the second Arc a little to the new one.]

Kent Cooper, AIA
Message 38 of 40
Sea-Haven
in reply to: Anonymous

The fillet 2 arcs has always been a problem, generally you get a big "S" as the answer, there is non acad Civil software that does it by asking for an approx center of the proposed arc. There is like 4 solutions for add an arc between 2 arcs.

 

It has been discussed before and most of us just use Circle TTR then trim excess circle.

Just tried adding an arc in my Bricscad V20 between 2 arcs using fillet and guess what it worked, but experience tells me it often doesn't. 

 

 

Message 39 of 40
Kent1Cooper
in reply to: Sea-Haven


@Sea-Haven wrote:

.... most of us just use Circle TTR then trim excess circle. .... 


That's fine if you know the radius, and when that is what matters, not the point of tangency.  This topic is about specifying the point of tangency on one of the objects, with the radius being a result as needed to end up tangent to the other object.

Kent Cooper, AIA
Message 40 of 40

@Kent1Cooper, That is a nice work-around, and it works. I look forward to your v 1.1 or 2.0 or whatever you'd want to call it if you write a new version. Otherwise, thanks for the suggested work-around.

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

Post to forums  

Autodesk Design & Make Report

”Boost