利用linux gtk模拟运动小球的轨迹.docx
- 文档编号:17957996
- 上传时间:2023-08-05
- 格式:DOCX
- 页数:11
- 大小:125.89KB
利用linux gtk模拟运动小球的轨迹.docx
《利用linux gtk模拟运动小球的轨迹.docx》由会员分享,可在线阅读,更多相关《利用linux gtk模拟运动小球的轨迹.docx(11页珍藏版)》请在冰点文库上搜索。
利用linuxgtk模拟运动小球的轨迹
背景说明
利用linuxgtk编写c/c++程序,模拟小球在sin/cos曲线上进行运动的轨迹。
源码
/*
*cairo.cpp
*
*Createdon:
Jan5,2011
*Author:
sjetlin
*/
#include
#include
#include
//---------------------------------------
doublesin_start_x=0;//sin水平坐标系原点x坐标
doublecos_start_x=0;
doublesin_start_y=75;
doublecos_start_y=225;
doublesin_ball_x=0;//sin小球圆心坐标
doublecos_ball_x=0;
//---------------------------------------
doublesin_ball_speed_rad;//sin小球每次移动的弧度
doublecos_ball_speed_rad;
doubleround_time;//sin和cos曲线周期,单位是M_PI
//---------------------------------------
doubleamplitude=50;//曲线振幅
doublewidth;//水平坐标系包含的像素点,设置与窗口宽度相等
doublewidth_rad=8*M_PI;//水平坐标系表示的弧度,默认为8M_PI
//---------------------------------------
voidclicked(GtkWidget*widget,GdkEventExpose*event,gpointerdata);
voidsin_wave(cairo_t*cr);//画sin曲线
voidcos_wave(cairo_t*cr);//画sin小球
voidsin_ball(cairo_t*cr);//画cos曲线
voidcos_ball(cairo_t*cr);//画cos小球
//--------------------------------------
//staticgbooleanon_expose_event(GtkWidget*widget,GdkEventExpose*event,gpointerdata)
voidclicked(GtkWidget*widget,GdkEventExpose*event,gpointerdata)
{
cairo_t*cr=(cairo_t*)data;
width=widget->allocation.width;
while(sin_ball_x<=width||cos_ball_x<=width)
{//当两个小球都在运动时改变画布内容
cairo_set_source_rgb(cr,255,255,255);
cairo_rectangle(cr,0,0,400,300);
cairo_fill(cr);//清空画布
cairo_set_source_rgb(cr,255,0,0);//设置画笔为红色
cairo_set_line_width(cr,0.7);//设置画笔宽度
sin_wave(cr);
sin_ball(cr);
cos_wave(cr);
cos_ball(cr);
cairo_stroke(cr);
g_usleep(0.5*1000000);//暂停0.5秒
}
}
voidsin_wave(cairo_t*cr)
{
cairo_move_to(cr,sin_start_x,sin_start_y);
cairo_line_to(cr,width,sin_start_y);//画sin水平坐标系
cairo_select_font_face(cr,"Georgis",CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(cr,12);
cairo_move_to(cr,sin_start_x,sin_start_y);
cairo_show_text(cr,"0");
cairo_move_to(cr,sin_start_x+width-30,sin_start_y);
cairo_show_text(cr,"8PI");
cairo_move_to(cr,sin_start_x,sin_start_y);//曲线起点
doublex=sin_start_x;
doubleinc_x=1;
while(x<=width)
{
doublenext_x=x+inc_x;
cairo_line_to(cr,x+inc_x,sin_start_y-amplitude*sin(2
*width_rad*next_x/round_time/width));
x=x+inc_x;
}
}
voidcos_wave(cairo_t*cr)
{
cairo_move_to(cr,cos_start_x,cos_start_y);
cairo_line_to(cr,width,cos_start_y);//画cos水平坐标系
cairo_select_font_face(cr,"Georgis",CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(cr,12);
cairo_move_to(cr,cos_start_x,cos_start_y);
cairo_show_text(cr,"0");
cairo_move_to(cr,cos_start_x+width-30,cos_start_y);
cairo_show_text(cr,"8PI");
cairo_move_to(cr,cos_start_x,cos_start_y-50);//曲线起点
doublex=cos_start_x;
doubleinc_x=1;
while(x<=width)
{
doublenext_x=x+inc_x;
cairo_line_to(cr,next_x,cos_start_y-amplitude*cos(2*width_rad
*next_x/round_time/width));
x=x+inc_x;
}
}
voidsin_ball(cairo_t*cr)
{
if(sin_ball_x<=width)
{
doublesin_ball_radius=10;
doublesin_ball_y=sin_start_y-amplitude*sin(2*width_rad
*sin_ball_x/round_time/width);
cairo_move_to(cr,sin_ball_x+sin_ball_radius,sin_ball_y);
cairo_arc(cr,sin_ball_x,sin_ball_y,sin_ball_radius,0,2*M_PI);
sin_ball_x=sin_ball_x+sin_ball_speed_rad*M_PI*width/width_rad;
}
}
voidcos_ball(cairo_t*cr)
{
if(cos_ball_x<=width)
{
doublecos_ball_radius=10;
doublecos_ball_y=cos_start_y-amplitude*cos(2*width_rad
*cos_ball_x/round_time/width);
cairo_move_to(cr,cos_ball_x+cos_ball_radius,cos_ball_y);
cairo_arc(cr,cos_ball_x,cos_ball_y,cos_ball_radius,0,2*M_PI);
cos_ball_x=cos_ball_x+cos_ball_speed_rad*M_PI*width/width_rad;
}
}
intmain(intargc,char*argv[])
{
printf("请输入一个实数,代表曲线周期,单位是PI\n");
scanf("%lf",&round_time);
printf("请输入一个实数,代表第一个小球移动的弧度,单位是PI\n");
scanf("%lf",&sin_ball_speed_rad);
printf("请输入一个实数,代表第二个小球移动的弧度,单位是PI\n");
scanf("%lf",&cos_ball_speed_rad);
printf("\n已生成窗口,点击窗口中的空白区域即可查看动画\n\n");
gtk_init(&argc,&argv);
GtkWidget*window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),"sincos&&ball");
gtk_window_set_default_size(GTK_WINDOW(window),400,300);
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
gtk_widget_set_app_paintable(window,TRUE);
gtk_widget_show_all(window);
cairo_t*cr=gdk_cairo_create(window->window);//创建画布
gtk_widget_add_events(window,GDK_BUTTON_PRESS_MASK);
g_signal_connect(window,"button-press-event",G_CALLBACK(clicked),cr);//注册点击事件
g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
gtk_main();
return0;
}
源码说明
1.编程和编译环境:
Linux+Eclipse+CDT,文件名sport.c,可执行文件sport
2.程序运行时需输入3个变量,分别是曲线周期、sin小球运动速度、cos小球运动速度
3.程序的设计思想是先创建一块画布,画布的内容在小球运动时动态改变,直至两小球都运动到终点时停止。
4.小球运动时画布改变顺序如下:
①先用一块白布将画布上的所有内容抹掉
②用一根红笔画出sin曲线、cos曲线、sin小球、cos小球
5.当画布上的内容更新一次时暂停0.5秒,时间到时重复4的步骤,此时曲线不变,小球的圆心改变。
6.画sin曲线时先画出x轴,标出起终点的水平坐标(0~8PI),该曲线众多的点和小线段组成,点是经过精确计算的在sin曲线上的点,而线段则由这些点连接起来,并最终汇总成为一条曲线。
7.画移动的小球时,小球每次移动的弧度由键盘输入,将该弧度转换为转化水平像素点,再加上上一个圆心的x坐标,即可确定出目前小球圆心所在的x坐标,取该x坐标对应于曲线上的一点作为小球的圆心。
运行截图
1.进入文件目录
2.编译
3.执行
①首先,程序会给出输入提示信息,输入相应信息
②弹出执行窗口,点击空白区域后,执行一段时间后状态如下
在这张图片中,我们看到了坐标轴是从0~8PI,以后看到的坐标系都是这个范围的。
我们输入的周期是2PI,所以这里出现了4个周期的图形。
Sin小球和cos小球移动弧度都是1PI,每0.5秒小球会跳动一次。
上图中是4次以后的状态图。
此时,两个小球都移动了4PI。
③结束状态
4.改变参数后再次运行
①周期1PI,小球移动速度分别为2PI和1PI,移动2次。
②周期4PI,小球移动速度为1PI和1.5PI,移动3次。
③周期为8PI,小球移动速度分别为2PI和1PI,移动3次。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 利用linux gtk模拟运动小球的轨迹 利用 linux gtk 模拟 运动 小球 轨迹