
- ;;;主程序
- (defun c:test(/ ptA PtB Ang Cir lst Cen Rad)
- ;;输入
- (if (and (setq ptA (getpoint "\n请输入一点:"))
- (setq Ang (getangle ptA "\n请输入角度:"))
- (setq Cir (car (entsel "\n请选择圆:")))
- (setq lst (entget Cir))
- (= (cdr (assoc 0 lst)) "CIRCLE")
- )
- (progn
- (setq Cen (cdr (assoc 10 lst))) ;圆心
- (setq Rad (cdr (assoc 40 lst))) ;半径
- (setq PtB (polar ptA Ang rad)) ;直线上的另一点
- (get-line-circle-intersect cen rad ptA ptB);求值
- )
- (alert "无效输入!")
- )
- (princ)
- )
- ;;;获得线段与圆的交点的函数
- ;;;参数: 圆心,半径,线段起点,线段终点
- ;;;返回值:交点或切点的列表,如果不相交则为nil
- (defun Get-line-circle-intersect
- (cen rad PtA PtB / Org eqt A B C D Pt0 Pt1 Pt2 Pt3 Pt4)
- (setq Pt0 (mapcar '- PtA Cen))
- (setq Pt1 (mapcar '- PtB Cen)) ;为了减少浮点误差
- (setq Org (list 0 0)) ;把原点移至圆心
- (setq eqt (Get-Line-Equation Pt0 Pt1)) ;直线的方程
- (setq A (car eqt) ;系数A
- B (cadr eqt) ;系数B
- C (caddr eqt) ;系数C
- )
- (setq D (/ C (sqrt (+ (* A A) (* B B))))) ;圆心到线段的距离
- (cond
- ((> (abs D) (+ Rad 1e-8)) ;如果距离大于半径
- (princ "\n无解!")
- nil ;无解
- )
- ((equal (abs D) Rad 1e-8) ;如果距离等于半径
- (princ "\n直线和圆相切!") ;直线跟圆相切
- (setq Pt2 (Polar Org (- Ang (/ Pi 2)) D)) ;求出切点
- (setq Pt2 (mapcar '+ Pt2 Cen)) ;切点变换到原坐标系
- (make-line PtA Pt2) ;画切线
- (list Pt2) ;返回切点列表
- )
- (t
- (princ "\n直线和圆有两个交点!") ;直线和圆有两个交点
- (setq Pt2 (Polar Org (- Ang (/ Pi 2)) D)) ;垂足点
- (setq E (sqrt (- (* Rad Rad) (* D D)))) ;半弦长
- (setq Pt3 (polar Pt2 Ang E)) ;交点一
- (setq Pt3 (mapcar '+ Pt3 Cen)) ;交点一变换到原坐标系
- (setq Pt4 (polar Pt2 Ang (- E))) ;交点二
- (setq Pt4 (mapcar '+ Pt4 Cen)) ;交点二变换到原坐标系
- (make-line Pt3 Pt4) ;画交线
- (list Pt3 Pt4) ;返回两个交点
- )
- )
- )
- ;;;两点的直线方程
- ;;;参数两个点
- ;;;返回值: 直线方程Ax+By+C=0的A,B,C值
- (defun Get-Line-Equation (Start-Pt End-Pt / x1 y1 x2 y2)
- (if (equal Start-Pt End-Pt 1e-8)
- nil
- (progn
- (setq x1 (car Start-Pt)
- y1 (cadr Start-Pt)
- x2 (car End-Pt)
- y2 (cadr End-Pt)
- )
- (list (- y1 y2)
- (- x2 x1)
- (- (* x1 y2) (* x2 y1))
- )
- )
- )
- )
- ;;;画线段的函数
- (defun make-line (Start-Pt End-Pt)
- (entmake
- (list
- (cons 0 "LINE")
- (cons 10 Start-Pt)
- (cons 11 End-Pt)
- )
- )
- )
- ;;;获得圆的参数
- (defun Get-Circle-Parameters(lst)
- (list (cdr (assoc 10 lst))
- (cdr (assoc 40 lst))
- )
- )
|