Joseflin 发表于 2006-10-4 09:58:00

【自我挑戰93】

求a b c值:

highflybir 发表于 2006-10-7 16:07:00

<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>&nbsp;</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>&nbsp;</P>
<P>这个题目的解题方法是同AHLZL的那个题目一样的,我重新发一次。但方法较简略,直接用了计算法:因为(60+50+40)/2=75,所以乘了个75 ,半径也取了75 ,这样省去了Sqrt(边长)的几何画法步骤和缩放步骤。</P>
<P>这种方法适用于所有的三角形。</P>
<P>&nbsp;</P>

ahlzl 发表于 2006-10-7 16:25:00

<P>这个程序是两年前写的。</P>
<P>并不是很完美,当一个内角接近180度时,CAD会死掉(现在不想花精力修正了)</P>
<P>Sub try()<BR>&nbsp;&nbsp;&nbsp; Dim PA, PB, PC As Variant<BR>&nbsp;&nbsp;&nbsp; PA = ThisDrawing.Utility.GetPoint(, vbCrLf &amp; "请输入三角形的第一个角点:")<BR>&nbsp;&nbsp;&nbsp; PB = ThisDrawing.Utility.GetPoint(, vbCrLf &amp; "请输入三角形的第二个角点:")<BR>&nbsp;&nbsp;&nbsp; PC = ThisDrawing.Utility.GetPoint(, vbCrLf &amp; "请输入三角形的第三个角点:")<BR>&nbsp;&nbsp;&nbsp; pi = 3.1415926535<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; '获得三个内角<BR>&nbsp;&nbsp;&nbsp; Dim aa As Double, bb As Double, cc As Double<BR>&nbsp;&nbsp;&nbsp; aa = Abs(ThisDrawing.Utility.AngleFromXAxis(PA, PB) _<BR>&nbsp;&nbsp;&nbsp; - ThisDrawing.Utility.AngleFromXAxis(PA, PC))<BR>&nbsp;&nbsp;&nbsp; If aa &gt; pi Then aa = 2 * pi - aa<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; bb = Abs(ThisDrawing.Utility.AngleFromXAxis(PB, PA) _<BR>&nbsp;&nbsp;&nbsp; - ThisDrawing.Utility.AngleFromXAxis(PB, PC))<BR>&nbsp;&nbsp;&nbsp; If bb &gt; pi Then bb = 2 * pi - bb<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; cc = Abs(ThisDrawing.Utility.AngleFromXAxis(PC, PB) _<BR>&nbsp;&nbsp;&nbsp; - ThisDrawing.Utility.AngleFromXAxis(PC, PA))<BR>&nbsp;&nbsp;&nbsp; If cc &gt; pi Then cc = 2 * pi - cc<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; '获得三边的长度<BR>&nbsp;&nbsp;&nbsp; Dim a As Double, d As Double, c As Double<BR>&nbsp;&nbsp;&nbsp; a = dis(PB, PC)<BR>&nbsp;&nbsp;&nbsp; b = dis(PC, PA)<BR>&nbsp;&nbsp;&nbsp; c = dis(PA, PB)<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; '赋初值<BR>&nbsp;&nbsp;&nbsp; Dim R1 As Double, R2 As Double, R3 As Double, R11 As Double<BR>&nbsp;&nbsp;&nbsp; R1 = 0.005 * (dis(PA, PB) + dis(PB, PC) + dis(PC, PA))<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; '中间变量<BR>&nbsp;&nbsp;&nbsp; Dim ta As Double, tb As Double, tc As Double<BR>&nbsp;&nbsp;&nbsp; ta = 1 / Tan(aa / 2): tb = 1 / Tan(bb / 2): tc = 1 / Tan(cc / 2)<BR>&nbsp;&nbsp;&nbsp; R11 = R1<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; Dim S2 As Double, S3 As Double<BR>&nbsp;&nbsp;&nbsp; Dim LR2 As Double, LR3 As Double<BR>&nbsp;&nbsp;&nbsp; Do<BR>&nbsp;&nbsp;&nbsp; R1 = R11<BR>&nbsp;&nbsp;&nbsp; S2 = (4 - 4 * ta * tb) * R1 * R1 + 4 * c * tb<BR>&nbsp;&nbsp;&nbsp; S3 = (4 - 4 * tc * ta) * R1 * R1 + 4 * b * tc<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; R2 = (-2 * R1 + Sqr(S2)) / (2 * tb)<BR>&nbsp;&nbsp;&nbsp; R3 = (-2 * R1 + Sqr(S3)) / (2 * tc)<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; LR2 = -1 / ta + (2 * (4 - 4 * ta * tb) * R1) / (4 * ta * Sqr(S2))<BR>&nbsp;&nbsp;&nbsp; LR3 = -1 / tc + (2 * (4 - 4 * tc * ta) * R1) / (4 * tc * Sqr(S3))<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; fx = tb * R2 * R2 + tc * R3 * R3 + 2 * R2 * R3 - a<BR>&nbsp;&nbsp;&nbsp; flx = 2 * tb * R2 * LR2 + 2 * tc * R3 * LR3 + 2 * R2 * LR3 + 2 * R3 * LR2<BR>&nbsp;&nbsp;&nbsp; R11 = R1 - fx / flx<BR>&nbsp;&nbsp;&nbsp; Loop While Abs(R11 - R1) &gt; 0.0000000000001<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; Dim paa(2) As Double, pbb(2) As Double, pcc(2) As Double<BR>&nbsp;&nbsp;&nbsp; Dim Dab, Dbc, Dca As Double<BR>&nbsp;&nbsp;&nbsp; Dab = dis(PC, PA) / dis(PC, PB)<BR>&nbsp;&nbsp;&nbsp; Dbc = dis(PA, PB) / dis(PA, PC)<BR>&nbsp;&nbsp;&nbsp; Dca = dis(PB, PC) / dis(PB, PA)<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; paa(0) = (PB(0) + Dbc * PC(0)) / (1 + Dbc)<BR>&nbsp;&nbsp;&nbsp; paa(1) = (PB(1) + Dbc * PC(1)) / (1 + Dbc)<BR>&nbsp;&nbsp;&nbsp; pbb(0) = (PC(0) + Dca * PA(0)) / (1 + Dca)<BR>&nbsp;&nbsp;&nbsp; pbb(1) = (PC(1) + Dca * PA(1)) / (1 + Dca)<BR>&nbsp;&nbsp;&nbsp; pcc(0) = (PA(0) + Dab * PB(0)) / (1 + Dab)<BR>&nbsp;&nbsp;&nbsp; pcc(1) = (PA(1) + Dab * PB(1)) / (1 + Dab)<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; Dim Aang As Double, Bang As Double, Cang As Double<BR>&nbsp;&nbsp;&nbsp; Aang = ThisDrawing.Utility.AngleFromXAxis(PA, paa)<BR>&nbsp;&nbsp;&nbsp; Bang = ThisDrawing.Utility.AngleFromXAxis(PB, pbb)<BR>&nbsp;&nbsp;&nbsp; Cang = ThisDrawing.Utility.AngleFromXAxis(PC, pcc)<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; Dim p1, p2, p3 As Variant<BR>&nbsp;&nbsp;&nbsp; p1 = ThisDrawing.Utility.PolarPoint(PA, Aang, R1 * R1 / Sin(aa / 2))<BR>&nbsp;&nbsp;&nbsp; p2 = ThisDrawing.Utility.PolarPoint(PB, Bang, R2 * R2 / Sin(bb / 2))<BR>&nbsp;&nbsp;&nbsp; p3 = ThisDrawing.Utility.PolarPoint(PC, Cang, R3 * R3 / Sin(cc / 2))<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; Dim c1 As AcadCircle, c2 As AcadCircle, c3 As AcadCircle<BR>&nbsp;&nbsp;&nbsp; Set c1 = ThisDrawing.ModelSpace.AddCircle(p1, R1 * R1)<BR>&nbsp;&nbsp;&nbsp; Set c2 = ThisDrawing.ModelSpace.AddCircle(p2, R2 * R2)<BR>&nbsp;&nbsp;&nbsp; Set c3 = ThisDrawing.ModelSpace.AddCircle(p3, R3 * R3)</P>
<P>End Sub<BR>Function dis(PA, PB As Variant) As Double<BR>&nbsp;&nbsp;&nbsp; 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>

