[Canvas绘图] 第02节 今日看“点"

来源:互联网 发布:vmware mac os补丁 编辑:程序博客网 时间:2024/06/06 05:09
本节目标:
(1) 封装map类
(2) 绘制坐标系
(3) 简单函数绘制


实现步骤:

续前节,有了画布,就想要画一些东西,就从最简单的“点”开始吧。点是和函数关系在一起的,怎样画出漂亮的函数图形呢?

在画出函数以前,我先想到了一个问题,怎样查看函数上各个点的坐标值?

今天就从这里开始。

我第一步,建立了一个Html表,用于显示数值,设计得非常简单。这个表通过一个函数给它刷数据:

/*** @usage   查看数据的表格* @author  mw* @date    2015年11月28日  星期六  13:00:45 * @param* @return**/function mytable() {var table = $$("table");//找<tbody>var node = table.firstChild;while (null != node) {/*想知道都有哪些子节点,用这个var text = document.createTextNode(node.nodeName);document.body.appendChild(text);*/if ("TBODY" == node.nodeName) break;node = node.nextSibling;}//生成映射数据var xArray = genData(10);var yArray = linearMap(xArray);//单元格插入for (var i = 0; i<10; i++) {//插入<tr>var tr = document.createElement("tr")//插入<td> xvar td = document.createElement("td");var x = document.createTextNode(xArray[i].toFixed(3));td.appendChild(x);tr.appendChild(td);//插入<td> yvar td = document.createElement("td");var y = document.createTextNode(yArray[i].toFixed(3));td.appendChild(y);tr.appendChild(td);node.appendChild(tr);}}

下面来看看效果怎样:


验证可行,接着进行下一步。

这里用到一个随机数生成函数,这样就可以省去没有数据可用的麻烦,这个函数很小巧。

/*** @usage   生成X轴测试随机数据* @author  mw* @date    2015年11月28日  星期六  12:10:34 * @param* @return**/function genData(n) {var xArray = new Array();//生成n个随机数for (var i = 0; i < n; i++) {var x = Math.random() * 200 - 100;xArray.push(x); //值在-100到100之间}return xArray;}

然后定义了两个简单的函数,分别是一个直线方程,和一个sin函数。

/*** @usage   直线函数映射* @author  mw* @date    2015年11月28日  星期六  12:11:59 * @param* @return**/function linearMap(xArray) {var yArray = new Array();//直线方程y = kx + bvar k = -1;var b = 0;for (var i = 0; i < xArray.length; i++) {var y = k * xArray[i] + b;yArray.push(y);}return yArray;}/*** @usage   正弦函数映射* @author  mw* @date    2015年11月28日  星期六  14:10:11 * @param* @return**/function sinMap(xArray) {var yArray = new Array();//方程y = sin(x)for (var i = 0; i < xArray.length; i++) {var y = 100* Math.sin(xArray[i]/100*Math.PI*2);yArray.push(y);}return yArray;}

有了这两个函数,就可以去验证接下来要设计的map容器的可靠程度了。

于是去设计map。

/*** @usage  映射类map* @author  mw* @date    2015年11月28日  星期六  08:01:13 * @param* @return**/function Map(){      /** 存放键的数组(遍历用到) */        this.keys = new Array();         /** 存放数据 */        this.data = new Object();                  /**        * 放入一个键值对        * @param {String} key        * @param {Object} value        */        this.put = function(key, value) {             if(this.data[key] == null){                 this.keys.push(key);    this.data[key] = new Array();        }             this.data[key].push(value);         };                  /**        * 获取某键对应的值        * @param {String} key        * @return {Object} value        */        this.get = function(key) {             return this.data[key];         };                  /**        * 删除一个键值对        * @param {String} key        */        this.remove = function(key) {             this.keys.remove(key);             this.data[key] = null;         };                  /**        * 遍历Map,执行处理函数        *         * @param {Function} 回调函数 function(key,value,index){..}        */        this.each = function(fn){             if(typeof fn != 'function'){                 return;             }             var len = this.keys.length;             for(var i=0;i<len;i++){                 var k = this.keys[i];                 fn(k,this.data[k],i);             }         };                  /**        * 获取键值数组(类似Java的entrySet())        * @return 键值对象{key,value}的数组        */        this.entrys = function() {             var len = this.keys.length;             var entrys = new Array(len);             for (var i = 0; i < len; i++) {                 entrys[i] = {                     key : this.keys[i],                     value : this.data[i]                 };             }             return entrys;         };                  /**        * 判断Map是否为空        */        this.isEmpty = function() {             return this.keys.length == 0;         };                  /**        * 获取键值对数量        */        this.size = function(){             return this.keys.length;         };                  /**        * 重写toString         */        this.toString = function(){             var s = "{";             for(var i=0;i<this.keys.length;i++,s+=','){                 var k = this.keys[i];                 s += k+"=";for (var j=0; j<this.data[k].length;j++,s+=',') {s+=this.data[k][j];   }        }             s+="}";             return s;         };   }  

现在好像材料都准备好了,可以写个绘图试试。

/*** @usage   绘制Demo* @author  mw* @date    2015年11月28日  星期六  13:00:45 * @param* @return**/function myplot_2015_11_28() {setPreference();//生成映射数据var xArray = genData(100);xArray = xArray.sort();var yArray = linearMap(xArray);var xArray2 = genData(100);var yArray2= sinMap(xArray2);axis(300,200,190);//绘制plot.setTransform(1.5,0,0,1.5, 300,200);/*//第一种取数据法for (var i=0; i<xArray.length; i++) {fillCircle(xArray[i],-yArray[i],2);}*///第二种取数据法var xyMap = new Map();//第一个函数for (var i = 0; i < xArray.length; i++) {xyMap.put(xArray[i], yArray[i]);}//第二个函数for (var i = 0; i < xArray2.length; i++) {xyMap.put(xArray2[i], yArray2[i]);}//绘出映射if (!xyMap.isEmpty()) {for (var i=0; i <xyMap.size(); i++) {var x = xyMap.keys[i];var y = xyMap.get(x);for (var j=0;j<y.length;j++) {fillCircle(x,y[j],2);}}}/*//数据检查var text = document.createTextNode(xyMap.toString());document.body.appendChild(text);*/}

有了map,图形可以更精彩,来看看效果吧。


坐标轴的函数,还是比较费事的。

/*** @usage   绘制直角坐标系* @author  mw* @date    2015年11月28日  星期六  14:17:34 * @param* @return**/function axis(x, y, r) {plot.beginPath().moveTo(x-r,y).lineTo(x+r,y).closePath().stroke();plot.beginPath().moveTo(x,y-r).lineTo(x,y+r).closePath().stroke();plot.setFillStyle('black');var r0 = 10;//x轴箭头plot.beginPath().moveTo(x+r- r0*Math.cos(Math.PI/3), y-r0*Math.sin(Math.PI/3)).lineTo(x+r+r0*Math.sin(Math.PI/3), y).lineTo(x+r -r0*Math.cos(Math.PI/3), y+r0*Math.sin(Math.PI/3)).closePath().fill()//y轴箭头plot.beginPath().moveTo(x+ r0*Math.sin(Math.PI/3), y-r+r0*Math.cos(Math.PI/3)).lineTo(x, y-r-r0*Math.sin(Math.PI/3)).lineTo(x-r0*Math.sin(Math.PI/3), y-r+r0*Math.cos(Math.PI/3)).closePath().fill()plot.setFillStyle('#666666');}
这一节就到这里。

0 0
原创粉丝点击