【自我挑戰93】
求a b c值: <P></P><P>1、求出切线AH长度,方法见下图;</P>
<P>2、AM为角BAC平分线,MH垂直AB;</P>
<P>3、M为圆心,MH为半径画圆1;</P>
<P>4、相切、相切、相切画其他的圆2,3。</P>
<P>5、擦除辅助线,完成。</P>
<P> </P>
<P>1、OP=75,AE=sqrt(75*60);BF=sqrt(75*50),CG=sqrt(75*40);</P>
<P>2、OM为角COP的角平分线,MJ=KA;</P>
<P>3、在OA的延长线上,作OH=KA;</P>
<P>4、延长KL交过H的垂直线于L。</P>
<P>5、LH就是上图中所要求的切线AH。</P>
<P> </P>
<P>这个题目的解题方法是同AHLZL的那个题目一样的,我重新发一次。但方法较简略,直接用了计算法:因为(60+50+40)/2=75,所以乘了个75 ,半径也取了75 ,这样省去了Sqrt(边长)的几何画法步骤和缩放步骤。</P>
<P>这种方法适用于所有的三角形。</P>
<P> </P> <P>这个程序是两年前写的。</P>
<P>并不是很完美,当一个内角接近180度时,CAD会死掉(现在不想花精力修正了)</P>
<P>Sub try()<BR> Dim PA, PB, PC As Variant<BR> PA = ThisDrawing.Utility.GetPoint(, vbCrLf & "请输入三角形的第一个角点:")<BR> PB = ThisDrawing.Utility.GetPoint(, vbCrLf & "请输入三角形的第二个角点:")<BR> PC = ThisDrawing.Utility.GetPoint(, vbCrLf & "请输入三角形的第三个角点:")<BR> pi = 3.1415926535<BR> <BR> '获得三个内角<BR> Dim aa As Double, bb As Double, cc As Double<BR> aa = Abs(ThisDrawing.Utility.AngleFromXAxis(PA, PB) _<BR> - ThisDrawing.Utility.AngleFromXAxis(PA, PC))<BR> If aa > pi Then aa = 2 * pi - aa<BR> <BR> bb = Abs(ThisDrawing.Utility.AngleFromXAxis(PB, PA) _<BR> - ThisDrawing.Utility.AngleFromXAxis(PB, PC))<BR> If bb > pi Then bb = 2 * pi - bb<BR> <BR> cc = Abs(ThisDrawing.Utility.AngleFromXAxis(PC, PB) _<BR> - ThisDrawing.Utility.AngleFromXAxis(PC, PA))<BR> If cc > pi Then cc = 2 * pi - cc<BR> <BR> '获得三边的长度<BR> Dim a As Double, d As Double, c As Double<BR> a = dis(PB, PC)<BR> b = dis(PC, PA)<BR> c = dis(PA, PB)<BR> <BR> '赋初值<BR> Dim R1 As Double, R2 As Double, R3 As Double, R11 As Double<BR> R1 = 0.005 * (dis(PA, PB) + dis(PB, PC) + dis(PC, PA))<BR> <BR> '中间变量<BR> Dim ta As Double, tb As Double, tc As Double<BR> ta = 1 / Tan(aa / 2): tb = 1 / Tan(bb / 2): tc = 1 / Tan(cc / 2)<BR> R11 = R1<BR> <BR> Dim S2 As Double, S3 As Double<BR> Dim LR2 As Double, LR3 As Double<BR> Do<BR> R1 = R11<BR> S2 = (4 - 4 * ta * tb) * R1 * R1 + 4 * c * tb<BR> S3 = (4 - 4 * tc * ta) * R1 * R1 + 4 * b * tc<BR> <BR> R2 = (-2 * R1 + Sqr(S2)) / (2 * tb)<BR> R3 = (-2 * R1 + Sqr(S3)) / (2 * tc)<BR> <BR> LR2 = -1 / ta + (2 * (4 - 4 * ta * tb) * R1) / (4 * ta * Sqr(S2))<BR> LR3 = -1 / tc + (2 * (4 - 4 * tc * ta) * R1) / (4 * tc * Sqr(S3))<BR> <BR> fx = tb * R2 * R2 + tc * R3 * R3 + 2 * R2 * R3 - a<BR> flx = 2 * tb * R2 * LR2 + 2 * tc * R3 * LR3 + 2 * R2 * LR3 + 2 * R3 * LR2<BR> R11 = R1 - fx / flx<BR> Loop While Abs(R11 - R1) > 0.0000000000001<BR> <BR> Dim paa(2) As Double, pbb(2) As Double, pcc(2) As Double<BR> Dim Dab, Dbc, Dca As Double<BR> Dab = dis(PC, PA) / dis(PC, PB)<BR> Dbc = dis(PA, PB) / dis(PA, PC)<BR> Dca = dis(PB, PC) / dis(PB, PA)<BR> <BR> paa(0) = (PB(0) + Dbc * PC(0)) / (1 + Dbc)<BR> paa(1) = (PB(1) + Dbc * PC(1)) / (1 + Dbc)<BR> pbb(0) = (PC(0) + Dca * PA(0)) / (1 + Dca)<BR> pbb(1) = (PC(1) + Dca * PA(1)) / (1 + Dca)<BR> pcc(0) = (PA(0) + Dab * PB(0)) / (1 + Dab)<BR> pcc(1) = (PA(1) + Dab * PB(1)) / (1 + Dab)<BR> <BR> Dim Aang As Double, Bang As Double, Cang As Double<BR> Aang = ThisDrawing.Utility.AngleFromXAxis(PA, paa)<BR> Bang = ThisDrawing.Utility.AngleFromXAxis(PB, pbb)<BR> Cang = ThisDrawing.Utility.AngleFromXAxis(PC, pcc)<BR> <BR> Dim p1, p2, p3 As Variant<BR> p1 = ThisDrawing.Utility.PolarPoint(PA, Aang, R1 * R1 / Sin(aa / 2))<BR> p2 = ThisDrawing.Utility.PolarPoint(PB, Bang, R2 * R2 / Sin(bb / 2))<BR> p3 = ThisDrawing.Utility.PolarPoint(PC, Cang, R3 * R3 / Sin(cc / 2))<BR> <BR> Dim c1 As AcadCircle, c2 As AcadCircle, c3 As AcadCircle<BR> Set c1 = ThisDrawing.ModelSpace.AddCircle(p1, R1 * R1)<BR> Set c2 = ThisDrawing.ModelSpace.AddCircle(p2, R2 * R2)<BR> Set c3 = ThisDrawing.ModelSpace.AddCircle(p3, R3 * R3)</P>
<P>End Sub<BR>Function dis(PA, PB As Variant) As Double<BR> dis = ((PA(0) - PB(0)) ^ 2 + (PA(1) - PB(1)) ^ 2 + (PA(2) - PB(2)) ^ 2) ^ 0.5<BR>End Function</P>
<P>用VBALOAD命令加载,VBARUN命令运行。</P> 本帖最后由 作者 于 2006-11-2 19:12:11 编辑 <br /><br /> <P></P>
<P>我也发一个lisp程序,与版主PK一下,检测我lisp学得怎么样了。</P>
<P>加载程序,运行:mal</P>
<P>;;*****************************************************************************<BR>;;求各切点到各顶点距离---------------------------------------------------------<BR>(defun C:Mal (/ pa pb pc a b c p xa xb xc<BR> ya yb yc aga agb agc ang ta tb tc ja<BR> jb jc ha hb hc vpa vpb vpc cen ra rb<BR> rc la lb lc cena cenb cenc<BR> )<BR> ;;(defun C:Mal ()<BR> (graphscr)<BR> (setq oldmode (getvar "osmode"))<BR> (setq oce (getvar "cmdecho"))<BR> (setvar "cmdecho" 0)<BR> ;;输入数据<BR> (command ".ucs" "W")<BR> (setq pa (getpoint "请输入第一点:\n"))<BR> (setq pb (getpoint "请输入第二点:\n"))<BR> (setq pc (getpoint "请输入第三点:\n"))<BR> (command ".ucs" "O" pa)<BR> (setq pa (trans pa 0 1)<BR> pb (trans pb 0 1)<BR> pc (trans pc 0 1)<BR> )<BR> ;;求三角形边长和半周长 <BR> (setq a (distance pb pc)<BR> b (distance pc pa)<BR> c (distance pa pb)<BR> p (/ (+ a b c) 2)<BR> )<BR> ;;计算切线长<BR> (setq xa (sqrt (- (* p p) (* p a)))<BR> xb (sqrt (- (* p p) (* p b)))<BR> xc (sqrt (- (* p p) (* p c)))<BR> )<BR> (setq ya (sqrt (* p a))<BR> yb (sqrt (* p b))<BR> yc (sqrt (* p c))<BR> )<BR> (setq aga (angle '(0 0) (list xa ya))<BR> agb (angle '(0 0) (list xb yb))<BR> agc (angle '(0 0) (list xc yc))<BR> )<BR> (setq ang (/ (+ aga agb agc) 2))<BR> (setq ta (* p (* (sin (- ang aga))) (* (sin (- ang aga)))))<BR> (setq tb (* p (* (sin (- ang agb))) (* (sin (- ang agb)))))<BR> (setq tc (* p (* (sin (- ang agc))) (* (sin (- ang agc)))))<BR> ;;***************************************************************************<BR> ;;求三角形内心---------------------------------------------------------------<BR> (defun cen_incir (pa pb pc)<BR> (setq jc (angle pa pb)<BR> ja (angle pb pc)<BR> jb (angle pc pa)<BR> )<BR> (setq ha (/ (+ jb jc pi) 2)<BR> hb (/ (+ jc ja pi) 2)<BR> hc (/ (+ ja jb pi) 2)<BR> )<BR> (setq vpa (polar pa ha 1)<BR> vpb (polar pb hb 1)<BR> vpc (polar pc hc 1)<BR> )<BR> (inters pa vpa pb vpb nil)<BR> )<BR> (setq cen (cen_incir pa pb pc))<BR> ;;***************************************************************************<BR> ;;求每个圆的半径,圆心位置---------------------------------------------------<BR> (defun tan (x)<BR> (/ (sin x) (cos x))<BR> )<BR> ;;定义正切函数<BR> (if (> 1e-16<BR> (abs (* (sin (- jb jc)) (sin (- jc ja)) (sin (- ja jb))))<BR> )<BR> (progn (alert "你输入的三点在一条直线上,请重新输入!")<BR> (command ".UCS" "P")<BR> (command ".UCS" "P")<BR> (setvar "osmode" oldmode)<BR> (setvar "cmdecho" oce)<BR> (princ)<BR> )<BR> ;;判断输入的三点是否在同一条直线上<BR> (progn<BR> (setq ra (* ta (/ 1 (abs (tan (/ (- jb jc) 2))))))<BR> (setq rb (* tb (/ 1 (abs (tan (/ (- jc ja) 2))))))<BR> (setq rc (* tc (/ 1 (abs (tan (/ (- ja jb) 2))))))<BR> (if (= 0 (abs (* ra rb rc)))<BR> (progn (princ "你输入的三点在一条直线上,请重新输入!")<BR> (setvar "cmdecho" oce)<BR> (setvar "osmode" oldmode)<BR> (princ)<BR> )<BR> ;;判断圆的半径是否为零<BR> (progn<BR> (defun gougu (x y)<BR> (sqrt (+ (* x x) (* y y)))<BR> )<BR> (setq la (gougu ta ra)<BR> lb (gougu tb rb)<BR> lc (gougu tc rc)<BR> )<BR> (setq cena (polar pa (angle pa cen) la)<BR> cenb (polar pb (angle pb cen) lb)<BR> cenc (polar pc (angle pc cen) lc)<BR> )<BR> ;;***********************************************************************<BR> ;;画圆-------------------------------------------------------------------<BR> (setvar "osmode" 0)<BR> (command ".line" pa pb pc "C")<BR> (command ".CIRCLE" cena ra)<BR> (command ".CIRCLE" cenb rb)<BR> (command ".CIRCLE" cenc rc)<BR> (command ".UCS" "P")<BR> (command ".UCS" "P")<BR> (setvar "osmode" oldmode)<BR> (setvar "cmdecho" oce)<BR> (princ)<BR> )<BR> )<BR> )<BR> )<BR>)</P>
<P>附注:我重新检查了lisp程序,增加了一个如果三点在同一条直线的出错判断,我想版主说的在有一个内角接近180度时CAD会出错,可能也与之相关。另外我增加了程序的可读性。版主的VB十分了得 ,我以后还得向版主学习。</P> <P>PK结果:<A name=34799><FONT color=#000066><B>highflybir</B></FONT></A>胜!</P> 这题好做!请看我的做法应该是最简单最快的!做法是书上来的! 这是著名的Malfatti作图问题,而zwf9900所给的方法是Steiner首先给出的,三角法在《100个著名初等数学问题》里有,通过三角法可以求出三圆的半径。
页:
[1]