highflybir 发表于 2006-10-7 22:23:00

本帖最后由 作者 于 2006-11-2 19:12:11 编辑 <br /><br /> <P></P>
<P>我也发一个lisp程序,与版主PK一下,检测我lisp学得怎么样了。</P>
<P>加载程序,运行:mal</P>
<P>;;*****************************************************************************<BR>;;求各切点到各顶点距离---------------------------------------------------------<BR>(defun C:Mal (/&nbsp;&nbsp;&nbsp; pa&nbsp;pb&nbsp;&nbsp; pc&nbsp;&nbsp; a&nbsp;&nbsp;&nbsp; b&nbsp;&nbsp;&nbsp; c&nbsp; p&nbsp;&nbsp;&nbsp; xa&nbsp;&nbsp; xb&nbsp;xc<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ya&nbsp;&nbsp; yb&nbsp;yc&nbsp;&nbsp; aga&nbsp; agb&nbsp; agc&nbsp; ang&nbsp; ta&nbsp;&nbsp; tb&nbsp;&nbsp; tc&nbsp;ja<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jb&nbsp;&nbsp; jc&nbsp;ha&nbsp;&nbsp; hb&nbsp;&nbsp; hc&nbsp;&nbsp; vpa&nbsp; vpb&nbsp; vpc&nbsp; cen&nbsp; ra&nbsp;rb<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rc&nbsp;&nbsp; la&nbsp;lb&nbsp;&nbsp; lc&nbsp;&nbsp; cena cenb cenc<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<BR>&nbsp; ;;(defun C:Mal ()<BR>&nbsp; (graphscr)<BR>&nbsp; (setq oldmode (getvar "osmode"))<BR>&nbsp; (setq oce (getvar "cmdecho"))<BR>&nbsp; (setvar "cmdecho" 0)<BR>&nbsp; ;;输入数据<BR>&nbsp; (command ".ucs" "W")<BR>&nbsp; (setq pa (getpoint "请输入第一点:\n"))<BR>&nbsp; (setq pb (getpoint "请输入第二点:\n"))<BR>&nbsp; (setq pc (getpoint "请输入第三点:\n"))<BR>&nbsp; (command ".ucs" "O" pa)<BR>&nbsp; (setq&nbsp;pa (trans pa 0 1)<BR>&nbsp;pb (trans pb 0 1)<BR>&nbsp;pc (trans pc 0 1)<BR>&nbsp; )<BR>&nbsp; ;;求三角形边长和半周长&nbsp; <BR>&nbsp; (setq&nbsp;a (distance pb pc)<BR>&nbsp;b (distance pc pa)<BR>&nbsp;c (distance pa pb)<BR>&nbsp;p (/ (+ a b c) 2)<BR>&nbsp; )<BR>&nbsp; ;;计算切线长<BR>&nbsp; (setq&nbsp;xa (sqrt (- (* p p) (* p a)))<BR>&nbsp;xb (sqrt (- (* p p) (* p b)))<BR>&nbsp;xc (sqrt (- (* p p) (* p c)))<BR>&nbsp; )<BR>&nbsp; (setq&nbsp;ya (sqrt (* p a))<BR>&nbsp;yb (sqrt (* p b))<BR>&nbsp;yc (sqrt (* p c))<BR>&nbsp; )<BR>&nbsp; (setq&nbsp;aga (angle '(0 0) (list xa ya))<BR>&nbsp;agb (angle '(0 0) (list xb yb))<BR>&nbsp;agc (angle '(0 0) (list xc yc))<BR>&nbsp; )<BR>&nbsp; (setq ang (/ (+ aga agb agc) 2))<BR>&nbsp; (setq ta (* p (* (sin (- ang aga))) (* (sin (- ang aga)))))<BR>&nbsp; (setq tb (* p (* (sin (- ang agb))) (* (sin (- ang agb)))))<BR>&nbsp; (setq tc (* p (* (sin (- ang agc))) (* (sin (- ang agc)))))<BR>&nbsp; ;;***************************************************************************<BR>&nbsp; ;;求三角形内心---------------------------------------------------------------<BR>&nbsp; (defun cen_incir (pa pb pc)<BR>&nbsp;&nbsp;&nbsp; (setq jc (angle pa pb)<BR>&nbsp;&nbsp; ja (angle pb pc)<BR>&nbsp;&nbsp; jb (angle pc pa)<BR>&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp; (setq ha (/ (+ jb jc pi) 2)<BR>&nbsp;&nbsp; hb (/ (+ jc ja pi) 2)<BR>&nbsp;&nbsp; hc (/ (+ ja jb pi) 2)<BR>&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp; (setq vpa (polar pa ha 1)<BR>&nbsp;&nbsp; vpb (polar pb hb 1)<BR>&nbsp;&nbsp; vpc (polar pc hc 1)<BR>&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp; (inters pa vpa pb vpb nil)<BR>&nbsp; )<BR>&nbsp; (setq cen (cen_incir pa pb pc))<BR>&nbsp; ;;***************************************************************************<BR>&nbsp; ;;求每个圆的半径,圆心位置---------------------------------------------------<BR>&nbsp; (defun tan (x)<BR>&nbsp;&nbsp;&nbsp; (/ (sin x) (cos x))<BR>&nbsp; )<BR>&nbsp; ;;定义正切函数<BR>&nbsp; (if (&gt; 1e-16<BR>&nbsp; (abs (* (sin (- jb jc)) (sin (- jc ja)) (sin (- ja jb))))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp; (progn (alert "你输入的三点在一条直线上,请重新输入!")<BR>&nbsp;&nbsp;&nbsp; (command ".UCS" "P")<BR>&nbsp;&nbsp;&nbsp; (command ".UCS" "P")<BR>&nbsp;&nbsp;&nbsp; (setvar "osmode" oldmode)<BR>&nbsp;&nbsp;&nbsp; (setvar "cmdecho" oce)<BR>&nbsp;&nbsp;&nbsp; (princ)<BR>&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp; ;;判断输入的三点是否在同一条直线上<BR>&nbsp;&nbsp;&nbsp; (progn<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq ra (* ta (/ 1 (abs (tan (/ (- jb jc) 2))))))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq rb (* tb (/ 1 (abs (tan (/ (- jc ja) 2))))))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq rc (* tc (/ 1 (abs (tan (/ (- ja jb) 2))))))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (if (= 0 (abs (* ra rb rc)))<BR>&nbsp;(progn (princ "你输入的三点在一条直线上,请重新输入!")<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setvar "cmdecho" oce)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setvar "osmode" oldmode)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (princ)<BR>&nbsp;)<BR>&nbsp;;;判断圆的半径是否为零<BR>&nbsp;(progn<BR>&nbsp;&nbsp; (defun gougu (x y)<BR>&nbsp;&nbsp;&nbsp;&nbsp; (sqrt (+ (* x x) (* y y)))<BR>&nbsp;&nbsp; )<BR>&nbsp;&nbsp; (setq&nbsp;la (gougu ta ra)<BR>&nbsp;&nbsp;lb (gougu tb rb)<BR>&nbsp;&nbsp;lc (gougu tc rc)<BR>&nbsp;&nbsp; )<BR>&nbsp;&nbsp; (setq&nbsp;cena (polar pa (angle pa cen) la)<BR>&nbsp;&nbsp;cenb (polar pb (angle pb cen) lb)<BR>&nbsp;&nbsp;cenc (polar pc (angle pc cen) lc)<BR>&nbsp;&nbsp; )<BR>&nbsp;&nbsp; ;;***********************************************************************<BR>&nbsp;&nbsp; ;;画圆-------------------------------------------------------------------<BR>&nbsp;&nbsp; (setvar "osmode" 0)<BR>&nbsp;&nbsp; (command ".line" pa pb pc "C")<BR>&nbsp;&nbsp; (command ".CIRCLE" cena ra)<BR>&nbsp;&nbsp; (command ".CIRCLE" cenb rb)<BR>&nbsp;&nbsp; (command ".CIRCLE" cenc rc)<BR>&nbsp;&nbsp; (command ".UCS" "P")<BR>&nbsp;&nbsp; (command ".UCS" "P")<BR>&nbsp;&nbsp; (setvar "osmode" oldmode)<BR>&nbsp;&nbsp; (setvar "cmdecho" oce)<BR>&nbsp;&nbsp; (princ)<BR>&nbsp;)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp; )<BR>&nbsp; )<BR>)</P>
<P>附注:我重新检查了lisp程序,增加了一个如果三点在同一条直线的出错判断,我想版主说的在有一个内角接近180度时CAD会出错,可能也与之相关。另外我增加了程序的可读性。版主的VB十分了得 ,我以后还得向版主学习。</P>

ahlzl 发表于 2006-10-7 22:49:00

<P>PK结果:<A name=34799><FONT color=#000066><B>highflybir</B></FONT></A>胜!</P>

zwf9900 发表于 2008-1-6 16:59:00

这题好做!请看我的做法应该是最简单最快的!做法是书上来的!

hejoseph 发表于 2008-1-23 13:28:00

这是著名的Malfatti作图问题,而zwf9900所给的方法是Steiner首先给出的,三角法在《100个著名初等数学问题》里有,通过三角法可以求出三圆的半径。
页: [1]
查看完整版本: 【自我挑戰93】