贝塞尔曲线计算

时间:2014-02-22 23:10:22

标签: math graphics bezier

我正在尝试制作一个简单的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。基本图片

enter image description here

更新

这是我使用等式

的简单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;

2 个答案:

答案 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的第一个答案。