There are two general mathematical approaches for calculating the center of the fillet radius (a1 in your figurer 3). One is to analytically solve for the intersection of a line and an arc. In this case the line will be a line offset from line pt1 pt2 by a distance r1 (the radius of the fillet). The center of the fillet will also be on an arc of radius equal to the fillet radius + given arc radius r = r1 + r2. This arc will have the same center as the given arc.
Since a line may intersect an arc twice, part of the task is to determine which of the two possible solutions is the one you want. This can be done with a bias point determined from existing geometry or by the user specifying which solution is needed.
Another method for finding the fillet center is to use numerical methods which use a sequence of systematic guesses to find a solution that is numerically satisfactory. I thought I'd have some fun with this problem and try a numerical solution.
In the code below pt10 and pt 11 define the line offset from the line passing through pt1 pt2 by the distance r1. A unit vector perpendicular to line p1 p2 and pointing towards the arc center (ptctr) is used to determine the direction of the offset.
The end of the offset line is used as an initial guess for the location of the center. This is the left most ptA.
ptB is the intersection of the line from ptA to ptctr.
ptB is then projected to line from pt10 to pt11> This defines a new ptA
Step 1 above is repeated using the new ptA
Step 2 is repeated to calculate a new ptB
The process continues until the distance between the most recent values for ptA and ptB is less than a specified tolerance. I set this value to 0.00001 in the code below but it could be smaller or a percentage of some value (e.g., the extents).
If a solution is not found in 100 tries the message "No Solution" is displayed.
; finds the center of a fillet given a line, arc, and fillet radius
; L. Minardi 10/30/2019
(defun c:ctrpoint (/)
(command "_pdmode" "35" "")
(setq osnp (getvar "osmode"))
(setvar "osmode" 0)
(setq r1 (getdist "\nEnter fillet radius")
ss (entsel "\nSelect line")
ed (entget (nth 0 ss))
pt1 (cdr (assoc 10 ed))
pt2 (cdr (assoc 11 ed))
ss (entsel "\nSelect arc")
ed (entget (nth 0 ss))
ptctr (cdr (assoc 10 ed))
r2 (cdr (assoc 40 ed)) ; radius of arc
perp12 (proj_pt pt1 pt2 ptctr) ; projection of arc center onto line
uperp12 (normalize (mapcar '- ptctr perp12)) ; unit vector in direction of arc center
pt10 (mapcar '+ pt1 (mapcar '* uperp12 (list r1 r1 r1))) ; offset line
pt11 (mapcar '+ pt10 (mapcar '- pt2 pt1))
ptA pt10 ; start point for interation
r (+ r1 r2) ; radius of arc with fillet center
cont T ; while flag
n 0 ; iteration counter
)
; ptB is at the intersetcion of the offset arc and line from ptA to arc center
; ptA is the projection of ptB onto the offset line.
(while cont
(setq
ptB (mapcar
'+
ptctr
(mapcar '* (normalize (mapcar '- ptA ptctr)) (list r r r))
)
)
(setq ptA (proj_pt pt10 pt11 ptB))
(setq
ptB
(mapcar '+
ptctr
(mapcar '* (normalize (mapcar '- ptA ptctr)) (list r r r))
)
)
(setq n (+ n 1))
(if (< (distance ptA ptB) 0.00001)
(setq cont nil)
) ; end if
(if (> n 100)
(setq cont nil)
) ; end if
) ; end while
(if (> n 100)
(princ "\nNo Solution")
(progn
(princ "\fillet center = ")
(princ ptB)
(command "_point" ptB "")
(princ "\iterations = ")
(princ n)
)
) ; end if
(setvar "osmode" osnp) ;reset osnap
;reset osnap
(princ)
) ; end defun
(defun normalize (p / d)
; normalize a vector
(setq d (distance '(0 0 0) p))
(setq p (mapcar '/ p (list d d d)))
)
;;; calculates point of p projected to line defined by p1 and p2
(defun proj_pt (p1 p2 p / d u12 )
(setq d (distance p1 p2))
(setq u12 (mapcar '/ (mapcar '- p2 p1) (list d d d)))
(setq d (dot u12 (mapcar '- p p1)))
(setq pp (mapcar '+ p1 (mapcar '* u12 (list d d d))))
)
;;; dot product of 2 vectors a and b
(defun dot (a b / dd)
(setq dd (mapcar '* a b))
(setq dd (+ (nth 0 dd) (nth 1 dd) (nth 2 dd)))
)