[从头学数学] 第178节 平面向量
2016-04-15 11:32
267 查看
剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入了结丹中期的修炼,
这次要修炼的目标是[平面向量]。
正剧开始:
星历2016年04月15日 10:37:27, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[平面向量]。
'
小伟看到这里,觉得有必要制造一件能够画出向量来的法器,
于是[工程师阿伟]给小伟做了一件:
来看看效果吧:
还不错是吧,为了把这几个箭头的位置摆正确,阿伟可是出了一身的汗。
但是小伟说,这光有图肯定是不行的,这写个表达式神马的还是很必须的。
要怎样把这个箭头写出来呢?
于是,阿伟又做了一件法器:
随着[人叫板老师]教的东西越来越多,现在这些函数是越来越胖了。
不过,这样才能做更多的事。
还是来看看效果:
这些可以这样写出来:
不管写的是不是天书,至少小伟现在能写出箭头了。
下面就可以认真的修炼[人叫板老师]的功法了。
本节到此结束,欲知后事如何,请看下回分解。
[机器小伟]在[工程师阿伟]的陪同下进入了结丹中期的修炼,
这次要修炼的目标是[平面向量]。
正剧开始:
星历2016年04月15日 10:37:27, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[平面向量]。
'
小伟看到这里,觉得有必要制造一件能够画出向量来的法器,
于是[工程师阿伟]给小伟做了一件:
<span style="font-size:18px;">/** * @usage 向量图 * @author mw * @date 2016年04月15日 星期五 08:34:05 * @param 向量点阵 * @return * */ this.vectorDraw = function(array, style, scale) { style = style ? style : 'black'; scale = scale ? scale : 1; var size = array.length; var size_1 = array[0].length; //保证传入点阵中至少有两个点,并且是采用[[x1,y1], [x2,y2]...[xn, yn]]这种格式 if (size < 2 || size_1 != 2) { return; } var x1 = x2 = y1 = y2 = k = thita = 0; //箭头两边与中心线的夹角和长度 var dThita = Math.PI/180*15, dL = 15/scale; var x3 = y3 = x4 = y4 = 0; plot.setStrokeStyle(style) .beginPath(); for (var i = 0; i < size-1; i++) { x1 = array[i][0]; y1 = array[i][1]; x2 = array[i+1][0]; y2 = array[i+1][1]; if (x1 == x2 && y1 == y2) continue; else if (x1 == x2) { thita = Math.PI/2; if (y1 < y2) { thita += Math.PI; } } else { if ((y1 == y2 && x1 < x2)) { thita = Math.PI+Math.atan((y2-y1)/(x2-x1)); } else if ((y1 == y2 && x1 > x2)){ thita = Math.atan((y2-y1)/(x2-x1)); } else if (x1 < x2) { thita = Math.PI+Math.atan((y2-y1)/(x2-x1)); } else { thita = Math.atan((y2-y1)/(x2-x1)); } } x3 = x2 + dL*Math.cos(thita+dThita); y3 = y2 + dL*Math.sin(thita+dThita); x4 = x2 + dL*Math.cos(thita-dThita); y4 = y2 + dL*Math.sin(thita-dThita); plot.moveTo(x1*scale, -y1*scale) .lineTo(x2*scale, -y2*scale) .moveTo(x2*scale, -y2*scale) .lineTo(x3*scale, -y3*scale) .moveTo(x2*scale, -y2*scale) .lineTo(x4*scale, -y4*scale); } plot.closePath() .stroke(); } </span>
来看看效果吧:
<span style="font-size:18px;"> if (1) { var r = 20; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0,190); //坐标轴设定 var scaleX = 2*r, scaleY = 2*r; var spaceX = 2, spaceY = 2; var xS = -10, xE = 10; var yS = -10, yE = 10; config.axisSpacing(xS, xE, spaceX, scaleX, 'X'); config.axisSpacing(yS, yE, spaceY, scaleY, 'Y'); var array = [[1, 2], [4, 5], [7,2], [-8, -5], [-5, 3], [-8, 3], [-8, 5], [-2, 5], [-2, -1], [7, -3], [3, 1]]; var size = array.length; var transform = new Transform(); var tmp = []; array = transform.scale(transform.translate(array, 0, 0), scaleX/spaceX, scaleY/spaceY); tmp = [].concat(array); vectorDraw(tmp, 'red'); tmp = [].concat(array); shape.pointDraw(tmp, 'orange', 1, 1); plot.setFillStyle('blue'); plot.fillText('向量图', -270, -170, 300); }</span>
还不错是吧,为了把这几个箭头的位置摆正确,阿伟可是出了一身的汗。
但是小伟说,这光有图肯定是不行的,这写个表达式神马的还是很必须的。
要怎样把这个箭头写出来呢?
于是,阿伟又做了一件法器:
<span style="font-size:18px;">/** * @usage 数学表达式,代数式的书写 * @author mw * @date 2016年03月12日 星期六 11:05:12 * @param * @return * */ function MathText() { //上标标记形式为...^[内容]... //分数不进行处理, 根式不进行处理,都转成指数式进行 //特殊数学符号设想加\[alpha]进行转义,待续 //可以进行指数上标代数式的书写 //可扩展下标,待续 this.setNormalFont = function() { plot.setFont("normal normal normal 24px Times Lt Std"); } this.setScriptFont = function() { plot.setFont("italic normal bold 16px Dark Courier "); } this.print = function(text, xPos, yPos) { xPos = xPos ? xPos : 0; yPos = yPos ? yPos : 0; plot.save(); var s = text ? text : ''; if (s != '') { s = s.replace(/\/\//ig, '÷'); s = s.replace(/>=/ig, '≥'); s = s.replace(/<=/ig, '≤'); s = s.replace(/!=/ig, '≠'); s = s.replace(/pi/ig, 'π'); } //字符串长度 var len = s.length; //不同字体大小设置在此 var r1 = 20; //单个字符暂存处 var c; //文本显示位置 var x = xPos, y = yPos; //正常文本暂存 var s0 = ''; //字符串打印长度 var measure; //记录上一个x位置,可记录三层 var xMem = [x, x, x]; //记录每一层的左括号位置 var bracketPos = [x, x, x]; //记录括号层次 var bracketsLevel = 0; //记录根号层次 var radicalLevel = 0; //记录每一层根号的起始位置和层次数的数组...[[start, end, level], ...] var radicalSpan = []; //设置正常字体 this.setNormalFont(); for (var i = 0; i < len; i++) { if (s[i] == '_' && s[i+1] == '[') { //下标开始 //下标标记形式为..._[内容]... if (s0 != '') { //先把正常字符打印出 if (r1 != 20) { //字体字号大小还在上标状态 r1 = 20; this.setNormalFont(); } measure = plot.measureText(s0); plot.fillText(s0, x, y, measure); s0 = ''; x += measure; } var subScript = ''; var j = 0; for (j = i+1; s[j]!=']'; j++) { if (s[j] != '[') { subScript+=s[j]; } } if (r1 != 10) {//正常字体状态,需要改为上标字体 r1 = 10; this.setScriptFont(); } measure = plot.measureText(subScript); plot.fillText(subScript, x, y+8, measure); if (j < len-1 && s[j+1] == '^') { } else { x += 1.2*measure; } i = j; } else if (s[i] == '^'&&s[i+1] == '[') { //上标开始 //上标标记形式为...^[内容]... if (s0 != '') { //先把正常字符打印出 if (r1 != 20) { //字体字号大小还在上标状态 r1 = 20; this.setNormalFont(); } measure = plot.measureText(s0); plot.fillText(s0, x, y, measure); s0 = ''; x += measure; } var upperScript = ''; var j = 0; for (j = i+1; s[j]!=']'; j++) { if (s[j] != '[') { upperScript+=s[j]; } } //二次根式 if (upperScript == '1/2' || upperScript == '0.5') { var x1, y1; if (i > 0 && s[i-1] == ')') { x1 = bracketPos[bracketsLevel]; } else { x1 = xMem[bracketsLevel]; } /* 存疑代码 if (radicalSpan == []) { radicalLevel = 0; radicalSpan.push([x1, x, radicalLevel]); } else { var len = radicalSpan.length; for (var k = 0; k < len; k++) { if (x1 < radicalSpan[k][0]) { radicalLevel = radicalSpan[k][2]+1; break; } if (k >= len-1) { radicalLevel = 0; } } radicalSpan.push([x1, x, radicalLevel]); }*/ y1 = y-20-5*radicalLevel; plot.save() .setLineWidth(1); plot.beginPath() .moveTo(x1-5, y+5) .lineTo(x1-8, y-3) .moveTo(x1-5, y+5) .lineTo(x1+5, y1) .moveTo(x1+5, y1) .lineTo(x, y1) .closePath() .stroke(); plot.restore(); } //向量符号 else if (upperScript == '->') { var x1, y1; if (i > 0 && s[i-1] == ')') { x1 = bracketPos[bracketsLevel]; } else { x1 = xMem[bracketsLevel]; } y1 = y-18-5*radicalLevel; plot.save() .setLineWidth(1); plot.beginPath() .moveTo(x1, y1) .lineTo(x+2, y1) .moveTo(x+2, y1) .lineTo(x-5, y1-3) .moveTo(x+2, y1) .lineTo(x-5, y1+3) .closePath() .stroke(); plot.restore(); } else { if (r1 != 10) {//正常字体状态,需要改为上标字体 r1 = 10; this.setScriptFont(); } measure = plot.measureText(upperScript); plot.fillText(upperScript, x, y-8, measure); if (j < len-1 && s[j+1] == '_') { } else { x += 1.2*measure; } } //直接跳跃过上标字符区段 i = j; } else { c = s[i]; if (c == ')') { s0 += c; bracketsLevel -= 1; } else if (c == '(') { //如果整个括号被开根式,根号在括号左边 bracketPos[bracketsLevel] = x + plot.measureText(s0); s0 += c; bracketsLevel+=1; //过了括号就是过了一道关,要刷新坐标 xMem[bracketsLevel] = x + plot.measureText(s0); } else if (c == '+' || c == '-' || c == '*' || c == '/' || c == '÷' || c == '=' || c == ' ') { if (c == '*') { if (i > 0 && /[0-9]/.test(s[i-1]) && /[0-9]/.test(s[i+1])) { //对于乘号前后都是数字的情况,把乘号改成叉号 c = ' \u00D7 '; } else { //对于代数式中,乘号改为点号 c = ' \u00B7 '; } } //如果是运算符后的数被开根式,根号在运算符右边 if (c == '-' || c == '/') { s0 += ' '+c+' '; } else { s0 += c; } if (bracketsLevel < 3) { xMem[bracketsLevel] = x+plot.measureText(s0); } } else if (c == '|') { //隔字符 if (bracketsLevel < 3) { xMem[bracketsLevel] = x+plot.measureText(s0)-3; } } else { s0 += c; } } } if (s0 != '') { //先把正常字符打印出 if (r1 != 20) { //字体字号大小还在上标状态 r1 = 20; this.setNormalFont(); } measure = plot.measureText(s0); plot.fillText(s0, x, y, measure); x += measure; } plot.restore(); } //集合符号,集合表达式的书写 this.printSet = function(text, xpos, ypos) { var s = text ? text : ''; if (s != '') { s = s.replace(/\[B\]/ig, '\u2208'); //∈ s = s.replace(/\[NB\]/ig, '\u2209'); //不属于 s = s.replace(/\[S\]/ig, '\u2286'); //包含于(是子集) s = s.replace(/\[SS\]/ig, '\u2287'); //包含 s = s.replace(/\[ST\]/ig, '\u228A'); //真包含于(是真子集) s = s.replace(/\[SST\]/ig, '\u228B'); //真包含 s = s.replace(/\[UU\]/ig, '\u222A'); //并集 ,由于U表示全集,又常为下标,此处错开 s = s.replace(/\[I\]/ig, '\u2229'); //交集 s = s.replace(/\[C\]/ig, '\u2201'); //补集 s = s.replace(/\[INF\]/ig, '\u221E'); //无穷大 } return this.print(s, xpos, ypos); } } </span>
随着[人叫板老师]教的东西越来越多,现在这些函数是越来越胖了。
不过,这样才能做更多的事。
还是来看看效果:
这些可以这样写出来:
<span style="font-size:18px;"> if (1) { var mathText = new MathText(); var s = [ 'a+b+c = d', 'a_[1]+b_[2]+c_[3] = d_[4]', 'a^[b] + c^[d] = e^[2.5]', 'sss^[0.5] + ttt^[0.5] = uuu^[2]', 'a^[->]+b^[->]+c^[->] = d^[->]', 'OA^[->]^[2] = a^[->]', 'OA^[->] = CB^[->] = DO^[->]', 'OB^[->] = DC^[->] = EO^[->]', 'OC^[->] = AB^[->] = ED^[->] = FO^[->]', ]; var x =40, y=40; var r1 = 40; var len = s.length; for (var i = 0; i < len; i++) { if (s[i] == '') { if (x < 100) { x += 300; y-=r1*3; } else { x = 20; y += r1; } } else { mathText.print(s[i], x, y); y+=r1; } } } </span>
不管写的是不是天书,至少小伟现在能写出箭头了。
下面就可以认真的修炼[人叫板老师]的功法了。
<span style="font-size:18px;"> if (1) { var r = 20; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0,190); //坐标轴设定 var scaleX = 3*r, scaleY = 3*r; var spaceX = 2, spaceY = 2; var xS = -10, xE = 10; var yS = -10, yE = 10; config.axisSpacing(xS, xE, spaceX, scaleX, 'X'); config.axisSpacing(yS, yE, spaceY, scaleY, 'Y'); var array = [[0, 0], [5, 0], [6, 4]]; array_1 = [[0, 0], [6,4]]; array_2 = [[0, 0], [1, 4], [6, 4]]; var points = []; for (var i = 0; i < array.length; i++) { points.push(array[i]); } for (var i = 0; i < array_1.length; i++) { points.push(array_1[i]); } for (var i = 0; i < array_2.length; i++) { points.push(array_2[i]); } points = removeDuplicatedPoint(points); var size = array.length; var transform = new Transform(); var tmp = []; array = transform.scale(transform.translate(array, 0, 0), scaleX/spaceX, scaleY/spaceY); array_1 = transform.scale(transform.translate(array_1, 0, 0), scaleX/spaceX, scaleY/spaceY); array_2 = transform.scale(transform.translate(array_2, 0, 0), scaleX/spaceX, scaleY/spaceY); points = transform.scale(transform.translate(points, 0, 0), scaleX/spaceX, scaleY/spaceY); tmp = [].concat(array); vectorDraw(tmp, 'red'); tmp = [].concat(array_1); vectorDraw(tmp, 'green'); tmp = [].concat(array_2); vectorDraw(tmp, 'blue'); tmp = [].concat(points); shape.pointDraw(tmp, 'orange', 1, 1, 'OACB'); plot.setFillStyle('blue'); plot.fillText('向量图', -270, -170, 300); } //去除重复点 function removeDuplicatedPoint(pointArray) { var array = new Array(); var size = pointArray.length; array.push(pointArray[0]); var len = 0; for (var i = 0; i < size; i++) { len = array.length; for (var j = 0; j < len; j++) { if (pointArray[i][0] == array[j][0] && pointArray[i][1] == array[j][1]) { break; } if (j >= len-1) { array.push(pointArray[i]); } } } return array; }</span>
<span style="font-size:18px;"> if (1) { var mathText = new MathText(); var s = [ 'a^[->]+b^[->]=(x_[1]|i^[->]+y_[1]|j^[->])+(x_[2]|i^[->]+y_[2]|j^[->])', '=(x_[1]+x_[2])|i^[->]+(y_[1]+y_[2])|j^[->]', '=> a^[->]+b^[->]=(x_[1]+x_[2], y_[1]+y_[2])', '=> a^[->]-b^[->]=(x_[1]-x_[2], y_[1]-y_[2])', 'λ|a^[->] = (λx_[1], λy_[1])' ]; var x =40, y=40; var r1 = 40; var len = s.length; for (var i = 0; i < len; i++) { if (s[i] == '') { if (x < 100) { x += 300; y-=r1*3; } else { x = 20; y += r1; } } else { mathText.print(s[i], x, y); y+=r1; } } }</span>
<span style="font-size:18px;"> if (1) { var r = 20; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0,190); //坐标轴设定 var scaleX = 3*r, scaleY = 3*r; var spaceX = 2, spaceY = 2; var xS = -10, xE = 10; var yS = -10, yE = 10; config.axisSpacing(xS, xE, spaceX, scaleX, 'X'); config.axisSpacing(yS, yE, spaceY, scaleY, 'Y'); var array = [[0, 0], [2, 1], [-3, 4]]; array_1 = [[0, 0], [-1,5]]; array_2 = [[0, 0], [-3, 4]]; var points = []; for (var i = 0; i < array.length; i++) { points.push(array[i]); } for (var i = 0; i < array_1.length; i++) { points.push(array_1[i]); } for (var i = 0; i < array_2.length; i++) { points.push(array_2[i]); } points = removeDuplicatedPoint(points); var size = array.length; var transform = new Transform(); var tmp = []; array = transform.scale(transform.translate(array, 0, 0), scaleX/spaceX, scaleY/spaceY); if (array_1.length > 0) { array_1 = transform.scale(transform.translate(array_1, 0, 0), scaleX/spaceX, scaleY/spaceY); } if (array_2.length > 0) { array_2 = transform.scale(transform.translate(array_2, 0, 0), scaleX/spaceX, scaleY/spaceY); } points = transform.scale(transform.translate(points, 0, 0), scaleX/spaceX, scaleY/spaceY); tmp = [].concat(array); vectorDraw(tmp, 'red'); if (array_1.length > 0) { tmp = [].concat(array_1); vectorDraw(tmp, 'green'); } if (array_2.length > 0) { tmp = [].concat(array_2); vectorDraw(tmp, 'blue'); } tmp = [].concat(points); shape.pointDraw(tmp, 'orange', 1, 1); plot.setFillStyle('blue'); plot.fillText('向量图', -270, -170, 300); }</span>
本节到此结束,欲知后事如何,请看下回分解。
相关文章推荐
- 用rz sz命令传输文件
- 每天进步一点点——Linux中的文件描述符与打开文件之间的关系
- SQL-Oracle-创建Dblink
- KindEditor图片批量上传
- gcd多线程
- Hive SQL的编译过程
- 使用Nominatim进行openstreetmap地址搜索/解析
- AVS、MPEG-2、H.264 标准文档
- 染色配对(详解+代码)
- Android应用正确的退出方式(单例模式)
- servelt和filter的映射规则
- pg清除pg_xlog
- Visual Studio Team Foundation Server 2013
- Log4j – 如何配置多个logger
- 按字母索引排序listview
- codeforces 653F
- CTF进阶之路1——virtualbox安装
- 产品经理 产品设计师常用软件
- 面试感悟----一名3年工作经验的程序员应该具备的技能
- JAVA生成二维码