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();



	
}

 

 

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

 

posted @ 2012-08-29 11:48  平阳小安  阅读(342)  评论(0编辑  收藏  举报