Skip to content

Instantly share code, notes, and snippets.

@GZShi
Created August 7, 2013 14:01
Show Gist options
  • Save GZShi/6174288 to your computer and use it in GitHub Desktop.
Save GZShi/6174288 to your computer and use it in GitHub Desktop.
Chrome arc函数采用贝塞尔曲线拟合圆
<html>
<head>
<title>chrome arc</title>
<meta charset='utf-8'>
</head>
<body>
<canvas id='c' width='2000' height='1500'></canvas>
<script>
// javascript code
function bezierArc(ctx, cx, cy, r) {
var begin = {x: r, y: 0};
var middle = {x: r, y: r * Math.tan(Math.PI/8)};
var end = {x: r * Math.SQRT1_2, y: r * Math.SQRT1_2};
var a0, a1, a2, t;
var lposx = r, lposy = 0;
var cposx = r, cposy = 0;
for(var i = 0; i <= 100; ++i) {
t = i / 100;
a0 = Math.pow(1 - t, 2);
a1 = 2 * t * (1 - t);
a2 = Math.pow(t, 2);
cposx = a0*begin.x + a1*middle.x + a2*end.x;
cposy = a0*begin.y + a1*middle.y + a2*end.y;
ctx.moveTo(lposx + cx, lposy + cy);
ctx.lineTo(cposx + cx, cposy + cy);
ctx.moveTo(lposy + cx, lposx + cy);
ctx.lineTo(cposy + cx, cposx + cy);
// 仅仅拟合1/4个圆
// ctx.moveTo(-lposx + cx, lposy + cy);
// ctx.lineTo(-cposx + cx, cposy + cy);
// ctx.moveTo(lposy + cx, -lposx + cy);
// ctx.lineTo(cposy + cx, -cposx + cy);
// ctx.moveTo(lposx + cx, -lposy + cy);
// ctx.lineTo(cposx + cx, -cposy + cy);
// ctx.moveTo(-lposy + cx, lposx + cy);
// ctx.lineTo(-cposy + cx, cposx + cy);
// ctx.moveTo(-lposx + cx, -lposy + cy);
// ctx.lineTo(-cposx + cx, -cposy + cy);
// ctx.moveTo(-lposy + cx, -lposx + cy);
// ctx.lineTo(-cposy + cx, -cposx + cy);
lposx = cposx;
lposy = cposy;
}
}
function normalArc(ctx, cx, cy, r) {
var delta = 0.5;
var t = 1 / 180;
ctx.moveTo(cx + r, cy);
for(var i = 0; i < 360; i+= delta) {
ctx.lineTo(
cx + Math.cos(Math.PI * i * t) * r,
cy + Math.sin(Math.PI * i * t) * r);
}
}
var ctx = document.getElementById('c').getContext('2d');
// native
ctx.beginPath();
ctx.arc(500, 0, 1000, 0, 2* Math.PI, true)
ctx.closePath();
ctx.strokeStyle = "red";
ctx.stroke();
// bezier
ctx.beginPath();
bezierArc(ctx, 500, 0, 1000);
ctx.closePath();
ctx.strokeStyle = "green";
ctx.stroke();
// normal
ctx.beginPath();
normalArc(ctx, 500, 0, 1000);
ctx.closePath();
ctx.strokeStyle = "blue";
ctx.stroke();
ctx.fillText("此处红色和绿色重合,颜色呈灰色,说明Chrome采用贝塞尔拟合", 900, 950);
ctx.fillText("蓝色为标准圆", 900, 970);
ctx.fillText("红色为Chrome的arc", 900, 990);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment