正剧开始:
星历2016年03月28日 07:41:05, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[圆]。
接着[人叫板老师]提到了怎样画圆:
对于画圆,小伟有自己的方法:
<span style="font-size:18px;"> //画圆 var r = 20; var r0 = 5*r; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0, 180); var triangle = new Triangle(); var transform = new Transform(); config.setSector(1,2,1,1); shape.fillCircle(0, 0, 5*r); config.setSector(1,2,1,2); shape.fillDraw(shape.nEdge(0, 0, 5*r, 36), 'red');</span>
左边的是直接调用画圆API, 右边的是36边的正多边形,看上去没有任何差别是吧。
不过用正多边形可以得到点的坐标阵列的。
下面阿伟看到了曾经学习过的《赵州桥》。
难怪这座桥梁这么漂亮又耐用,原来它的拱是一个90度的圆心角对应的圆弧。
主桥拱半径是26.16米。
怎样求三角形的外心呢?
小伟是这样做的:
<span style="font-size:18px;"> //求三角形的外心 var r = 20; var r0 = 5*r; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0, 180); var triangle = new Triangle(); var transform = new Transform(); //已知三角形边长 var a = 3, b = 4, c = 5; //得到三角形顶点阵列 var array = triangle.know3edges([a, b, c]); //进行缩放转换 array = transform.scale(array, r); //三个顶点 var x1 = array[0][0], y1 = array[0][1], x2 = array[1][0], y2 = array[1][1], x3 = array[2][0], y3 = array[2][1]; //令 var A1 = 2*(x2-x1), B1 = 2*(y2-y1), C1 = x2*x2+y2*y2-x1*x1-y1*y1, A2 = 2*(x3-x2), B2 = 2*(y3-y2), C2 = x3*x3+y3*y3-x2*x2-y2*y2; //得到外心的坐标 var px = ((C1*B2)-(C2*B1))/((A1*B2)-(A2*B1)), py = ((A1*C2)-(A2*C1))/((A1*B2)-(A2*B1)); //外接圆半径 var rOut = a*b*c/Math.sqrt(4*b*b*c*c-Math.pow((b*b+c*c-a*a), 2)); rOut *= r; //document.write(px.toFixed(2)+', '+py.toFixed(2)+'; ' + rOut.toFixed(2)); shape.strokeDraw([].concat(array), 'red'); shape.strokeCircle(px, -py, rOut);</span>
那如果它的边长为15, 18, 21呢?
<span style="font-size:18px;"> //求三角形的外心 var r = 20; var r0 = 5*r; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0, 180); var triangle = new Triangle(); var transform = new Transform(); //已知三角形边长 var a = 15, b = 18, c = 21; //得到三角形顶点阵列 var array = triangle.know3edges([a, b, c]); //进行缩放转换 array = transform.scale(array, r/2); //三个顶点 var x1 = array[0][0], y1 = array[0][1], x2 = array[1][0], y2 = array[1][1], x3 = array[2][0], y3 = array[2][1]; //令 var A1 = 2*(x2-x1), B1 = 2*(y2-y1), C1 = x2*x2+y2*y2-x1*x1-y1*y1, A2 = 2*(x3-x2), B2 = 2*(y3-y2), C2 = x3*x3+y3*y3-x2*x2-y2*y2; //得到外心的坐标 var px = ((C1*B2)-(C2*B1))/((A1*B2)-(A2*B1)), py = ((A1*C2)-(A2*C1))/((A1*B2)-(A2*B1)); //外接圆半径 var rOut = a*b*c/Math.sqrt(4*b*b*c*c-Math.pow((b*b+c*c-a*a), 2)); //与顶点矩阵相同的变换 rOut*=r/2; //document.write(px.toFixed(2)+', '+py.toFixed(2)+'; ' + rOut.toFixed(2)); shape.angleDraw([].concat(array), 'red'); shape.strokeCircle(px, -py, rOut);</span>
那么怎样求三角形的内心呢?
小伟是这样做的:
<span style="font-size:18px;"> //求三角形的内心 var r = 20; var r0 = 5*r; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0, 180); var triangle = new Triangle(); var transform = new Transform(); //已知三角形边长 var a = 15, b = 18, c = 21; //与公式的映射关系: //AB=a, BC=b, CA=c; //BC=a, CA=b, AB=c; //得到三角形顶点阵列,注意三条边的给定顺序,如果不对要调整 var array = triangle.know3edges([c, b, a]); //进行缩放转换 array = transform.scale(array, r/2); //三个顶点 var x1 = array[0][0], y1 = array[0][1], x2 = array[1][0], y2 = array[1][1], x3 = array[2][0], y3 = array[2][1]; //得到内心的坐标 var px = (a*x1+b*x2+c*x3)/(a+b+c), py = (a*y1+b*y2+c*y3)/(a+b+c); //内切圆半径 var S = Math.sqrt((a+b+c)*(a+b-c)*(a+c-b)*(b+c-a)); var rIn = S/(a+b+c)/2; //与顶点矩阵相同的变换 rIn*=r/2; //document.write(px.toFixed(2)+', '+py.toFixed(2)+'; ' + rOut.toFixed(2)); shape.angleDraw([].concat(array), 'red'); shape.strokeCircle(px, -py, rIn);</span>
再试一次:
<span style="font-size:18px;"> //六角亭例题 var r = 20; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0, 180); var triangle = new Triangle(); var transform = new Transform(); var array = shape.nEdge(0, 0, 4, 6); shape.angleDraw(array, 'red', r); </span>
下面小伟想来设计一下这条跑道:
<span style="font-size:18px;"> //设计跑道 var r = 25; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0, 180); var triangle = new Triangle(); var transform = new Transform(); var scale = 3; var r0 = 100/Math.PI; var parts = 36; var array = shape.nEdge(0, 0, r0, parts); var array_part1 = array.slice(0, parts/2+2), array_part2 = array.slice(parts/2, parts); array_part2 = array_part2.concat(array.slice(0,2)); array_part1 = transform.translate(array_part1, 50, 0); array_part2 = transform.translate(array_part2, -50, 0); var rect = [[-50, -r0], [50, -r0], [50, r0], [-50, r0]]; shape.multiLineDraw(array_part1, 'red', scale); shape.multiLineDraw(array_part2, 'red', scale); shape.strokeDraw(rect, 'red', scale); for (var i = 2; i < 8; i+=2) { r0 = (100+4*i)/Math.PI; array = shape.nEdge(0, 0, r0, parts); array_part1 = array.slice(0, parts/2+2), array_part2 = array.slice(parts/2, parts); array_part2 = array_part2.concat(array.slice(0,2)); array_part1 = transform.translate(array_part1, 50, 0); array_part2 = transform.translate(array_part2, -50, 0); rect = [[-50, -r0], [50, -r0], [50, r0], [-50, r0]]; shape.multiLineDraw(array_part1, 'blue', scale); shape.multiLineDraw(array_part2, 'blue', scale); shape.strokeDraw(rect, 'blue', scale); } r0 = 100/Math.PI; var startPoints = [[-50, -r0-0.5]]; var x = -50, y = -r0-0.5; for (var i = 0; i < 8; i++) { x += 6.28; y -= 1; startPoints.push([x, y]); } shape.pointDraw(startPoints, 'red', scale);</span>
这条跑道的直线部分是100米长,每个半圆的圆周也是100米长,每两条跑道的起点相差是6.28米。
终点线在左边的竖直蓝线处。
但是这里面还有一些小问题,小伟还没想明白。
四点共圆,应该是对角和为180度。
本节到此结束,欲知后事如何,请看下回分解。