在html画布上绘制贝塞尔曲线
Drawing bezier curve on html canvas
我需要绘制一条由N个控制点定义的贝塞尔曲线,这些控制点存储在一个数组中。我有一个500px x 500px的画布。这里是JSFiddle的链接:jsfiddle.net/HswXy整个JS代码:
<script>
window.onload=function(){
var old_n=0,n=0;
var nrSelect = document.getElementById("mySelect");
var submit = document.getElementById("submit");
nrSelect.addEventListener("change",function(){
old_n=n;
n = nrSelect.selectedIndex;
var inputx,inputy,br;
if(document.getElementById("pointsdiv"))
{
for(i=1;i<=n;i++){
inputx = document.createElement('input');
inputy = document.createElement('input');
br = document.createElement('br');
inputx.type = "text";
inputy.type = "text";
inputx.size = 3;
inputy.size = 3;
inputx.id = "x_" + i;
inputy.id = "y_" + i;
inputx.value = "x_" + i;
inputy.value = "y_" + i;
inputx.addEventListener("focus",function(){if(this.value==this.id) this.value="";});
inputy.addEventListener("focus",function(){if(this.value==this.id) this.value="";});
document.getElementById("pointsdiv").appendChild(inputx);
document.getElementById("pointsdiv").appendChild(inputy);
document.getElementById("pointsdiv").appendChild(br);
}
document.getElementById("pointsdiv").id="pointsdiv_after";
}
else
{
if( old_n < n )
{
for(i=old_n+1;i<=n;i++){
inputx = document.createElement('input');
inputy = document.createElement('input');
br = document.createElement('br');
inputx.type = "text";
inputy.type = "text";
inputx.size = 3;
inputy.size = 3;
inputx.id = "x_" + i;
inputy.id = "y_" + i;
inputx.value = "x_" + i;
inputy.value = "y_" + i;
inputx.addEventListener("focus",function(){if(this.value==this.id) this.value="";});
inputy.addEventListener("focus",function(){if(this.value==this.id) this.value="";});
document.getElementById("pointsdiv_after").appendChild(inputx);
document.getElementById("pointsdiv_after").appendChild(inputy);
document.getElementById("pointsdiv_after").appendChild(br);
}
}
else
{
var parent;
for(i=n+1;i<=old_n;i++){
parent = document.getElementById("pointsdiv_after");
parent.removeChild(parent.lastChild);
parent.removeChild(parent.lastChild);
parent.removeChild(parent.lastChild);
}
}
}
});
//BEZIER CURVE
function factorial(n){
var result=1;
for(i=2;i<=n;i++){
result = result*i;
}
return result;
}
function Point(x,y){
this.x=x;
this.y=y;
}
var points = new Array();
function getPoint(t){
var i;
var x=points[0].x;
var y=points[0].y;
var factn = factorial(n);
for(i=0;i<n;i++){
var b = factn / (factorial(i)*factorial(n-i));
var k = Math.pow(1-t,n-i)*Math.pow(t,i);
// console.debug( i+": ",points[i] );
x += b*k*points[i].x;
y += b*k*points[i].y;
}
return new Point(x, y);
}
//--BEZIER CURVE
submit.addEventListener("click",function(){
if(n){
for(i=1;i<=n;i++){
var px = document.getElementById("x_"+i);
var py = document.getElementById("y_"+i);
points.push(new Point(parseInt(px.value,10),parseInt(py.value,10)));
// console.debug( points[i-1] );
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.beginPath();
console.debug( points[0].x, points[0].y );
context.moveTo(points[0].x, points[0].y);
var t=0.01;
while (t<=1)
{
//get coordinates at position
var p=getPoint(t);
// console.debug( p.x, p.y );
//draw line to coordinates
context.lineTo(p.x, p.y);
//increment position
t += 0.01;
}
context.stroke();
}
});
}
</script>
问题是它似乎不能正常工作。我现在测试了2个点,它总是从画布的左上角开始(即使我的第一个点是(250,250),并且线的长度不是应该的像素数)。这是更长的时间。
我不是画布或几何方面的专家,但这是我的想法:在画假线之前,你不应该先画moveTo
points[0]
,因为你的getPoint
函数似乎会引导你到那里。我在调试你的代码时看到的是,你先移动到(20,20)
,然后画了一条直线(大致)到(40,40)
,然后开始逐渐画回(20,20)
,生成了那个不是你想要的封闭形状。
对你的代码做一个小的(快速和肮脏的)改变,使它开始画一条曲线:
// DO NOT MOVE TO HERE
//context.moveTo(points[0].x, points[0].y);
var t = 0.01;
// MOVE TO THE FIRST POINT RETURNED BY getPoint
var p0 = getPoint(t);
context.moveTo(p0.x, p0.y);
t+=0.01;
// now loop from 0.02 to 1...
我相信你可以把它重构成更好的东西,就像我说过的那样,我的修改既快又脏。
http://jsfiddle.net/HswXy/3/相关文章:
- 画布:制作贝塞尔曲线绘制动画
- 在谷歌地理图中绘制两点之间的曲线
- 在新框架上绘制图像,同时仍然使用P5.js中的利萨茹曲线
- 在滚动上绘制一条曲线虚线 SVG
- 绘制具有 JS 中平均值和标准偏差的正态分布曲线
- 在 WebGL 中的曲面上绘制曲线
- 绘制正态分布曲线,左下角区域在 javascript 中带有阴影
- 如何使用 svg 循环绘制贝塞尔曲线
- 用createjs绘制一个虚线曲线
- HTML5 画布:加载时绘制的贝塞尔曲线
- 在HTML5画布上慢慢绘制二次曲线
- 在HTML5画布上复制曲线时未绘制点
- 如何使用javascript HTML5画布绘制通过N个点的曲线
- 如何使用CSS和JavaScript绘制正态分布曲线(Bell曲线)
- 如何绘制曲线svg路径
- 如何在画布上绘制文本,该文本遵循使用二次曲线方法绘制的二次曲线
- 如何在HTML画布上绘制具有可变厚度的贝塞尔曲线
- 如何使用bezierCurveTo动态绘制曲线
- 如何在Javascript中绘制3d blezier曲线?(three.js, webGL)
- 用二次贝塞尔曲线和三次贝塞尔曲线绘制椭圆