Tangent, Radius and Point Arc

Tangent, Radius and Point Arc

mehsan
Advocate Advocate
3,180 Views
19 Replies
Message 1 of 20

Tangent, Radius and Point Arc

mehsan
Advocate
Advocate

I have one circle and two lines, i want to add anther lisp code to my program for drawing one arc tangnet to circle, with Radius input and any point on the line.

thanks 

0 Likes
3,181 Views
19 Replies
Replies (19)
Message 2 of 20

Kent1Cooper
Consultant
Consultant

I'm afraid that in your example drawing [in which the Arc is not, in fact, tangent to the Circle], that's a geometric impossibility, unless the Arc curves in the opposite direction from the Circle.  The Arc's radius is smaller than the Circle's, which means that if it is to be tangent to the Circle at any point, and curving in the same direction, then all of it except the tangent point must be inside the Circle.

 

If the curvature is allowed to be in the opposite direction [as long as the radius of the Arc is no less than half the distance from the point to the Circle], or if in real-life situations the radius of the Arc will always be greater than that of the Circle, something could probably be worked out.

 

Or, if the example is real, maybe you mean to say that the Arc should be tangent to the Line rather than to the Circle [it looks like it is, though I didn't verify that].  Certainly an Arc that is tangent to a Line at a given point, and of a given radius, could be constructed to the point(s) where it meets the Circle.

Kent Cooper, AIA
0 Likes
Message 3 of 20

stevor
Collaborator
Collaborator

Either or the 2 red circles your objective?

S
0 Likes
Message 4 of 20

marko_ribar
Advisor
Advisor

You have to firstly understand Apollonius problem Line, Point, Circle to get construction done correctly and only after that you can write your routine if you wish...

Here is the problem solved :

http://www.cut-the-knot.org/Curriculum/Geometry/GeoGebra/PLC.shtml

 

I have drawn this solution on your DWG, so you have it, but for routine I don't quite have a time to dedicate to it... Solutions are red circles...

Look at the attachment - from red circles you only have to extract arcs either by trimming or with routine you have to write...

 

BTW... You have one argument predifined - it's radius of an arc... If your point P1 is on line and that line is tangent to arc in that point P1 and you have circle on which you should get other tangent, then radius is predetermined - it can be automatically derived from previous data...

 

HTH, Regards, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 5 of 20

gpcattaneo
Advocate
Advocate

@marko_ribar wrote:

...Apollonius problem Line, Point, Circle to get construction...


Marko, the OP's request is "drawing one arc tangnet to circle, with Radius input and any point on the line."

This is my attempt.

 

(defun c:TesT ( / *error* cir p lin pc pL rad_min rad pA pc dA dB dC pFc pF1 pF2)

    (vl-load-com)
    
    (defun *error* ( msg )
        (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
        (if cir (redraw cir 4))
        (if lin (redraw lin 4))
        (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )

    (vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))
    (if (and
            (setq cir (car (setq p (entsel "\nSelect Circle "))))
            (setq p (cadr p))
            (not (redraw cir 3))
            (setq lin (car (entsel "\nSelect Line ")))
            (not (redraw lin 3))           
            (setq pc (cdr (assoc 10 (entget cir))))
            (setq pL (vlax-curve-getClosestPointTo (vlax-ename->vla-object lin) pc))
            (setq rad_min (distance pL pc))
            (not 
                (while
                    (progn
                        (setq rad (getreal (strcat "\nFillet Radius (min. = " (rtos rad_min) "): ")))
                        (not (<= rad_min rad))
                    )
                )
            )            
        )
        (progn            
            (redraw cir 4)
            (redraw lin 4)
            (setq pA (polar pL (angle pL pc) rad))
            (setq dA (- rad (cdr (assoc 40 (entget cir)))))
            (setq dB (distance pc pA))
            (setq dC (sqrt (- (* dA dA) (* dB dB))))
            (if (minusp (sin (- (angle pc p) (angle pc pA))))
                (setq pFc (polar pA (- (angle pA pc) (* pi 0.5)) dC))
                (setq pFc (polar pA (+ (angle pA pc) (* pi 0.5)) dC))
            )
            (setq pF1 (polar pFc (angle pFc pc) rad))
            (setq pF2 (polar pFc (angle pc pL) rad))
            (if (minusp (sin (- (angle pc p) (angle pc pA))))
                (vl-cmdf "_arc" "_non" pF2 "_c" "_non" pFc "_non" pF1)
                (vl-cmdf "_arc" "_non" pF1 "_c" "_non" pFc "_non" pF2)
            )
        )
    )
    (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
)

 

 Smiley Happy

0 Likes
Message 6 of 20

Kent1Cooper
Consultant
Consultant

See notes in the attached drawing.  All the stuff I added is yellow, plus I copied the original white Lines, Circle and Point for the right side.

 

Whether the Arcs curving the other direction, as in the left side solution, or in real situations the desired Arc radius will be greater than the Circle radius, as in the right side, I'd have to think about how to automate that in a routine, but it can probably be done.

Kent Cooper, AIA
0 Likes
Message 7 of 20

mehsan
Advocate
Advocate

Hi, The code send to me looks great but how can i use to get the required result, i am trying but the result is not achived, i have attached the dwg for further informations.

thanks

0 Likes
Message 8 of 20

marko_ribar
Advisor
Advisor

mehsan, I am telling you again, some input data are predetermined... Either you don't need line at all - point is somewhere out of circle and you are searching for tangent of arc and circle as second point of an arc... => look at Kents drawing, or you want both tangents of arc where first point is point on line which is at the same time tangent of an arc and second point is tangent of an arc and circle - here is like I said radius data input unnecessary... => look at my posted drawing... The way you draw your example is actually tangent of an arc and line in input point and second point of an arc is actually intersection of an arc and circle where that point isn't tangent of an arc and circle in that point... Your construction is simple : offset line towards circle by the value of your radius of an arc, then draw perpendicular line at input point on line so that its perpendicular to line... At intersection of this line and offset parallel line is center of your arc/circle... Draw circle with that intersecting point perpendicular to line until it touches it at input point... At the end just trim circle with input line and input circle - you'll get your way of an arc... But I think that you are actually searching for both tangent arc at point on line and at calculated point on circle - you have to look to PLC Apollonius problem with point at special position on line...

I'll attach one more example explaining this problem solved and like I said you don't have to input radius at all...

 

M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 9 of 20

Kent1Cooper
Consultant
Consultant

@mehsan wrote:

... i have attached the dwg for further informations.

...


Here's the drawn solution to that.  If that's what you're looking for, putting it into a routine is probably doable, though I'd have to think about whether it would be possible [or easy] to calculate the geometry of the Arc and build it directly, or easier to have it actually draw those Circles and the ones that include the solution Arcs, and do the Trimming.

 

[I assumed that the wording "Radius for this circle is 55 + 2 = 57" refers to the desired radius for the Arc that goes through Pt1 and is tangent to the original Circle.  The red Arc in the drawing is not of that radius, which is why I mention it.]

Kent Cooper, AIA
0 Likes
Message 10 of 20

doni49
Mentor
Mentor

@mehsan wrote:

Hi, The code send to me looks great but how can i use to get the required result, i am trying but the result is not achived, i have attached the dwg for further informations.

thanks


meshan,

I know that people typically don't like to deal with semantics, but using the wrong words quite often make it hard for people to understand what you're after.  For something to be tangent to a circle, that object will only pass through ONE POINT on the circle -- even if you were to extend the object to infinity.

 

What I suspect you really want is to find the point of compound curvature.   Or possibly Point of Reverse Curvature.  I can't think of anything else that you could possibly be looking for.  But knowing WHICH you want would be important.



Don Ireland
Engineering Design Technician




If a reply solves your issue, please remember to click on "Accept as Solution". This will help other users looking to solve a similar issue. Thank you.


Please do not send a PM asking for assistance. That's what the forums are for. This allows everyone to benefit from the question asked and the answers given.

0 Likes
Message 11 of 20

doni49
Mentor
Mentor

@doni49 wrote:

@mehsan wrote:

Hi, The code send to me looks great but how can i use to get the required result, i am trying but the result is not achived, i have attached the dwg for further informations.

thanks


meshan,

I know that people typically don't like to deal with semantics, but using the wrong words quite often make it hard for people to understand what you're after.  For something to be tangent to a circle, that object will only pass through ONE POINT on the circle -- even if you were to extend the object to infinity.

 

What I suspect you really want is to find the point of compound curvature.   Or possibly Point of Reverse Curvature.  I can't think of anything else that you could possibly be looking for.  But knowing WHICH you want would be important.


Here's what I'm getting at.

In a Reverse Curve situation, if you were to draw a line between the two center points, the point where they intersect the line would be the point of

Reverse curvature.

Curve Example PRC.png

 

In a Compound Curve situation, the centers of the two arcs/circles and the Point of Compound Curvature will all be along the same straight line.

Curve Example PCC.png



Don Ireland
Engineering Design Technician




If a reply solves your issue, please remember to click on "Accept as Solution". This will help other users looking to solve a similar issue. Thank you.


Please do not send a PM asking for assistance. That's what the forums are for. This allows everyone to benefit from the question asked and the answers given.

0 Likes
Message 12 of 20

gpcattaneo
Advocate
Advocate

@mehsan wrote:

Hi, The code send to me looks great but how can i use to get the required result, i am trying but the result is not achived, i have attached the dwg for further informations.

thanks


Updated code

 

;  FILLET Circle-Line
;  06.Apr.2015
;  Gian Paolo Cattaneo

(defun c:FCL ( / *error* cir p lin pc pL rad_min rad pA pc dA dB dC pFc pF1 pF2)

    (defun *error* ( msg )
        (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
        (if cir (redraw cir 4))
        (if lin (redraw lin 4))
        (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )

    (vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))
    (if (and
            (setq cir (car (setq p (entsel "\nSelect Circle "))))
            (setq p (cadr p))
            (not (redraw cir 3))
            (setq lin (car (entsel "\nSelect Line ")))
            (not (redraw lin 3))           
            (setq pc (cdr (assoc 10 (entget cir))))
            (setq pL (vlax-curve-getClosestPointTo (vlax-ename->vla-object lin) pc))
            (setq rad_min (distance pL pc))
            (not 
                (while
                    (progn
                        (setq rad (getreal (strcat "\nEnter Fillet Radius (min. = " (rtos rad_min) "): " )))
                        (not (>= rad rad_min))
                    )
                )
            )            
        )
        (progn
            (redraw cir 4)
            (redraw lin 4)
            (setq dA (- rad (cdr (assoc 40 (entget cir)))))
            (if (equal rad rad_min 1e-8)
                (progn
                    (if (minusp (sin (- (angle pL p) (angle pL pc))))
                        (setq pFc (polar pc (- (angle pc pL) (* pi 0.5)) dA))
                        (setq pFc (polar pc (+ (angle pc pL) (* pi 0.5)) dA))
                    )
                    (setq pF1 (polar pFc (angle pFc pc) rad))
                    (setq pF2 (polar pFc (angle pc pL) rad))
                )
                (progn
                    (setq pA (polar pL (angle pL pc) rad))
                    (setq dB (distance pc pA))
                    (setq dC (sqrt (- (* dA dA) (* dB dB))))
                    (if (minusp (sin (- (angle pL p) (angle pL pc))))
                        (setq pFc (polar pA (- (angle pA pc) (* pi 0.5)) dC))
                        (setq pFc (polar pA (+ (angle pA pc) (* pi 0.5)) dC))
                    )
                    (setq pF1 (polar pFc (angle pFc pc) rad))
                    (setq pF2 (polar pFc (angle pc pL) rad))
                )
            )
            (if (minusp (sin (- (angle pL p) (angle pL pc))))                
                (vl-cmdf "_arc" "_non" pF2 "_c" "_non" pFc "_non" pF1)
                (vl-cmdf "_arc" "_non" pF1 "_c" "_non" pFc "_non" pF2)
            )
        )
    )
    (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
)

(vl-load-com)

(princ "\nFILLET Circle-Line ... by Gian Paolo Cattaneo")
(princ "\nType \"FCL\" to invoke")
(princ)

 

 

 

552.gif

 

 

 

Message 13 of 20

gpcattaneo
Advocate
Advocate

Explanation...

 

550a.jpg

 

 

551.jpg

 

 

 

 

 

0 Likes
Message 14 of 20

Kent1Cooper
Consultant
Consultant

That routine apparently assumes that the intent is for the resultant Arc to be tangent to the Line as well as to the Circle, determining for itself the point of tangency on the Line.  I took the original question, supported [I think] by the wording in the posted drawings, to be about a specific User-specified point along the Line [their Pt1] from which an Arc of a User-specified radius would be drawn that would end tangentially on the Circle.  But some clarification from mehsan is in order, because:

a)  the example drawings have the Arc tangent to neither the Circle nor the Line [it looks pretty close to being tangent to the Line, but isn't];

b)  the use of the wording "any point on the line" in the first Post leaves room for doubt about whether that is really to be a particular User-specified point or just a result of other factors;

c)  the distance from the Circle to the Line happens to also be the same as the second example drawing's described difference in radius between the Circle and the desired Arc, but it's not clear to me whether that would always be the case, and the radius of the Arc in the drawing is not as described.

Kent Cooper, AIA
0 Likes
Message 15 of 20

marko_ribar
Advisor
Advisor

Gian, I've just tested your code and it works fine... If only OP was describing the problem as like you "FILLET CIRCLE-LINE" than we wouldn't have to search for so much options... Nevertheless I think your code can be useful in CAD drafting - I've added it to my startup acaddoc.lsp... Thanks and I'll give you kudo for it... Keep good coding...

 

Regards, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 16 of 20

phanaem
Collaborator
Collaborator

the minimum radius is like this

 

 

rad_min.png

0 Likes
Message 17 of 20

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

....  I took the original question, supported [I think] by the wording in the posted drawings, to be about a specific User-specified point along the Line [their Pt1] from which an Arc of a User-specified radius would be drawn that would end tangentially on the Circle.  ....


... supported as well, come to think of it, by the very Subject of the thread.  I really don't think tangency to the Line is part of it, but the OP will need to clarify.

Kent Cooper, AIA
0 Likes
Message 18 of 20

marko_ribar
Advisor
Advisor

Yes, phanaem, that's correct... I've modified Gian's code to be applicable and for those kind of cases... This is what I use now...

 

;  FILLET Circle-Line
;  06.Apr.2015
;  Gian Paolo Cattaneo
;  mod by M.R.

(defun c:FCL ( / *error* cir pc lin pl c pcl rad_min cr rad )

    (vl-load-com)

    (defun *error* ( msg )
        (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
        (if cir (redraw cir 4))
        (if lin (redraw lin 4))
        (if msg (prompt msg))
        (princ)
    )

    (vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))
    (if (and
            (setq cir (car (setq pc (entsel "\nSelect Circle - choose side..."))))
            (setq pc (cadr pc))
            (not (redraw cir 3))
            (setq lin (car (setq pl (entsel "\nSelect Line..."))))
            (setq pl (cadr pl))
            (not (redraw lin 3))           
            (setq c (cdr (assoc 10 (entget cir))))
            (setq pcl (vlax-curve-getclosestpointto lin c))
            (setq rad_min (/ (+ (distance pcl c) (setq cr (cdr (assoc 40 (entget cir))))) 2.0))
            (not 
                (while
                    (progn
                        (setq rad (getreal (strcat "\nEnter Fillet Radius <min. = " (rtos rad_min) "> : ")))
                        (if (null rad) (setq rad rad_min))
                        (not (>= rad rad_min))
                    )
                )
            )            
        )
        (progn
            (redraw cir 4)
            (redraw lin 4)
            (command "_.CIRCLE" "_TTR" pl pc rad)
            (setq pc (polar pc (angle pc c) (* 10.0 cr)))
            (command "_.TRIM" (ssadd lin (ssadd cir)) "" (vlax-curve-getclosestpointto (entlast) pc) "")
        )
    )
    (*error* nil)
)

 I know that there is no math, but it works...

 

Ciao...

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 19 of 20

Anonymous
Not applicable

Yes, You are right i will still explain more actually i am making a program for 3 centered radius compound curve.

thanks

0 Likes
Message 20 of 20

marko_ribar
Advisor
Advisor

As I can't edit my last code, I've decided to post my final version - should work in any 3D space / UCS / View... Tested on A2008-A2014...

 

;  FILLET Circle-Line
;  06.Apr.2015
;  Gian Paolo Cattaneo
;  mod by M.R.

(defun c:FCL ( / *error* 3D->2D MR:Collinear-p cir pc lin pl c pcl lix rad_min cr rad cirn pcn pln mpar pmn cn )

    (vl-load-com)

    (defun *error* ( msg )
        (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
        (if cir (redraw cir 4))
        (if lin (redraw lin 4))
        (if msg (prompt msg))
        (princ)
    )

    ;; 3D to 2D point  -  M.R.
    ;; Returns 2D point list from supplied 3D point list or returns supplied argument if it isn't 3D point list

    (defun 3D->2D ( p )
        (if (and (listp p) (vl-every '(lambda ( x ) (eq (type x) 'REAL)) p) (eq (length p) 3))
            (list (car p) (cadr p))
            p
        )
    )

    ;; Collinear-p  -  M.R.
    ;; Returns T if p1,p2,p3 are collinear

    (defun MR:Collinear-p ( p1 p2 p3 )
        (equal (distance p1 p3)
              (+ (distance p1 p2) (distance p2 p3))
              1e-8
        )
    )

    (vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))
    (princ "\n")
    (prompt "\nFILLET CIRCLE-LINE")
    (princ "\n")
    (princ "\n")
    (if (and
            (setq cir (car (setq pc (entsel "\nSelect Circle - choose side..."))))
            (vl-cmdf "_.UCS" "_E" (cadr pc))
            (setq pc (polar '(0.0 0.0 0.0) 0.0 (setq cr (cdr (assoc 40 (entget cir))))))
            (not (redraw cir 3))
            (setq lin (car (setq pl (entsel "\nSelect Line..."))))
            (setq pl (osnap (cadr pl) "_nea"))
            (not (redraw lin 3))           
            (setq c '(0.0 0.0 0.0))
            (setq pcl (trans (vlax-curve-getclosestpointto lin (trans c 1 0) t) 0 1))
            (setq lix (entget lin))
            (if (not
                  (and
                    (equal (caddr (trans (cdr (assoc 10 lix)) lin 1)) 0.0 1e-8)
                    (equal (caddr (trans (cdr (assoc 11 lix)) lin 1)) 0.0 1e-8)
                  )
                )
                (prompt "\nPicked line doesn't lie in the same plane as picked circle... Restart routine again and choose correct entities...")
                t
            )
            (if (not (vlax-curve-getparamatpoint lin (trans pcl 1 0)))
              (if (< (distance (trans (cdr (assoc 10 lix)) lin 1) pcl) (distance (trans (cdr (assoc 11 lix)) lin 1) pcl))
                (entupd (cdr (assoc -1 (entmod (subst (cons 10 (trans pcl 1 lin)) (assoc 10 lix) lix)))))
                (entupd (cdr (assoc -1 (entmod (subst (cons 11 (trans pcl 1 lin)) (assoc 11 lix) lix)))))
              )
              t
            )
            (if (or
                  (equal (trans pcl 1 lin) (cdr (assoc 10 (entget lin))) 1e-6)
                  (equal (trans pcl 1 lin) (cdr (assoc 11 (entget lin))) 1e-6)
                )
                (vl-cmdf "_.LENGTHEN" "_P" 200 pcl "")
                t
            )
            (if (not (MR:Collinear-p pl pcl (trans (vlax-curve-getclosestpointto lin (trans pc 1 0) t) 0 1)))
              (setq pl (polar pl (angle pl pcl) (distance pl pcl)))
              t
            )
            (setq rad_min (/ (+ (distance pcl c) cr) 2.0))
            (not 
                (while
                    (progn
                        (setq rad (getreal (strcat "\nEnter Fillet Radius <min. = " (rtos rad_min) "> : ")))
                        (if (null rad) (setq rad rad_min))
                        (not (>= rad rad_min))
                    )
                )
            )            
        )
        (progn
            (redraw cir 4)
            (redraw lin 4)
            (command "_.ZOOM" "_O" (ssadd lin (ssadd cir)) "")
            (command "_.CIRCLE" "_TTR" "_tan" pc "_tan" pl rad)
            (setq cirn (entlast))
            (command "_.ZOOM" "_O" (ssadd lin (ssadd cir (ssadd cirn))) "")
            (setq pcn (trans (vlax-invoke (vlax-ename->vla-object cir) 'intersectwith (vlax-ename->vla-object cirn) acextendnone) 0 1))
            (setq pln (trans (vlax-invoke (vlax-ename->vla-object lin) 'intersectwith (vlax-ename->vla-object cirn) acextendnone) 0 1))
            (setq mpar (/ (+ (vlax-curve-getparamatpoint cirn (trans pcn 1 0)) (vlax-curve-getparamatpoint cirn (trans pln 1 0))) 2.0))
            (setq pmn (trans (vlax-curve-getpointatparam cirn mpar) 0 1))
            (setq cn (trans (cdr (assoc 10 (entget cirn))) cirn 1))
            (if (> (distance pc pmn) (distance pc (polar pmn (angle pmn cn) (* 2.0 (cdr (assoc 40 (entget cirn)))))))
              (setq pmn (polar pmn (angle pmn cn) (* 2.0 (cdr (assoc 40 (entget cirn))))))
            )
            (entdel cirn)
            (command "_.ARC" "_none" (3D->2D pcn) "_none" (3D->2D pmn) "_none" (3D->2D pln))
            (entupd (cdr (assoc -1 (entmod lix))))
            (command "_.ZOOM" "_P")
            (command "_.ZOOM" "_P")
            (command "_.UCS" "_P")
        )
    )
    (*error* nil)
)

 HTH, just a little, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes