HTML5的CANVAS上绘制椭圆的几种方法


<div class="lato" id="ty" x="100" y="100" a="100" b="20" onClick="javascript:tty()">椭圆</div>
<canvas id="myCanvas" style=" width:200px; height:200px">

第一种方法不是很椭圆。

function tty(){
	var cc=document.getElementById('myCanvas');
	var context=cc.getContext('2d');
	var x=parseInt(document.getElementById("ty").getAttribute('x'));
	var y=parseInt(document.getElementById("ty").getAttribute('y'));
	var a=parseInt(document.getElementById("ty").getAttribute('a'));
	var b=parseInt(document.getElementById("ty").getAttribute('b'));
	console.log(a+"a");
	console.log(b+"b");
	var step = (a > b) ? 1 / a : 1 / b;
	console.log(step)
	context.beginPath();
	context.moveTo(x + a, y); //从椭圆的左端点开始绘制
	for (var i = 0; i < 2 * Math.PI; i += step)
	{
	  //参数方程为x = a * cos(i), y = b * sin(i),
	  //参数为i,表示度数(弧度)
	  context.lineTo(x + a * Math.cos(i), y + b * Math.sin(i));
	}
	context.closePath();
	context.stroke();

	
}

第二种方法

这种方法利用了数学中的均匀压缩原理将圆进行均匀压缩为椭圆,理论上为能够得到标准的椭圆.

function tty(){
	var cc=document.getElementById('myCanvas');
	var context=cc.getContext('2d');
	var x=parseInt(document.getElementById("ty").getAttribute('x'));
	var y=parseInt(document.getElementById("ty").getAttribute('y'));
	var a=parseInt(document.getElementById("ty").getAttribute('a'));
	var b=parseInt(document.getElementById("ty").getAttribute('b'));
	context.save();
   //选择a、b中的较大者作为arc方法的半径参数
   var r = (a > b) ? a : b;
   var ratioX = a / r; //横轴缩放比率
   var ratioY = b / r; //纵轴缩放比率
   context.scale(ratioX, ratioY); //进行缩放(均匀压缩)
   context.beginPath();
   //从椭圆的左端点开始逆时针绘制
   context.moveTo((x + a) / ratioX, y / ratioY);
   context.arc(x / ratioX, y / ratioY, r, 0, 2 * Math.PI);
   context.closePath();
   context.stroke();
   context.restore();

	
}

第三种方法:三次贝塞尔曲线法

function tty(){
	var cc=document.getElementById('myCanvas');
	var context=cc.getContext('2d');
	var x=parseInt(document.getElementById("ty").getAttribute('x'));
	var y=parseInt(document.getElementById("ty").getAttribute('y'));
	var a=parseInt(document.getElementById("ty").getAttribute('a'));
	var b=parseInt(document.getElementById("ty").getAttribute('b'));
	 //关键是bezierCurveTo中两个控制点的设置
   //0.5和0.6是两个关键系数(在本函数中为试验而得)
   var ox = 0.5 * a,
       oy = 0.6 * b;

   context.save();
   context.translate(x, y);
   context.beginPath();
   //从椭圆纵轴下端开始逆时针方向绘制
   context.moveTo(0, b);
   context.bezierCurveTo(ox, b, a, oy, a, 0);
   context.bezierCurveTo(a, -oy, ox, -b, 0, -b);
   context.bezierCurveTo(-ox, -b, -a, -oy, -a, 0);
   context.bezierCurveTo(-a, oy, -ox, b, 0, b);
   context.closePath();
   context.stroke();
   context.restore();



	
}

经过实验,第二,第三种方法比较靠谱。

优质内容筛选与推荐>>
1、《梦断代码》阅读笔记3
2、Server.MapPath()
3、再理解C++指针
4、定风波
5、postman中 form-data、x-www-form-urlencoded、raw、binary的区别


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn