/*
key 'q' quit
key 'c' clear screen
key 'e' erase curve
鼠标左键点击空白处,添加点
鼠标左键点击点,选中点,此时拖动鼠标,可移动所选中的点
鼠标右键点击点,删除点
*/
#include<cstdlib>
#include<stdio.h>
#include <gl/glut.h>
void keyboard( unsigned char key , int x, int y );
#define MAX_CPTS 1000 // 控制点最大数目
const int MESH = 50; // 切分段数
float bPoints[MESH][3];
GLfloat cpts[MAX_CPTS][3];
GLfloat cpts2[MAX_CPTS][3]; // store points when calculate Bezier
bool trackingMouse = false;
int index = -1;
int ncpts = 0 ;
static int width = 500 , height = 500; // 绘制窗口的宽度和高度
void calPoint( float t ) // t is the parameter in Bezier Curve
{
for( int i = 0 ; i<ncpts ; i++ )
for( int j = 0 ; j<3 ; j++ )
cpts2[i][j] = cpts[i][j];
for( int i = 0 ; i<ncpts-1 ; i++ ) // recur times
for( int j = 0 ; j<ncpts-1-i ; j++ )
for( int k =0 ; k<2 ; k++ ) // coordinate z is not calculated
cpts2[j][k] = (1-t)*cpts2[j][k] + t*cpts2[j+1][k] ;
}
void drawCurves()
{
if( ncpts==1 ) return ;
float interval = 1/(float)MESH;
float t = 0;
bPoints[0][0] = cpts[0][0];
bPoints[0][1] = cpts[0][1];
bPoints[MESH-1][0] = cpts[ncpts-1][0];
bPoints[MESH-1][1] = cpts[ncpts-1][1];
for( int k=1 ; k<MESH-1 ; k++ )
{
t+=interval;
calPoint( t );
for( int i=0 ; i<2 ; i++ )
bPoints[k][i] = cpts2[0][i] ;
}
glColor3f(1.0 , 0.0 , 0.0 ); // chang color to red
glBegin( GL_LINE_STRIP );
for( int i=0 ; i<MESH ; i++ )
glVertex3fv( bPoints[i] );
glEnd();
}
void drawPoints()
{
glColor3f( 0.0 , 0.0 , 0.0); // change color to black
glBegin(GL_POINTS);
for( int i=0 ; i<ncpts ; i++)
{
glVertex3fv(cpts[i]);
}
glEnd();
glColor3f( 0.0 , 1.0 , 1.0 ); // change color to yellow
glBegin(GL_LINE_STRIP);
for( int i=0 ; i<ncpts ; i++ )
glVertex3fv( cpts[i] );
glEnd();
}
void showList()
{
printf("========\n");
for( int i=0 ; i<ncpts ; i++ )
{
printf("\t\t\t%f %f\n" , cpts[i][0] , cpts[i][1] );
}
printf("========\n");
}
void drawElements()
{
drawPoints();
drawCurves();
showList();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
}
int check( float x , float y )
{
// if point(x , y ) is close to any point in array 'cpts' , return the index , else return -1
for( int i=0 ; i<ncpts ; i++ )
{
if( (cpts[i][0]-x)*(cpts[i][0]-x) + (cpts[i][1]-y)*(cpts[i][1]-y) <=0.0003 )
return i;
}
return -1;
}
void addPoint( float wx , float wy )
{
// 判断是否还可以定义更多的控制点
if( ncpts == MAX_CPTS ) return ;
// 储存控制点的位置
cpts[ncpts][0] = wx ;
cpts[ncpts][1] = wy ;
cpts[ncpts][2] = 0.0 ;
ncpts++;
glutPostRedisplay();
drawElements();
glFlush();
}
void action_LeftDown( float wx , float wy)
{
index = check( wx , wy );
if( index>-1 )
{
trackingMouse = true;
printf("start tracking.\n");
}
else
addPoint( wx , wy );
}
void action_LeftUp()
{
trackingMouse = false;
}
void action_DeletePoint(float wx , float wy)
{
printf( "delete point ");
index = check(wx , wy );
if( index==-1 )
{
return ;
}
else // delete the point chosen , and move the rest points forward
{
for( int i=index+1 , j = index ; i<ncpts ; i++ , j++ )
{
for( int k=0 ; k<2 ; k++) // move next point i to point i-1
cpts[j][k]=cpts[i][k];
}
ncpts--;
}
showList();
glutPostRedisplay();
drawElements();
glFlush();
}
void mouse( int button , int state , int x , int y )
{
float wx , wy ;
// 把鼠标的位置逆向变换到世界坐标系
wx = (2.0*x)/ (float)(width-1) - 1.0 ;
wy = (2.0 *(height -1-y) ) / (float)(height-1) -1.0;
if( button==GLUT_RIGHT_BUTTON && state ==GLUT_DOWN )
{
action_DeletePoint(wx , wy );
showList();
}
if( button==GLUT_LEFT_BUTTON )
{
switch( state )
{
case GLUT_DOWN:
action_LeftDown(wx , wy );
break;
case GLUT_UP:
action_LeftUp();
showList();
break;
}
}
}
void mouseMotion( int x , int y)
{
float wx = (2.0*x)/ (float)(width-1) - 1.0 ;
float wy = (2.0 *(height -1-y) ) / (float)(height-1) -1.0;
cpts[index][0] = wx ;
cpts[index][1] = wy ;
glutPostRedisplay();
drawElements();
glFlush();
}
void keyboard(unsigned char key , int x , int y)
{
switch(key)
{
case 'q':case'Q':
exit(0);
break;
case 'c':case'C':
ncpts = 0 ;
glutPostRedisplay();
glFlush();
break;
case'e':case'E':
glutPostRedisplay();
break;
}
}
void reshape( int w , int h)
{
width = w ;
height = h ;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0 , 1.0 , -1.0 , 1.0 , -1.0 , 1.0 );
glMatrixMode(GL_MODELVIEW);
glViewport(0 , 0 , w , h );
}
int main(int argc , char **argv)
{
glutInit(&argc , argv);
glutInitDisplayMode( GLUT_RGB );
glutInitWindowSize(width , height);
glutCreateWindow("Bezier curves");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(mouseMotion);
glutReshapeFunc(reshape);
glClearColor(1.0 , 1.0 , 1.0 , 1.0 );
glColor3f(0.0 , 0.0 , 0.0 );
glPointSize(5.0);
glutMainLoop();
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
Bezier.rar (30个子文件)
Bezier
Debug
Bezier.ilk 348KB
Bezier.exe 32KB
Bezier.pdb 379KB
ipch
bezier-d918ecd6
bezier-631bcc6d.ipch 3MB
Bezier
BezierSurface.cpp 524B
Bezier.vcxproj 3KB
Debug
cl.command.1.tlog 2KB
CL.read.1.tlog 7KB
vc100.idb 75KB
mt.read.1.tlog 610B
link.read.1.tlog 3KB
Bezier2.obj 25KB
link.write.1.tlog 632B
CL.write.1.tlog 1KB
Bezier.obj 21KB
vc100.pdb 68KB
BezierSurface.obj 6KB
Bezier.log 2KB
Bezier.lastbuildstate 53B
Bezier.exe.intermediate.manifest 381B
link.command.1.tlog 2KB
mt.write.1.tlog 238B
mt.command.1.tlog 412B
Bezier.vcxproj.user 143B
Bezier2.cpp 5KB
Bezier.vcxproj.filters 1KB
Bezier.cpp 4KB
Bezier.sdf 24.33MB
Bezier.suo 11KB
Bezier.sln 885B
共 30 条
- 1
资源评论
- IZUMI-KOUSHIRO2015-05-15之前只会写规定阶数的beizer 看了之后学习了
- q19735552012-12-14为什么运行的时候有错误,但还是能运行成功呢?另外再点击作图的时候为什么松开鼠标就看不见做出的图了,必须在加点的时候不松鼠标才能看见?
- norriswang2016-01-22还不错,学习了!
- huangruodan2014-05-25感觉挺好的 可以交作业了
- andr_ew2012-07-25通过楼主的帮助我也完成了自己的bezier曲线绘制程序,多谢楼主分享~
lainegates
- 粉丝: 295
- 资源: 8
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功