6

给定由 2d 画布上下文函数绘制的线bezierCurveToquadraticCurveTo或者arcTo,我怎样才能找到沿这些线的点?

我的意图是在曲线的中点绘制一个对象。使用 SVG DOM,我可以使用方法getPointAtLength&来做到这一点getTotalLength,但我在 HTML 画布中看不到等价物。

4

2 回答 2

11

你很难找到他们:(

HTML 画布中没有等价物。你必须用简单的旧数学自己找到中点。

我做了一个如何为你找到贝塞尔曲线中点的例子。在此处的 jsFiddle 现场查看。javascript 的副本粘贴在下面。

真实曲线是红色的,中点是绿色的小矩形。其他一切都只是视觉辅助。

var ctx = $("#test")[0].getContext("2d")
function mid(a,b) {
 return (a+b) / 2;
}


var cp1x = 100;
var cp1y = 150;
var cp2x = 175;
var cp2y = 175;
var x = 200;
var y = 0;

ctx.lineWidth = 4;
ctx.strokeStyle = "red";
ctx.fillStyle = "rgba(0,0,0,0.6)";

ctx.beginPath();
ctx.moveTo(0, 0);
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
ctx.stroke();

//line goes from start to control point 1
ctx.strokeStyle = "rgba(0,0,200,0.4)";
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(cp1x , cp1y);
ctx.stroke();

//line goes from end to control point 2
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(cp2x , cp2y);
ctx.stroke();

//line goes from control point to control point
ctx.strokeStyle = "rgba(200,0,200,0.4)";
ctx.beginPath();
ctx.moveTo(cp1x, cp1y);
ctx.lineTo(cp2x , cp2y);
ctx.stroke();

// now find the midpoint of each of those 3 lines
var ax = mid(cp1x,0);
var bx = mid(cp2x,x)
var cx = mid(cp1x,cp2x)

var ay = mid(cp1y,0)    
var by = mid(cp2y,y)    
var cy = mid(cp1y,cp2y)


// draw midpoints for visual aid 
// not gonna look exact 'cause square
// will be drawn from top-right instead of center
ctx.fillRect(ax, ay, 4, 4);
ctx.fillRect(bx, by, 4, 4);
ctx.fillRect(cx, cy, 4, 4);


//now draw lines between those three points. These are green
ctx.strokeStyle = "rgba(0,200,0,0.4)";
ctx.beginPath();
ctx.moveTo(ax, ay);
ctx.lineTo(cx , cy);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(bx, by);
ctx.lineTo(cx , cy);
ctx.stroke();

//now the midpoint of the green lines:
// so g1 and g2 are the green line midpoints
var g1x = mid(ax,cx);
var g2x = mid(bx,cx);

var g1y = mid(ay,cy); 
var g2y = mid(by,cy);  

//draw them to make sure:
ctx.fillRect(g1x , g1y, 4, 4);
ctx.fillRect(g2x , g2y, 4, 4);

//now one final line, in gray
ctx.strokeStyle = "rgba(20,20,20,0.4)";
ctx.beginPath();
ctx.moveTo(g1x , g1y);
ctx.lineTo(g2x , g2y);
ctx.stroke();

//whew! We made it!
var FinallyTheMidpointx = mid(g1x,g2x); 
var FinallyTheMidpointy = mid(g1y,g2y); 

//draw something at the midpoint to celebrate
ctx.fillStyle = "rgba(0,255,0,1)";
ctx.fillRect(FinallyTheMidpointx, FinallyTheMidpointy, 4, 4);

​</p>

于 2010-08-26T19:47:35.800 回答
1

贝塞尔曲线是用这个公式数学计算的, 其中 P0 是起点,P1 和 P2 是控制点,P3 是终点。
贝塞尔曲线数学

要计算中点,您可以使用t = 0.5.

二次曲线类似:
数学上的二次曲线

来源和更多信息

于 2019-04-02T13:29:38.267 回答