Cairo图形指南(9)——变换.doc_第1页
Cairo图形指南(9)——变换.doc_第2页
Cairo图形指南(9)——变换.doc_第3页
Cairo图形指南(9)——变换.doc_第4页
Cairo图形指南(9)——变换.doc_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Cairo 图形指南 (9) 变换这一篇讲述变换(Transformation) 仿射变换是由一些线性变换与平移构成的。线性变换可以写为单个矩阵的形式。旋转是让一个刚体绕一点运动的变换。缩放变换是让物体的形状扩大与减小,并且在 各个方向上的缩放因子都相同。平移变换将每个点沿着指定的方向移动常量距离。错切对于给定轴线,沿垂直于它的方向对物体进行移动的变换,并且在轴线的一侧 的移动距离大于另一侧。上述内容来自维基百科全书平移下面这个例子演示了一个简单的平移变换。?1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556#include #include static gbooleanon_expose_event(GtkWidget *widget,GdkEventExpose *event,gpointer data)cairo_t *cr;cr = gdk_cairo_create (widget-window);cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);cairo_rectangle(cr, 20, 20, 80, 50);cairo_stroke_preserve(cr);cairo_set_source_rgb(cr, 1, 1, 1);cairo_fill(cr);cairo_translate(cr, 100, 100);cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);cairo_rectangle(cr, 20, 20, 80, 50);cairo_stroke_preserve(cr);cairo_set_source_rgb(cr, 1, 1, 1);cairo_fill(cr);cairo_destroy(cr);return FALSE;int main(int argc, char *argv)GtkWidget *window;gtk_init(&argc, &argv);window = gtk_window_new(GTK_WINDOW_TOPLEVEL);g_signal_connect(window, expose-event,G_CALLBACK (on_expose_event), NULL);g_signal_connect(window, destroy,G_CALLBACK (gtk_main_quit), NULL);gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);gtk_window_set_default_size(GTK_WINDOW(window), 300, 230); gtk_widget_set_app_paintable(window, TRUE);gtk_widget_show_all(window);gtk_main();return 0;这个例子先是画了个矩形,然后将它平移并绘制出平移结果。?1cairo_translate(cr, 100, 100);cairo_translate() 函数可通过平移用于空间的原点来修改当前的变换矩阵。在这个示例中,是将原点沿水平和竖直方向平移了 100 个单位长度。旋转下面这个例子演示了一个简单的旋转变换。?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758#include #include #include static gbooleanon_expose_event(GtkWidget *widget,GdkEventExpose *event,gpointer data)cairo_t *cr;cr = gdk_cairo_create (widget-window);cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);cairo_rectangle(cr, 20, 20, 80, 50);cairo_stroke_preserve(cr);cairo_set_source_rgb(cr, 1, 1, 1);cairo_fill(cr);cairo_translate(cr, 150, 100);cairo_rotate(cr, M_PI/2);cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);cairo_rectangle(cr, 20, 20, 80, 50);cairo_stroke_preserve(cr);cairo_set_source_rgb(cr, 1, 1, 1);cairo_fill(cr);cairo_destroy(cr);return FALSE;int main(int argc, char *argv)GtkWidget *window;gtk_init(&argc, &argv);window = gtk_window_new(GTK_WINDOW_TOPLEVEL);g_signal_connect(window, expose-event,G_CALLBACK (on_expose_event), NULL);g_signal_connect(window, destroy,G_CALLBACK (gtk_main_quit), NULL);gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);gtk_window_set_default_size(GTK_WINDOW(window), 300, 230); gtk_widget_set_app_paintable(window, TRUE);gtk_widget_show_all(window);gtk_main();return 0;这个例子先是画了个矩形,然后对它进行了平移和旋转变换,并绘制出变换结果。?12cairo_translate(cr, 150, 100);cairo_rotate(cr, M_PI/2);首先对用户空间的原点进行平移,然后再围绕它旋转 180。注意:旋转角度是弧度,而非角度。缩放下面这个例子演示了一个对象的缩放变换。(作者还真是沉闷阿,相同的句式连用了 n 次,这个可怜的矩形被折腾的痛苦不堪!)?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172#include #include static gbooleanon_expose_event(GtkWidget *widget,GdkEventExpose *event,gpointer data)cairo_t *cr;cr = gdk_cairo_create (widget-window);cairo_save(cr);cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);cairo_rectangle(cr, 20, 30, 80, 50);cairo_stroke_preserve(cr);cairo_set_source_rgb(cr, 1, 1, 1);cairo_fill(cr);cairo_restore(cr);cairo_save(cr);cairo_translate(cr, 130, 30);cairo_scale(cr, 0.7, 0.7);cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);cairo_rectangle(cr, 0, 0, 80, 50);cairo_stroke_preserve(cr);cairo_set_source_rgb(cr, 1, 1, 1);cairo_fill(cr);cairo_restore(cr);cairo_save(cr);cairo_translate(cr, 220, 30);cairo_scale(cr, 1.5, 1.5);cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);cairo_rectangle(cr, 0, 0, 80, 50);cairo_stroke_preserve(cr);cairo_set_source_rgb(cr, 1, 1, 1);cairo_fill(cr);cairo_restore(cr);cairo_destroy(cr);return FALSE;int main(int argc, char *argv)GtkWidget *window;gtk_init(&argc, &argv);window = gtk_window_new(GTK_WINDOW_TOPLEVEL);g_signal_connect(window, expose-event,G_CALLBACK (on_expose_event), NULL);g_signal_connect(window, destroy,G_CALLBACK (gtk_main_quit), NULL);gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);gtk_window_set_default_size(GTK_WINDOW(window), 360, 140); gtk_widget_set_app_paintable(window, TRUE);gtk_widget_show_all(window);gtk_main();return 0;这次的例子是用指定的缩放因子,把初始的矩形变的小了点,然后又把它变的大了点。?123cairo_save(cr);.cairo_restore(cr);若对初始的矩形完成两次缩放操作,需要将初始的变换矩阵保存一下,这个可通过 cairo_save() 和 cairo_restore() 函数来实现。?12cairo_translate(cr, 130, 30);cairo_scale(cr, 0.7, 0.7);这里首先将用户空间的原点平移了一下,然后又开始用 0.7 作为因子进行缩放变换。错切在下面的示例中,我们来实现错切变换。?1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283#include #include static gbooleanon_expose_event(GtkWidget *widget,GdkEventExpose *event,gpointer data)cairo_t *cr;cairo_matrix_t matrix;cr = gdk_cairo_create (widget-window);cairo_save(cr);cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);cairo_rectangle(cr, 20, 30, 80, 50);cairo_stroke_preserve(cr);cairo_set_source_rgb(cr, 1, 1, 1);cairo_fill(cr);cairo_restore(cr);cairo_save(cr);cairo_translate(cr, 130, 30);cairo_matrix_init(&matrix,1.0, 0.5,0.0, 1.0,0.0, 0.0);cairo_transform (cr, &matrix);cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);cairo_rectangle(cr, 0, 0, 80, 50);cairo_stroke_preserve(cr);cairo_set_source_rgb(cr, 1, 1, 1);cairo_fill(cr);cairo_restore(cr);cairo_save(cr);cairo_translate(cr, 220, 30);cairo_matrix_init(&matrix,1.0, 0.0,0.7, 1.0,0.0, 0.0);cairo_transform(cr, &matrix);cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);cairo_rectangle(cr, 0, 0, 80, 50);cairo_stroke_preserve(cr);cairo_set_source_rgb(cr, 1, 1, 1);cairo_fill(cr);cairo_restore(cr);cairo_destroy(cr);return FALSE;int main(int argc, char *argv)GtkWidget *window;gtk_init(&argc, &argv);window = gtk_window_new(GTK_WINDOW_TOPLEVEL);g_signal_connect(window, expose-event,G_CALLBACK(on_expose_event), NULL);g_signal_connect(window, destroy,G_CALLBACK(gtk_main_quit), NULL);gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);gtk_window_set_default_size(GTK_WINDOW(window), 360, 140); gtk_widget_set_app_paintable(window, TRUE);gtk_widget_show_all(window);gtk_main();return 0;这份示例代码实现了两次错切变换。对于错切变换,没有特定的函数,必须使用矩阵来实现。?1cairo_matrix_t matrix;这个 cairo_matrix 是存储仿射变换的数据结构。?123456cairo_matrix_init(&matrix,1.0, 0.5,0.0, 1.0,0.0, 0.0);cairo_transform (cr, &matrix);这一变换的数学形式可表示为:?123456cairo_matrix_init(&matrix,1.0, 0.0,0.7, 1.0,0.0, 0.0);cairo_transform(cr, &matrix);这一变换的数学形式可表示为:椭圆下面的这个例子,画了一个灰常复杂的形状,它由一串旋转的椭圆形成。?1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162#include #include static gbooleanon_expose_event(GtkWidget *widget,GdkEventExpose *event,gpointer data)cairo_t *cr;cr = gdk_cairo_create(widget-window);gint width, height;gtk_window_get_size(GTK_WINDOW(widget), &width, &height); cairo_set_line_width(cr, 0.5);cairo_translate(cr, width/2, height/2);cairo_arc(cr, 0, 0, 120, 0, 2 * M_PI);cairo_stroke(cr);gint i;cairo_save(cr);for ( i = 0; i 36; i+) cairo_rotate(cr, i*M_PI/36);cairo_scale(cr, 0.3, 1);cairo_arc(cr, 0, 0, 120, 0, 2 * M_PI);cairo_restore(cr);cairo_stroke(cr);cairo_save(cr);cairo_destroy(cr);return FALSE;int main(int argc, char *argv)GtkWidget *window;gtk_init(&argc, &argv);window = gtk_window_new(GTK_WINDOW_TOPLEVEL);g_signal_connect(G_OBJECT(window), expose-event,G_CALLBACK(on_expose_event), NULL);g_signal_connect(G_OBJECT(window), destroy,G_CALLBACK(gtk_main_quit), NULL);gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);gtk_window_set_default_size(GTK_WINDOW(window), 350, 250); gtk_widget_set_app_paintable(window, TRUE);gtk_widget_show_all(window);gtk_main();return 0;?123cairo_translate(cr, width/2, height/2);cairo_arc(cr, 0, 0, 120, 0, 2 * M_PI);cairo_stroke(cr);在 GTK+ 的窗口中间,绘制了一个圆,它是那些椭圆的边界圆。?123456789cairo_save(cr);for ( i = 0; i 36; i+) cairo_rotate(cr, i*M_PI/36);cairo_scale(cr, 0.3, 1);cairo_arc(cr, 0, 0, 120, 0, 2 * M_PI);cairo_restore(cr);cairo_stroke(cr);cairo_save(cr);沿着边界圆画 36 个椭圆。椭圆可用圆的缩放变换而获得。旋转这个椭圆,这样就创建了一个有趣的形状。星星下面的示例绘制了一个又旋转又缩放的星星,可惜不会发光呃。?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105#include #include #include int points112 = 0, 85 , 75, 75 , 100, 10 , 125, 75 , 200, 85 , 150, 125 , 160, 190 , 100, 150 , 40, 190 , 50, 125 , 0, 85 ;static gbooleanon_expose_event(GtkWidget *widget,GdkEventExpose *event,gpointer data)cairo_t *cr;static gdouble angle = 0;static gdouble scale = 1;static gdouble delta = 0.01;gint width, height;gtk_window_get_size(GTK_WINDOW(widget), &width, &height);cr = gdk_cairo_create(widget-window);cairo_set_source_rgb(cr, 0, 0.44, 0.7);cairo_set_line_width(cr, 1);cairo_translate(cr, width / 2, height / 2 );cairo_rotate(cr, angle);cairo_scale(cr, scale, scale);gint i;for ( i = 0; i 10; i+ ) cairo_line_to(cr, pointsi0, pointsi1);cairo_close_path(cr);cairo_fill(cr);cairo_stroke(cr);if ( scale 0.99) delta = -delta;scale += delta;angle += 0.01;cairo_destroy(cr);return FALSE;static gbooleantime_handler (GtkWidget *widget)if (widget-window = NULL) return FALSE;gt

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论