我正在尝试制作一个简单的Bezier曲线但是我无法理解它背后的数学,如果有人能够向我解释这个简单的Bezier曲线它会很棒:)
我们有
point1
X: 0
Y: 0
point2
X: 100
Y: 100
control point1
X: 0
Y: 100
所以基本上我们有一条从左上角开始的线,从左上角到右下角的100 x 100像素的正方形,但现在我想尝试将该线拉到控件指向X位置0和Y位置100,有人可以向我解释这里发生的简单数学,如果可能的话,可以用我的值显示计算:)。
谢谢
P.S。基本图片
更新
这是我使用等式
的简单javascript代码canvasHolder = document.getElementById( 'canvas' );
canvas = canvasHolder.getContext('2d');
var deltaT = 0.10;
var point1 = new Point(300,300);
var point2 = new Point(400,400);
var controlPoint1 = new Point(100,200);
//Bezier cruve
for( var i = 0; i < 10; i++ )
{
var t = (i/10) * 0.1;
var xPos = ( 1.0 * - t*t ) * point1.x + 2.0 * ( 1 - t ) * t * controlPoint1.x + t * t * point2.x;
var yPos = ( 1.0 * - t*t ) * point1.y + 2.0 * ( 1 - t ) * t * controlPoint1.y + t * t * point2.y;
console.log( "xPos = " + xPos + ", yPos = " + yPos );
var particle = new Particle( "circle", xPos, yPos, 5, "#FF0000", "#333333");
particles[i] = particle;
}
这是
的输出xPos = 0, yPos = 0 bezierCurve.js:35
xPos = 1.9900000000000004, yPos = 3.970000000000001 bezierCurve.js:35
xPos = 3.9600000000000004, yPos = 7.880000000000001 bezierCurve.js:35
xPos = 5.909999999999999, yPos = 11.729999999999999 bezierCurve.js:35
xPos = 7.840000000000001, yPos = 15.520000000000001 bezierCurve.js:35
xPos = 9.75, yPos = 19.25 bezierCurve.js:35
xPos = 11.639999999999997, yPos = 22.919999999999998 bezierCurve.js:35
xPos = 13.509999999999996, yPos = 26.529999999999998 bezierCurve.js:35
xPos = 15.360000000000003, yPos = 30.080000000000005 bezierCurve.js:35
xPos = 17.190000000000005, yPos = 33.57000000000001
我获得此结果的原因
编辑,
确定我正在这样做
var xPos = ( 1.0 * - t*t ) * point1.x + 2.0 * ( 1 - t ) * t * controlPoint1.x + t * t * point2.x;
这是什么时候
var xPos = ( 1.0 - t*t ) * point1.x + 2.0 * ( 1 - t ) * t * controlPoint1.x + t * t * point2.x;
答案 0 :(得分:1)
贝塞尔曲线是参数曲线。这意味着你将有2个方程:1表示曲线上的x坐标,另一个表示曲线上的y坐标。
在这种情况下,您正在使用二次贝塞尔曲线。 quadratic beziers的等式是:
x(t)=(1.0 - t ^ 2)* p0.x + 2.0 *(1 - t)* t * p1.x + t ^ 2 * p2.x;
y(t)=(1.0 - t ^ 2)* p0.y + 2.0 *(1 - t)* t * p1.y + t ^ 2 * p2.y;
在这种情况下,p0是起点,p1是控制点,p2是终点。
在曲线上从0到1变化。因此,要使用标准线条绘制功能绘制它,您需要执行以下操作:
float numDivisions = 100.0; // <- You need to decide what this value should be. See below
float t;
float deltaT = t / numDivisions;
MoveTo (p0.x, p0.y);
for (t = 0; t <= 1.0; t += deltaT)
{
x = (1.0 - t*t) * p0.x + 2.0 * (1 - t) * t * p1.x + t * t * p2.x;
y = (1.0 - t*t) * p0.y + 2.0 * (1 - t) * t * p1.y + t * t * p2.y;
LineTo (x, y);
}
numDivisions将控制曲线的分辨率。如果你只有3个分区,你将获得起点,中间1点(参数化)和终点。如果你使用10,000点,你可能会得到比你需要的更多的东西。根据经验,连接点的直线总是比实际曲线长,因此您永远不需要使用大于该数的除法。 (您可以使用点之间的欧几里德距离。)
答案 1 :(得分:0)
您可以从几何表示中导出贝塞尔曲线的参数方程:
(a)--A-----(c)
x \
C
\
\
(b)
从a-&gt; c-&gt; b
画一条线将a->c
中的一行细分为 A ,其中 A = t *( c - a )+ a ,即 t 单位从 a 到 c (0℃; = 吨&LT; = 1)。使用相同的比率 t ,从c前进到b,相同的 t 单位(C点)。
(递归地)将A-> C细分为 t 和 1-t 的部分,将点 x 放置在分裂点处。这是位于Bezier曲线的真实点。
可以使用相同的程序生成三次贝塞尔曲线 - 再向该过程添加一个步骤。
求和:(a = {ax,ay}),A = {Ax,Ay})等。
A = (c-a)*t + a = { cx-ax * t + ax, cy-ay * t + ay }
B = (b-c)*t + c = { bx-cx * t + cx, by-cy * t + cy }
x = (C-A)*t + A = { Cx-Ax * t + Ax, Cy-Ay * y + Ay }
(注意,如果a = {ax,ay,az},即3D点,则同样的原则成立)
这些公式现在可以组合起来产生Cx,Cy,[Cz]的闭合形式方程式,作为 t 的二次函数,常数ax,ay,cx,cy,bx,by ,如user1118321的第一个答案。