您的位置:首页 > 其它

Bézier Spline Curves

2017-06-09 17:21 13 查看
思路:

每次套公式得到x,y,的值并且逐步改变点的坐标

// ====== Computer Graphics Experiment #7 ======
// | Bezier curve |
// =============================================
//
// Requirement:
// (1) Implement algorithm to draw Bezier curve.
// (2)Implement interactive method to specify
// Bezier curve control points by mouse clicking.
// (3) Implement display callback function

#include <windows.h>
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>

// 2D point class
class CPoint2D
{
public:
float x, y;
};

int n_cp; // Number of control points
int ic_cp; // Control point counter
int i_cp; // Index of control point being moved
CPoint2D *control_points; // Coordinates of control points

// Program window size
int pw_width, pw_height;

int running_state;
// 0 --- Setting up control points.
// 1 --- Normal state.
// 2 --- Moving control point.

void plotPoint(CPoint2D bezCurvePt)
{

glPointSize(1.0f);
glBegin(GL_POINTS);
glVertex2f(bezCurvePt.x, bezCurvePt.y);
glEnd();
}
void binomialCoeffs(GLint n, GLint *C)
{
GLint k, j;
for (k = 0; k <= n; k++)
{
C[k] = 1;
for (j = n; j >= k + 1; j--)
C[k] *= j;
for (j = n - k; j >= 2; j--)
C[k] /= j;
}
}
void computeBezPt(GLfloat u, CPoint2D *bezPt, GLint nCtrlPts, CPoint2D *ctrlPts, GLint *C)
{
GLint k, n = nCtrlPts-1;
GLfloat bezBlendFcn;
bezPt->x = bezPt->y = 0;
for (k = 0; k < nCtrlPts; k++)
{
bezBlendFcn = C[k] * pow(u, k)*pow(1 - u, n - k);
bezPt->x += ctrlPts[k].x*bezBlendFcn;
bezPt->y += ctrlPts[k].y*bezBlendFcn;
}
}
// Draw Bezier curve
void Draw_Bezier(CPoint2D *ctrlPts, int nCtrlPts, int nBezCurvePts)
// nctrl --- Number of control points
// cp --- Array of control points
// m --- Number of subdivision
{
// Write your code here
CPoint2D bezCurvePt;
GLfloat u;
GLint *C, k;
C = new GLint[nCtrlPts];
binomialCoeffs(nCtrlPts - 1, C);
for (k = 0; k <= nBezCurvePts; k++)
{
u = GLfloat(k) / GLfloat(nBezCurvePts);
computeBezPt(u, &bezCurvePt, nCtrlPts,ctrlPts,C);
plotPoint(bezCurvePt);
}
delete[]C;
}

// Display callback function
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);

// Draw control points
// Write your code here
glColor4ub(255, 0, 0,255);
glPointSize(10.0f);
glBegin(GL_POINTS);
printf("\n%d %f %f \n", ic_cp,control_points[ic_cp-1].x, control_points[ic_cp-1].y);
for(int i=0;i<ic_cp;i++)
glVertex2f(control_points[i].x,control_points[i].y);
glEnd();
// Draw control graph
// Write your code here
glColor3f(255, 0.0, 0.0);
glEnable(GL_LINE_STIPPLE);
glLineStipple(2, 0x0f0f);
glLineWidth(2);
glBegin(GL_LINES);

for (int i = 1; i < ic_cp; i++)
{
glVertex2f(control_points[i - 1].x, control_points[i - 1].y);
glVertex2f(control_points[i].x, control_points[i].y);
}
glDisable(GL_LINE_STIPPLE);
glEnd();
// Draw Bezier curve
// Write your code here
Draw_Bezier(control_points,ic_cp,1000);
glutSwapBuffers();
}

// Mouse callback function
void mouse_func(int button, int state, int x, int y)
{
float dis;
if (button==GLUT_LEFT_BUTTON)
{
if ((state==GLUT_DOWN)&(running_state==0)&(ic_cp<n_cp))
{
control_points[ic_cp].x=x;
control_points[ic_cp].y=pw_height-y;
ic_cp++;
if (ic_cp==n_cp)
running_state=1;
glutPostRedisplay();
}
else if ((state==GLUT_DOWN)&(running_state==1))
{
for (int i=0 ;i<n_cp;i++)
{
dis=(x-control_points[i].x)*(x-control_points[i].x)+(pw_height-y-control_points[i]
4000
.y)*(pw_height-y-control_points[i].y);
if (dis < 0)
dis = -dis;
if (dis<10)
{
i_cp=i;
running_state=2;
break;
}
}
}
else if ((state==GLUT_DOWN)&(running_state==2))
{
control_points[i_cp].x=x;
control_points[i_cp].y=pw_height-y;
glutPostRedisplay();
}
else if ((state==GLUT_UP)&(running_state==2))
{
running_state=1;
}
}
}
// Mouse motion callback function
void motion_func(int x, int y)
{

if (running_state==2)
{
control_points[i_cp].x=x;
control_points[i_cp].y=pw_height-y;
glutPostRedisplay();
}
}
// Initialization function
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glEnable(GL_LINE_STIPPLE);

}

// Reshape callback function
void reshape(int w, int h)
{
pw_width=w;
pw_height=h;

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D (0.0, w, 0.0, h);
}

// Keyboard callback function
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
}
}

// Main program entrance
int main(int argc, char* argv[])
{
// Input number of control points
printf("Number of control points = ");
scanf("%d", &n_cp);
if (n_cp<2) return 1;
control_points=new CPoint2D[n_cp];
running_state=0;
ic_cp=0;

glutInit(&argc, argv);
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutCreateWindow("Test Bézier Curve");
init();
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse_func);
glutMotionFunc(motion_func);
glutDisplayFunc(display);
glutMainLoop();

delete [] control_points;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: