赛贝尔曲线怎么做啊,有人知道吗

赛贝尔曲线怎么做啊,有人知道吗

能有一段代码~~~就更感谢啦~:904:

给你偷一个

// 三次贝塞尔.cpp : Defines the entry point for the console application.
//

#include “stdafx.h”
#include <stdio.h>
#include
#include
#define NUM_STEPS 30 //越大,曲线越密,越逼近
using namespace std;
class CvPoint
{
public:
float x;
float y;
CvPoint()
{
x=0.0;
y=0.0;
}
CvPoint(float a,float b)
{
x=a;
y=b;
}

};

void curve4(vector &p,
double x1, double y1, //Anchor1
double x2, double y2, //Control1
double x3, double y3, //Control2
double x4, double y4) //Anchor2
{
CvPoint tmp0(x1,y1);
p.push_back(tmp0);
double dx1 = x2 - x1;
double dy1 = y2 - y1;
double dx2 = x3 - x2;
double dy2 = y3 - y2;
double dx3 = x4 - x3;
double dy3 = y4 - y3;

double subdiv_step  = 1.0 / (NUM_STEPS + 1);  
double subdiv_step2 = subdiv_step*subdiv_step;  
double subdiv_step3 = subdiv_step*subdiv_step*subdiv_step;  

double pre1 = 3.0 * subdiv_step;  
double pre2 = 3.0 * subdiv_step2;  
double pre4 = 6.0 * subdiv_step2;  
double pre5 = 6.0 * subdiv_step3;  

double tmp1x = x1 - x2 * 2.0 + x3;  
double tmp1y = y1 - y2 * 2.0 + y3;  

double tmp2x = (x2 - x3)*3.0 - x1 + x4;  
double tmp2y = (y2 - y3)*3.0 - y1 + y4;  

double fx = x1;  
double fy = y1;  

double dfx = (x2 - x1)*pre1 + tmp1x*pre2 + tmp2x*subdiv_step3;  
double dfy = (y2 - y1)*pre1 + tmp1y*pre2 + tmp2y*subdiv_step3;  

double ddfx = tmp1x*pre4 + tmp2x*pre5;  
double ddfy = tmp1y*pre4 + tmp2y*pre5;  

double dddfx = tmp2x*pre5;  
double dddfy = tmp2y*pre5;  

int step = NUM_STEPS;  

while(step--)  
{  
    fx   += dfx;  
    fy   += dfy;  
    dfx  += ddfx;  
    dfy  += ddfy;  
    ddfx += dddfx;  
    ddfy += dddfy;  
    CvPoint tmp1(fx,fy);
    p.push_back(tmp1);  
}  
CvPoint tmp2(x4,y4);
p.push_back(tmp2); 

}

int _tmain(int argc, _TCHAR* argv])
{
CvPoint point;
point.x=1.0;
point.y=4.0;
point.x=2.2;
point.y=5.0;
point.x=6;
point.y=3;
point.x=8;
point.y=9;
vector curvePoint;
curve4(curvePoint,
point.x,point.y,
point.x,point.y,
point.x,point.y,
point.x,point.y
);
int i=0;
for(;i<curvePoint.size();i++)
{
cout<<"("<<curvePoint*.x<<","<<curvePoint*.y<<")";
if((i+1)%2==0)
cout<<endl;
}
cout<<endl<<“点的个数:”<<i<<endl;
system(“pause”);
return 0;
}**

楼主,我给你讲下赛贝尔曲线的数学概念,你可以把它转换成你的程序代码。

赛贝尔曲线公式:
B(t) = P0*(1-t)^3 + P1*(1-t)^2t + P2(1-t)t^2 + P3t^3
其中: ^3 表示三次方, ^2是二次方。
P0和P3是曲线的开始和结束2个点,P1和P2是曲线的控制点。控制点用于决定曲线的弯曲度。
B(t)表示曲线上的某个点,他可以用这个公司来计算。

具体怎么计算呢?
t 的取值范围是是0~1, 0 和 1 分别表示是曲线的其实和结束点,也就是P0和P1.
0~1之间有很多小数的值,但是我们不可能把他们全部穷举出来。
比如我们给t 的取值是:0. 0.1, 0.2, 0.3, … 0.9, 1.0,把这11个值带到上面的公式里面就会得到11个B(t)的值,也就是曲线经过的11个点,要想多算出来一些点,就把t 的取值更加精细些,但是程序运行时间就会加长,这个就要看你的软件需求了。

一个点一般有2个熟悉(x,y),带入到上面的公式中去:
B(t).x = P0.x*(1-t)^3 + P1.x*(1-t)^2t + P2.x(1-t)t^2 + P3.xt^3
B(t).y = P0.y*(1-t)^3 + P1.y*(1-t)^2t + P2.y(1-t)t^2 + P3.yt^3

通过上面2个公式就可以得出曲线上 某个t 值对应点的(xt, yt)。

不知道我讲清楚了没有。。。

我这里有段我写的GLSL geometry shader 程序,用它来产生一段赛贝尔曲线。 其中“pointNum”就是用户定义的要产生几个点,也就是我前面讲的 要产生几个 t 的值。
static const char glslGeomProg] =
#version 420 compatibility\n”
“layout (lines_adjacency) in;\n”
“layout (line_strip, max_vertices = 100) out;\n”
“uniform float pointNum;\n”
“void main()\n”
“{\n”
“int num = int( pointNum + 0.99 );\n”
“float dt = 1. / float(num);\n”
“float t = 0.;\n”
“for( int i = 0; i <= num; i++ ) {\n”
“float omt = 1. - t;\n”
“float omt2 = omt * omt;\n”
“float omt3 = omt * omt2;\n”
“float t2 = t * t;\n”
“float t3 = t * t2;\n”
“vec4 xyzw= omt3 * gl_in.gl_Position.xyzw +\n”
“3. * t * omt2 * gl_in.gl_Position.xyzw +\n”
“3. * t2 * omt* gl_in.gl_Position.xyzw +\n”
“t3 * gl_in.gl_Position.xyzw;\n”
“gl_Position= xyzw;\n”
“vec4 rgba= omt3 * gl_in.gl_FrontColor.rgba +\n”
“3. * t * omt2 * gl_in.gl_FrontColor.rgba +\n”
“3. * t2 * omt* gl_in.gl_FrontColor.rgba +\n”
“t3 * gl_in.gl_FrontColor.rgba;\n”
“gl_FrontColor= rgba;\n”
“EmitVertex();\n”
“t += dt;\n”
“}\n”
“}\n”;