剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入了筑基中期的修炼,
这次要修炼的目标是[全等三角形]。
只要已知两条边或是两个角,或是三条边,小伟总能画出个三角形来。
效果是:

这个完全一样。



本节到此结束,欲知后事如何,请看下回分解。
[机器小伟]在[工程师阿伟]的陪同下进入了筑基中期的修炼,
这次要修炼的目标是[全等三角形]。
正剧开始:
星历2016年03月10日 12:44:32, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[全等三角形]。
为了和[人叫板老师]一样来探究这个全等的条件,小伟下了大力气专门做了一个三角形的工具。
首先是需要用到的顶点排序:
<span style="font-size:18px;">this.angleDraw = function(array, style, scale) {
style = style ? style : 'black';
//array是一个存放二维坐标点序列的数组
var a0 = [].concat(array);
scale = scale ? scale : 1;
var len = a0.length;
if (scale != 1 && scale > 0) {
for (var i = 0; i < len; i++) {
for (var j = 0; j < 2; j++) {
a0[i][j]*=scale;
}
}
}
//进行环状排序,这样传入的array就可以任意顺序放置坐标点。
var a = this.angularSort(a0);
//分两次绘点和连线
var tmp = [].concat(a);
this.pointDraw(tmp, style);
tmp = [].concat(a);
this.strokeDraw(tmp, style);
var d1, d2, d3, angle;
var x1,y1, x2, y2, x3, y3;
var s;
//坐标点编号
var s0 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
//为每个点利用余弦定理求角
for (var i = 0; i < len; i++) {
if (i == 0) {
x1 = a[len-1][0];
y1 = a[len-1][1];
x3 = a[i+1][0];
y3 = a[i+1][1];
}
else if (i == len-1) {
x1 = a[i-1][0];
y1 = a[i-1][1];
x3 = a[0][0];
y3 = a[0][1];
}
else {
x1 = a[i-1][0];
y1 = a[i-1][1];
x3 = a[i+1][0];
y3 = a[i+1][1];
}
x2 = a[i][0];
y2 = a[i][1];
d1 = (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
d2 = (x2-x3)*(x2-x3)+(y2-y3)*(y2-y3);
d3 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
angle = Math.acos((d1+d2-d3)/(2*Math.sqrt(d1*d2)))/Math.PI*180;
s = angle.toFixed(2)+'°';
//document.write(s+'<p>');
//标注角度和顶点编号
plot.fillText(s, x2, -y2-5, 100);
plot.fillText(s0[i], x2, -y2+20, 20);
}
}</span>
接下来是这个工具:
<span style="font-size:18px;">function Triangle() {
this.edges = [];
this.angles = [];
//已知三条边
this.know3edges = function(edges) {
this.edges = edges;
//角度为弧度单位
//a边对应角
this.angles.push(Math.acos((edges[1]*edges[1] + edges[2]*edges[2]-edges[0]*edges[0])/(2*edges[1]*edges[2])));
//b边对应角
this.angles.push(Math.acos((edges[0]*edges[0] + edges[2]*edges[2]-edges[1]*edges[1])/(2*edges[0]*edges[2])));
//c边对应角
this.angles.push(Math.acos((edges[0]*edges[0] + edges[1]*edges[1]-edges[2]*edges[2])/(2*edges[0]*edges[1])));
var x0 = 0, y0 = 0;
var x1 = x0 + this.edges[0], y1 = y0;
var x2 = x0 + this.edges[1] * Math.cos(-this.angles[2]),
y2 = y0 + this.edges[1] * Math.sin(-this.angles[2]);
var retArray = new Array();
retArray.push([x0, y0]);
retArray.push([x1, y1]);
retArray.push([x2, y2]);
return retArray;
}
//已知两个角
this.know2angles = function(angles, r) {
this.angles = [angles[0]/180*Math.PI, angles[1]/180*Math.PI,
(180-(angles[0]+angles[1]))/180*Math.PI];
//设其中一边长度为10
r = r > 0 ? r : 10;
//A边
this.edges.push(r);
var angleA = this.angles[0];
angleB = this.angles[1];
angleC = this.angles[2];
//B边
this.edges.push(Math.sin(angleB)/Math.sin(angleA)*r);
//C边
this.edges.push(Math.sin(angleC)/Math.sin(angleA)*r);
var x0 = 0, y0 = 0;
var x1 = x0 + this.edges[0], y1 = y0;
var x2 = x0 + this.edges[1] * Math.cos(-this.angles[2]),
y2 = y0 + this.edges[1] * Math.sin(-this.angles[2]);
var retArray = new Array();
retArray.push([x0, y0]);
retArray.push([x1, y1]);
retArray.push([x2, y2]);
return retArray;
}
//已知2条边
this.know2edges = function(edges, angle) {
//如果没有指定两边的夹角,默认为90度
angle = angle ? angle/180*Math.PI : Math.PI/2;
var edgeC = Math.sqrt(edges[0]*edges[0]+edges[1]*edges[1]-2*edges[0]*edges[1]*Math.cos(angle));
this.edges = [edges[0], edges[1], edgeC];
var edgeA = this.edges[0],
edgeB = this.edges[1];
//角度为弧度单位
//a边对应角
this.angles.push(Math.acos((edgeB*edgeB + edgeC*edgeC-edgeA*edgeA)/(2*edgeB*edgeC)));
//b边对应角
this.angles.push(Math.acos((edgeA*edgeA + edgeC*edgeC-edgeB*edgeB)/(2*edgeA*edgeC)));
//c边对应角
this.angles.push(angle);
var x0 = 0, y0 = 0;
var x1 = x0 + this.edges[0], y1 = y0;
var x2 = x0 + this.edges[1] * Math.cos(-this.angles[2]),
y2 = y0 + this.edges[1] * Math.sin(-this.angles[2]);
var retArray = new Array();
retArray.push([x0, y0]);
retArray.push([x1, y1]);
retArray.push([x2, y2]);
return retArray;
}
//返回角度和边信息的字符串
this.info = function() {
var angleLabel = ['C', 'A', 'B'];
var edgeLabel = ['ab', 'bc', 'ac'];
var s = '';
for (var i = 0; i < 3; i++) {
s += edgeLabel[i]+' : ';
s += this.edges[i].toFixed(2)+' ; ';
}
for (var i = 0; i < 3; i++) {
s += angleLabel[i]+' : ';
s += (this.angles[i]*180/Math.PI).toFixed(2) + ' ; ';
}
return s;
}
}</span>
只要已知两条边或是两个角,或是三条边,小伟总能画出个三角形来。
这样就可以跟着[人叫板老师]一起做了。先来三条边的:
<span style="font-size:18px;">function myDraw(xGlobal, yGlobal) {
var config = new PlotConfiguration();
config.init();
config.setPreference();
var r = 20;
config.setSector(1,1,1,1);
config.graphPaper2D(0, 0, r);
config.axis2D(0, 0,180);
var triangle = new Triangle();
var a = triangle.know3edges([2, 5, 6]);
var tmp = [].concat(a);
shape.angleDraw(tmp, 'red', 2*r);
var s = triangle.info();
plot.fillText(s, -250, 150, 500);
}</span>
效果是:
但这个角度好像有微小差别,到底小伟有没有错呢?
先验证[人叫板老师]的角度:
<span style="font-size:18px;">function myDraw(xGlobal, yGlobal) {
var config = new PlotConfiguration();
config.init();
config.setPreference();
var r = 20;
config.setSector(1,1,1,1);
config.graphPaper2D(0, 0, r);
config.axis2D(0, 0,180);
var triangle = new Triangle();
var a = triangle.know2angles([51.34, 110.46], 5);
var tmp = [].concat(a);
shape.angleDraw(tmp, 'red', 2*r);
var s = triangle.info();
plot.fillText(s, -250, 150, 500);
}</span>
再验证小伟的角度:
<span style="font-size:18px;">function myDraw(xGlobal, yGlobal) {
var config = new PlotConfiguration();
config.init();
config.setPreference();
var r = 20;
config.setSector(1,1,1,1);
config.graphPaper2D(0, 0, r);
config.axis2D(0, 0,180);
var triangle = new Triangle();
var a = triangle.know2angles([51.32, 110.49], 5);
var tmp = [].concat(a);
shape.angleDraw(tmp, 'red', 2*r);
var s = triangle.info();
plot.fillText(s, -250, 150, 500);
}</span>
可以看到边长都是完全一样的,或许,这就是传说中的误差允许范围吧。
接着看:
<span style="font-size:18px;">function myDraw(xGlobal, yGlobal) {
var config = new PlotConfiguration();
config.init();
config.setPreference();
var r = 20;
config.setSector(1,1,1,1);
config.graphPaper2D(0, 0, r);
config.axis2D(0, 0,180);
var triangle = new Triangle();
var a = triangle.know2edges([4, 5], 75);
var tmp = [].concat(a);
shape.angleDraw(tmp, 'red', r);
var s = triangle.info();
plot.fillText(s, -250, 150, 500);
}</span>
这个完全一样。
当然,如果只给定两条边,小伟就可以默认它是直角三角形了:
<span style="font-size:18px;">function myDraw(xGlobal, yGlobal) {
var config = new PlotConfiguration();
config.init();
config.setPreference();
var r = 20;
config.setSector(1,1,1,1);
config.graphPaper2D(0, 0, r);
config.axis2D(0, 0,180);
var triangle = new Triangle();
var a = triangle.know2edges([4, 5], 75);
var tmp = [].concat(a);
shape.angleDraw(tmp, 'red', r);
var s = triangle.info();
plot.fillText(s, -250, 150, 500);
}</span>
<span style="font-size:18px;">function myDraw(xGlobal, yGlobal) {
var config = new PlotConfiguration();
config.init();
config.setPreference();
var r = 20;
config.setSector(1,1,1,1);
config.graphPaper2D(0, 0, r);
config.axis2D(0, 0,180);
var triangle = new Triangle();
var a = triangle.know2angles([45, 75], 5);
var tmp = [].concat(a);
shape.angleDraw(tmp, 'red', r);
var s = triangle.info();
plot.fillText(s, -250, -100, 500);
}
</span>
<span style="font-size:18px;">//xGlobal, yGlobal是传入自页面的全局地图坐标,不一定需要用上。
function myDraw(xGlobal, yGlobal) {
var config = new PlotConfiguration();
config.init();
config.setPreference();
var r = 20;
config.setSector(1,1,1,1);
config.graphPaper2D(0, 0, r);
config.axis2D(0, 0,180);
var r0 = 10*r, r1 = r0*0.707, r2 = r1*1.414/1.848;
shape.fillDraw(shape.nEdge(0, 0, r0, 4), 'blue');
shape.fillDraw(shape.nEdge(0, 0, r1, 4, Math.PI/4), 'pink');
var a = shape.paraquad(0, 0, 0, r2, r2, Math.PI/4);
var tmp;
for (var i = 0; i < 4; i++) {
plot.save()
.rotate(-Math.PI*3/8-Math.PI/2*i);
tmp = [].concat(a);
shape.fillDraw(tmp, 'red');
plot.restore();
}
}</span>
<span style="font-size:18px;">function myDraw(xGlobal, yGlobal) {
var config = new PlotConfiguration();
config.init();
config.setPreference();
var r = 20;
config.setSector(1,1,1,1);
config.graphPaper2D(0, 0, r);
config.axis2D(0, 0,180);
var triangle = new Triangle();
var a = triangle.know2angles([22.5, 22.5], 5);
var tmp = [].concat(a);
shape.angleDraw(tmp, 'red', r);
var s = triangle.info();
plot.fillText(s, -250, 150, 500);
}</span>
<span style="font-size:18px;">function myDraw(xGlobal, yGlobal) {
var config = new PlotConfiguration();
config.init();
config.setPreference();
var r = 75;
config.setSector(1,1,1,1);
config.graphPaper2D(0, 0, r);
config.axis2D(0, 0,180);
var a = [[-r, 0], [r, 0], [0, r], [0, -2*r]];
shape.angleDraw(a, 'red');
}</span>
本节到此结束,欲知后事如何,请看下回分解。