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;
}
每次套公式得到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;
}
相关文章推荐
- 有关三边Bezier曲面的一个问题的试探
- BEZIER程序
- 【iOS-Cocos2d游戏开发之十三】CCSprite利用Bezier(贝塞尔)抛物线并同时播放两个Action动作! 推荐
- CGDIplus2Dlg::OnDrawBezier()
- Bezier贝塞尔曲线的原理、二次贝塞尔曲线的实现
- UIBezierPath + bezierPathWithArcCenter
- 利用de Casteljau算法绘制Bezier曲面
- 第26周-window程序设计(基础篇)-第5章(图形基础)-贝塞尔曲线BEZIER.C
- 【修正】问题五十五:怎么用ray tracing画Utah teapot (bicubic bezier patches)
- Unity3D教你制作Bezier和Spine曲线编辑器二
- cubic-bezier贝塞尔曲线CSS3动画工具
- Bézier Curve 简略论述(1)
- 中点法转化三次Bezier为二次Bezier,从C#到Flash
- opengl实现bezier、b曲线和曲面,16个控制点的4*4bezier块;最后可以看到茶壶teapot的实现
- windows程序设计 例题解析 BEZIER.C
- Bezier(贝塞尔曲线通用规律算法-DEMO)
- cubic-bezier贝塞尔曲线函数
- 经常被忽略的几个CSS3属性之强大应用(一、timing-function: steps() 二、animation-direction 三、timing-function: cubic-bezier())
- canvas的quadraticCurveTo和bezierCurveTo
- Q97:怎么用三角形网格细分Bezier曲面——以Utah Teapot为例