zgzzsn 发表于 2015-11-23 14:23:22

已知圆弧的弧长及弦长、弧长及弓高、弦长及弓高,求半径及画圆弧, 请高手帮忙调试...

已知圆弧的弧长及弦长、弧长及弓高、弦长及弓高,求半径及画圆弧,请高手帮忙调试这个lsp



;========arcL========
;已知同弧的弧长及弦长、弧长及弓高、弦长及弓高,求半径及画圆弧
(defun C:arcL()
        (setq xtblm '("cmdecho" "osmode")
        xtblz (mapcar 'getvar xtblm) ;获取系统变量的原始值
        )
        (mapcar 'setvar xtblm '(0 33));对系统变量初始化
        (command "_undo" "de") ;设置撤消命令的起点
        ;设置选择画弧方式的关健字
        ;L为按“弧长弦长”方式画圆弧(默认方式)
        ;H为按“弧长弓高”方式画国弧
        ;C为按 "弦长弓高"方式画圆弧
        (initget "L H C")
        (setq htbz(getkword "\n画弧方式〔L一弧长弦长/H一弧长弓高/C一弦长弓高〕<L>:"))
        (if(= htbz nil)(setq htbz "L"))
        (if(wcmatch htbz "L,H")(setq L(getreal "\n弧长:")))
        (if(wcmatch htbz "L,C")(setq C(getdist "\n弦长:")))
        (if(wcmatch htbz "H,C")(setq h(getdist "\n弓高:")))       
        ;当“弧长弓高”方式画圆弧时,询问是劣弧还是优弧
        ;将圆心角<l.5pi的圆弧都视为劣孤
        (initget "Y N")
        (if(= htbz "H")
        (if(= (setq yh(getkword "\n 劣弧<Y>:"))nil)
        (setq yh "Y")
        )
        )
        (setq eps le-10;设定迭代精度e=10^-10(即10的负10次方)
        x 0
        xi (* 1.0 pi);初值
        )
        (if (and (= htbz "H")(= yh "N"))(setq xi (* 2.0 pi)))       
        (if(wcmatch htbz "L,C")(setq xi (* 2.0 pi)))
        ;牛顿迭代法求圆心角
        (while(>(abs(- xi x)) eps)
        (setq x xi)
        (if(= htbz "L")
        ;已知圆弧长度及弦长的迭代
        (setq fx(-(* 2.0 L (sin(/ x 2.0)))(* c x))
                dfx(-(* L (cos(/ x 2.0)))c)
        )
        (if(= htbz "H")
                ;已知圆弧长度及弓高的迭代
                (setq fx (- L (* L (cos(* 0.5 x)))(* h x))
                        dfx(-(* 0.5 L (sin(* 0.5 x)))h)
        )
        ;已知圆弦长度及弓高的迭代
        (setq fx (-(* 2.0 h (sin(* 0.5 x)))(* -1.0 c (cos(* 0.5 x)))c)
                dfx(-(* h (cos(* 0.5 x)))(* 0.5 c (sin(* 0.5 x))))

        )
        )
        )
        (setq xL (- x (/ fx dfx)))
        )
        ;由圆心角计算出半径       
        (if(wcmatch htbz "L,H")
                (setq r (/ L xL))
                (setq r (/ c 2.0 (sin(* 0.5 xL))))
        )
        (princ "\n解算出的半径R=")(princ(rtos r 2 10))
        ;根据已知数据及解算出的圆心角、半径计算弓高
        (if(= htbz "L")(setq h (* r (1-(cos(* 0.5 xL))))))
        (if(= htbz "H")
                (progn
                        (setq c(* 2.0 r (sin(*0.5 xL))))
        (if(<(abs(- xL (* 2.0 pi))) 1e-6)(setq c(* 2.0 r)))))
        )
        ;根据指定的点、已知及解算出的数据计算圆弧的中点、止点
        (setq pt (getpoint "\n 起点:")
        pt3 (polar pt1 0 c)
        ptm (polar pt1 0 (* 0.5 c))
        pt2 (polar ptm(* 0.5 pi) h)
        )
        (setvar "osmode" 0);关闭对象捕捉功能
        ;调用CAD已有的三点画圆弧命令画圆弧
        (command "_arc" pt1 pt2 pt3)
        (setvar "osmode" 33);设置对象捕捉(捕捉端点和交点)
        (princ "\n止点方向:")
        ;动态将固弧旋转到指定方向
        (command "_rotate" (entlast) "" pt1 "r" pt1 pt3 pause)
        (command "_undo" "e") ;设置撤消命令的止点
        (mapcar 'setvar xtblm xtblz);恢复系统变量的原始值
        (princ)
)








ynhh 发表于 2015-11-23 14:54:25

能为AUTOCAD增加功能
感谢你对CAD事业的支持

自贡黄明儒 发表于 2015-11-23 15:18:02

本帖最后由 自贡黄明儒 于 2015-11-23 15:19 编辑

难点在于要应用高数知识,我都忘了。lisp知识是次要的,如图,你格式化一下,就会发现少括号。
注意:一个分号,二个分号,三个分号,作用是不同的

jltx123456 发表于 2015-11-23 15:26:51

应该是多了一个回括,
你试试看:
;========arcL========
;已知同弧的弧长及弦长、弧长及弓高、弦长及弓高,求半径及画圆弧
(defun C:arcL()
        (setq xtblm '("cmdecho" "osmode")
      xtblz (mapcar 'getvar xtblm) ;获取系统变量的原始值
        )
        (mapcar 'setvar xtblm '(0 33));对系统变量初始化
        (command "_undo" "de") ;设置撤消命令的起点
        ;设置选择画弧方式的关健字
        ;L为按“弧长弦长”方式画圆弧(默认方式)
        ;H为按“弧长弓高”方式画国弧
        ;C为按 "弦长弓高"方式画圆弧
        (initget "L H C")
        (setq htbz(getkword "\n画弧方式〔L一弧长弦长/H一弧长弓高/C一弦长弓高〕<L>:"))
        (if(= htbz nil)(setq htbz "L"))
        (if(wcmatch htbz "L,H")(setq L(getreal "\n弧长:")))
        (if(wcmatch htbz "L,C")(setq C(getdist "\n弦长:")))
        (if(wcmatch htbz "H,C")(setq h(getdist "\n弓高:")))         
        ;当“弧长弓高”方式画圆弧时,询问是劣弧还是优弧
        ;将圆心角<l.5pi的圆弧都视为劣孤
        (initget "Y N")
        (if(= htbz "H")
      (if(= (setq yh(getkword "\n 劣弧<Y>:"))nil)
                        (setq yh "Y")
                )
        )
        (setq eps le-10   ;设定迭代精度e=10^-10(即10的负10次方)
      x 0
      xi (* 1.0 pi);初值
        )
        (if (and (= htbz "H")(= yh "N"))(setq xi (* 2.0 pi)))      
        (if(wcmatch htbz "L,C")(setq xi (* 2.0 pi)))
        ;牛顿迭代法求圆心角
        (while(>(abs(- xi x)) eps)
      (setq x xi)
      (if(= htbz "L")
                        ;已知圆弧长度及弦长的迭代
                        (setq fx(-(* 2.0 L (sin(/ x 2.0)))(* c x))
                dfx(-(* L (cos(/ x 2.0)))c)
                        )
                        (if(= htbz "H")
                ;已知圆弧长度及弓高的迭代
                (setq fx (- L (* L (cos(* 0.5 x)))(* h x))
                                        dfx(-(* 0.5 L (sin(* 0.5 x)))h)
                                )
                                ;已知圆弦长度及弓高的迭代
                                (setq fx (-(* 2.0 h (sin(* 0.5 x)))(* -1.0 c (cos(* 0.5 x)))c)
                                        dfx(-(* h (cos(* 0.5 x)))(* 0.5 c (sin(* 0.5 x))))
                                       
                                )
                        )
                )
      (setq xL (- x (/ fx dfx)))
        )
        ;由圆心角计算出半径      
        (if(wcmatch htbz "L,H")
                (setq r (/ L xL))
                (setq r (/ c 2.0 (sin(* 0.5 xL))))
        )
        (princ "\n解算出的半径R=")(princ(rtos r 2 10))
        ;根据已知数据及解算出的圆心角、半径计算弓高
        (if(= htbz "L")(setq h (* r (1-(cos(* 0.5 xL))))))
        (if(= htbz "H")
                (progn
                        (setq c(* 2.0 r (sin(*0.5 xL))))
                        (if(<(abs(- xL (* 2.0 pi))) 1e-6)(setq c(* 2.0 r)))
                )
        )
        ;根据指定的点、已知及解算出的数据计算圆弧的中点、止点
        (setq pt (getpoint "\n 起点:")
                pt3 (polar pt1 0 c)
                ptm (polar pt1 0 (* 0.5 c))
                pt2 (polar ptm(* 0.5 pi) h)
        )
        (setvar "osmode" 0);关闭对象捕捉功能
        ;调用CAD已有的三点画圆弧命令画圆弧
        (command "_arc" pt1 pt2 pt3)
        (setvar "osmode" 33);设置对象捕捉(捕捉端点和交点)
        (princ "\n止点方向:")
        ;动态将固弧旋转到指定方向
        (command "_rotate" (entlast) "" pt1 "r" pt1 pt3 pause)
(command "_undo" "e") ;设置撤消命令的止点
(mapcar 'setvar xtblm xtblz);恢复系统变量的原始值
(princ)
)

zgzzsn 发表于 2015-11-23 15:34:05

还是不能通过

命令: _appload 已成功加载 arcl2.lsp。
命令: ; 错误: 输入的字符串有缺陷

jltx123456 发表于 2015-11-23 16:14:01

zgzzsn 发表于 2015-11-23 15:34 static/image/common/back.gif
还是不能通过

命令: _appload 已成功加载 arcl2.lsp。


问题点还蛮多
                                        ;========arcL========
                                        ;已知同弧的弧长及弦长、弧长及弓高、弦长及弓高,求半径及画圆弧
(defun C:arcL ()
(setq        xtblm '("cmdecho" "osmode")
        xtblz (mapcar 'getvar xtblm)        ;获取系统变量的原始值
)
(mapcar 'setvar xtblm '(0 33))        ;对系统变量初始化
(command  "_undo" "be")                ;设置撤消命令的起点
                                        ;设置选择画弧方式的关健字
                                        ;L为按“弧长弦长”方式画圆弧(默认方式)
                                        ;H为按“弧长弓高”方式画国弧
                                        ;C为按 "弦长弓高"方式画圆弧
(initget "L H C")
(setq        htbz (getkword
             "\n画弧方式〔L一弧长弦长/H一弧长弓高/C一弦长弓高〕<L>:"
             )
)
(if (= htbz nil)
    (setq htbz "L")
)
(if (wcmatch htbz "L,H")
    (setq L (getreal "\n弧长:"))
)
(if (wcmatch htbz "L,C")
    (setq C (getdist "\n弦长:"))
)
(if (wcmatch htbz "H,C")
    (setq h (getdist "\n弓高:"))
)
                                        ;当“弧长弓高”方式画圆弧时,询问是劣弧还是优弧
                                        ;将圆心角<l.5pi的圆弧都视为劣孤
(initget "Y N")
(if (= htbz "H")
    (if        (= (setq yh (getkword "\n 劣弧<Y>:")) nil)
      (setq yh "Y")
    )
)
(setq        eps le-10                        ;设定迭代精度e=10^-10(即10的负10次方)
        x   0
        xi(* 1.0 pi)                        ;初值
)
(if (and (= htbz "H") (= yh "N"))
    (setq xi (* 2.0 pi))
)
(if (wcmatch htbz "L,C")
    (setq xi (* 2.0 pi))
)
                                        ;牛顿迭代法求圆心角
(while (> (abs (- xi x)) eps)
    (setq x xi)
    (if        (= htbz "L")
                                        ;已知圆弧长度及弦长的迭代
      (setq fx        (- (* 2.0 L (sin (/ x 2.0))) (* c x))
          dfx        (- (* L (cos (/ x 2.0))) c)
      )
    )
    (if        (= htbz "H")
                                        ;已知圆弧长度及弓高的迭代
      (setq fx        (- L (* L (cos (* 0.5 x))) (* h x))
          dfx        (- (* 0.5 L (sin (* 0.5 x))) h)
      )
    )
    (if        (= htbz "C")
                                        ;已知圆弦长度及弓高的迭代
      (setq fx        (- (* 2.0 h (sin (* 0.5 x))) (* -1.0 c (cos (* 0.5 x))) c)
          dfx        (- (* h (cos (* 0.5 x))) (* 0.5 c (sin (* 0.5 x))))

      )
    )
    (setq xL (- x (/ fx dfx)))
)
                                        ;由圆心角计算出半径      
(if (wcmatch htbz "L,H")
    (setq r (/ L xL))
    (setq r (/ c 2.0 (sin (* 0.5 xL))))
)
(princ "\n解算出的半径R=")
(princ (rtos r 2 10))
                                        ;根据已知数据及解算出的圆心角、半径计算弓高
(if (= htbz "L")
    (setq h (* r (1- (cos (* 0.5 xL)))))
)
(if (= htbz "H")
    (progn
      (setq c (* 2.0 r (sin (*0.5 xL))))
      (if (< (abs (- xL (* 2.0 pi))) 1e-6)
        (setq c (* 2.0 r))
      )
    )
)
                                        ;根据指定的点、已知及解算出的数据计算圆弧的中点、止点
(setq        pt(getpoint "\n 起点:")
        pt3 (polar pt1 0 c)
        ptm (polar pt1 0 (* 0.5 c))
        pt2 (polar ptm (* 0.5 pi) h)
)
(setvar "osmode" 0)                        ;关闭对象捕捉功能
                                        ;调用CAD已有的三点画圆弧命令画圆弧
(command "_arc" pt1 pt2 pt3)
(setvar "osmode" 33)                        ;设置对象捕捉(捕捉端点和交点)
(princ "\n止点方向:")
                                        ;动态将固弧旋转到指定方向
(command "_rotate" (entlast) "" pt1 "r" pt1 pt3 pause)
(command  "_undo" "e")                ;设置撤消命令的止点
(mapcar 'setvar xtblm xtblz)                ;恢复系统变量的原始值
(princ)
)

yshf 发表于 2015-11-23 19:57:27

本帖最后由 yshf 于 2015-11-23 22:33 编辑

对照检查一下:;=====================   arc1==============================
;已知圆弧的弧长及弦长、弧长及弓高、弦长及弓高,求半径及画圆弧
(defun c:arc1()
    (setq xtblm '("cmdecho" "osmode")
          xtblz(mapcar 'getvar xtblm);获取系统变量的原始值
    )
    (mapcar 'setvar xtblm '(0 33));对系统变量初始化
    (command "_undo" "be");设置撤消命令的起点
    ;设置选择画弧方式的关键字
    ;L-按“弧长弦长”方式画圆弧 (默认方式)
    ;H-按“弧长弓高”方式画圆弧
    ;C-按“弦长弓高”方式画圆弧
    (initget "L H C")
    (setq htbz (getkword "\n画弧方式<L>:"))
    (if (= htbz nil)(setq htbz "L"))
    (if (wcmatch htbz "L,H") (setq l (getreal "\n弧长:")))
    (if (wcmatch htbz "L,C") (setq c (getdist "\n弦长:")))
    (if (wcmatch htbz "H,C") (setq h (getdist "\n弓高:")))
    ;当“弧长弓高”方式画圆弧时,询问是劣弧还是优弧
    ;将圆心角<1.5π的圆弧都视为劣弧
    (initget "Y N")
    (if (= htbz "H")
      (if (= (setq yh (getkWord "\n劣弧<Y>:")) nil)
            (setq yh "Y")
      )
    )
    (setq eps 1e-10 ;设定迭代精度ε=10^-10(即10的负10次方)
          x   0
          x1(* 1.0 pi) ;初值
    )
    (if (and (= htbz "H") (= yh "N")) (setq x1 (* 2.0 pi)))
    (if (= htbz "L") (setq x1 (* 2.0 pi)))
    ;(if (wcmatch htbz "L,C") (setq x1 (* 2.0 pi)))
    ;牛顿迭代法求圆心角
    (while (> (abs (- x1 x)) eps)
       (setq x x1)
       (if (= htbz "L" )
         ;已知圆弧长度及弦长的迭代
         (setq fx(- (* 2.0 l (sin (/ x 2.0))) (* c x))
               dfx (- (*   l (cos (/ x 2.0))) c)
         )
         (if (= htbz "H")
               ;已知圆弧长度及弓高的迭代
               (setq fx(- l (* l (cos (* 0.5 x))) (* h x))
                     dfx (-   (* 0.5 l (sin (* 0.5 x))) h)
               )
               ;已知圆弦长及弓高的迭代
               (setq fx(- (* 2.0 h (sin (* 0.5 x)))(* -1.0 c (cos (* 0.5 x))) c)
                     dfx (- (*   h (cos (* 0.5 x)))(*0.5 c (sin (* 0.5 x))))
               )
         )
       )
       (setq x1 (- x (/ fx dfx)))
    )
    ;由圆心角计算出半径
    (if (wcmatch htbz "L,H")
      (setq r (/ l x1))
      (setq r   (/ c 2.0 (sin (* 0.5 x1))))
    )
    (princ "\n解算出的半径R=")(princ (rtos r 2 10))
    ;根据已知数据及解算出的圆心角、半径计算弓高
    (if (= htbz "L") (setq h (* r (1- (cos (* 0.5 x1))))))
    (if (= htbz "H")
      (progn
         (setq c (* 2.0 r (sin (* 0.5 x1))))
         (if (< (abs (- x1 (* 2.0 pi))) 1e-6) (setq c (* 2.0 r)))
      )
    )
    ;根据指定的点、已知及解算出的数据计算圆弧的中点、止点
    (setq pt1 (getpoint "\n起点:")
          pt3(polar pt1 0 c)
          ptm(polar pt1 0 (* 0.5 c))
          pt2(polar ptm (* 0.5 pi) h)
    )
    (setvar "osmode" 0);关闭对象捕捉功能
    ;调用CAD已有的三点画圆弧命令画圆弧
    (command "_arc" pt1 pt2 pt3)
    (setvar "osmode" 33);设置对象捕捉(捕捉端点和交点)
    (princ "\n止点方向:")
    ;动态将圆弧旋转到指定方向
    (command "_rotate" (entlast) "" pt1 "r" pt1 pt3 pause)
    (command "_undo" "e");设置撤消命令的止点
    (mapcar 'setvar xtblm xtblz);恢复系统变量的原始值
    (princ)
)

lawrence 发表于 2015-11-23 21:04:58

yshf 发表于 2015-11-23 19:57 static/image/common/back.gif
对照检查一下:

这个计算有误吧:
弦长:20
弓高:5
解算出的半径R=1.1797576798E+17

半径应是R12.5才对

yshf 发表于 2015-11-23 22:36:35

本帖最后由 yshf 于 2015-11-23 22:44 编辑

将:;(if (= htbz "L") (setq x1 (* 2.0 pi)))
    (if (wcmatch htbz "L,C") (setq x1 (* 2.0 pi)))改为:(if (= htbz "L") (setq x1 (* 2.0 pi)))
    ;(if (wcmatch htbz "L,C") (setq x1 (* 2.0 pi)))试一试。

命令: arc1
画弧方式<L>:c
弦长:20
弓高:5
初值=3.141592653589793
解算出的半径R=12.5000000000
起点:
止点方向:

zgzzsn 发表于 2015-11-24 08:35:32

本帖最后由 zgzzsn 于 2015-11-24 08:36 编辑

可算遇到高手了。而且忙到深更半夜。
谢谢楼上各位帮忙。
请把您最后调试成功的lsp传上来,好吗?
页: [1] 2
查看完整版本: 已知圆弧的弧长及弦长、弧长及弓高、弦长及弓高,求半径及画圆弧, 请高手帮忙调试...