這一篇講述變換(Transformation) 仿射變換是由一些線性變換與平移構成的。線性變換可以寫為單個矩陣的形式。旋轉是讓一個剛體繞一點運動的變換。縮放變換是讓物體的形狀擴大與減小,并且在各個方向上的縮放因子都相同。平移變換将每個點沿着指定的方向移動常量距離。錯切對于給定軸線,沿垂直于它的方向對物體進行移動的變換,并且在軸線的一側的移動距離大于另一側。
——上述内容來自維基百科全書
平移
下面這個例子示範了一個簡單的平移變換。
[html] view plain copy print ?
- #include <cairo.h>
- #include <gtk/gtk.h>
- staticgboolean
- on_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);
- returnFALSE;
- }
- 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();
- return0;
- }
#include
<cairo.h>
#include <gtk/gtk.h>
staticgboolean
on_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);
returnFALSE;
}
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();
return0;
}
這個例子先是畫了個矩形,然後将它平移并繪制出平移結果。
|
cairo_translate() 函數可通過平移用于空間的原點來修改目前的變換矩陣。在這個示例中,是将原點沿水準和豎直方向平移了 100 個機關長度。

旋轉
下面這個例子示範了一個簡單的旋轉變換。
[html] view plain copy print ?
- #include <cairo.h>
- #include <gtk/gtk.h>
- #include <math.h>
- staticgboolean
- on_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);
- returnFALSE;
- }
- 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();
- return0;
- }
#include
<cairo.h>
#include <gtk/gtk.h>
#include <math.h>
staticgboolean
on_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);
returnFALSE;
}
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();
return0;
}
這個例子先是畫了個矩形,然後對它進行了平移和旋轉變換,并繪制出變換結果。
|
首先對使用者空間的原點進行平移,然後再圍繞它旋轉 180°。注意:旋轉角度是弧度,而非角度。
縮放
下面這個例子示範了一個對象的縮放變換。(作者還真是沉悶阿,相同的句式連用了 n 次,這個可憐的矩形被折騰的痛苦不堪!)
[html] view plain copy print ?
- #include <cairo.h>
- #include <gtk/gtk.h>
- staticgboolean
- on_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);
- returnFALSE;
- }
- 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();
- return0;
- }
#include
<cairo.h>
#include <gtk/gtk.h>
staticgboolean
on_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);
returnFALSE;
}
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();
return0;
}
這次的例子是用指定的縮放因子,把初始的矩形變的小了點,然後又把它變的大了點。
|
若對初始的矩形完成兩次縮放操作,需要将初始的變換矩陣儲存一下,這個可通過 cairo_save() 和 cairo_restore() 函數來實作。
|
這裡首先将使用者空間的原點平移了一下,然後又開始用 0.7 作為因子進行縮放變換。
錯切
在下面的示例中,我們來實作錯切變換。
[html] view plain copy print ?
- #include <cairo.h>
- #include <gtk/gtk.h>
- staticgboolean
- on_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);
- returnFALSE;
- }
- 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();
- return0;
- }
#include
<cairo.h>
#include <gtk/gtk.h>
staticgboolean
on_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);
returnFALSE;
}
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();
return0;
}
這份示例代碼實作了兩次錯切變換。對于錯切變換,沒有特定的函數,必須使用矩陣來實作。
|
這個 cairo_matrix 是存儲仿射變換的資料結構。
|
這一變換的數學形式可表示為:
|
這一變換的數學形式可表示為:
橢圓
下面的這個例子,畫了一個灰常複雜的形狀,它由一串旋轉的橢圓形成。
[html] view plain copy print ?
- #include <cairo.h>
- #include <gtk/gtk.h>
- staticgboolean
- on_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);
- returnFALSE;
- }
- 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();
- return0;
- }
#include
<cairo.h>
#include <gtk/gtk.h>
staticgboolean
on_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);
returnFALSE;
}
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();
return0;
}
|
在 GTK+ 的視窗中間,繪制了一個圓,它是那些橢圓的邊界圓。
|
沿着邊界圓畫 36 個橢圓。橢圓可用圓的縮放變換而獲得。旋轉這個橢圓,這樣就建立了一個有趣的形狀。
星星
下面的示例繪制了一個又旋轉又縮放的星星,可惜不會發光呃。
[html] view plain copy print ?
- #include <cairo.h>
- #include <gtk/gtk.h>
- #include <math.h>
- int points[11][2] = {
- { 0, 85 },
- { 75, 75 },
- { 100, 10 },
- { 125, 75 },
- { 200, 85 },
- { 150, 125 },
- { 160, 190 },
- { 100, 150 },
- { 40, 190 },
- { 50, 125 },
- { 0, 85 }
- };
- staticgboolean
- on_expose_event(GtkWidget *widget,
- GdkEventExpose *event,
- gpointer data)
- {
- cairo_t *cr;
- staticgdouble angle = 0;
- staticgdouble scale = 1;
- staticgdouble 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, points[i][0], points[i][1]);
- }
- cairo_close_path(cr);
- cairo_fill(cr);
- cairo_stroke(cr);
- if( scale < 0.01 ) {
- delta = -delta;
- }else if (scale > 0.99) {
- delta = -delta;
- }
- scale += delta;
- angle += 0.01;
- cairo_destroy(cr);
- returnFALSE;
- }
- staticgboolean
- time_handler (GtkWidget *widget)
- {
- if(widget->window == NULL) returnFALSE;
- gtk_widget_queue_draw(widget);
- returnTRUE;
- }
- int main(int argc,char *argv[])
- {
- GtkWidget *window;
- gtk_init(&argc, &argv);
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_widget_add_events (window, GDK_BUTTON_PRESS_MASK);
- 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_title(GTK_WINDOW(window),"star");
- gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
- gtk_widget_set_app_paintable(window, TRUE);
- g_timeout_add(10, (GSourceFunc) time_handler, (gpointer) window);
- gtk_widget_show_all(window);
- gtk_main();
- return0;
- }
#include
<cairo.h>
#include <gtk/gtk.h>
#include <math.h>
int points[11][2] = {
{ 0, 85 },
{ 75, 75 },
{ 100, 10 },
{ 125, 75 },
{ 200, 85 },
{ 150, 125 },
{ 160, 190 },
{ 100, 150 },
{ 40, 190 },
{ 50, 125 },
{ 0, 85 }
};
staticgboolean
on_expose_event(GtkWidget *widget,
GdkEventExpose *event,
gpointer data)
{
cairo_t *cr;
staticgdouble angle = 0;
staticgdouble scale = 1;
staticgdouble 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, points[i][0], points[i][1]);
}
cairo_close_path(cr);
cairo_fill(cr);
cairo_stroke(cr);
if( scale < 0.01 ) {
delta = -delta;
}else if (scale > 0.99) {
delta = -delta;
}
scale += delta;
angle += 0.01;
cairo_destroy(cr);
returnFALSE;
}
staticgboolean
time_handler (GtkWidget *widget)
{
if(widget->window == NULL) returnFALSE;
gtk_widget_queue_draw(widget);
returnTRUE;
}
int main(int argc,char *argv[])
{
GtkWidget *window;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_add_events (window, GDK_BUTTON_PRESS_MASK);
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_title(GTK_WINDOW(window),"star");
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
gtk_widget_set_app_paintable(window, TRUE);
g_timeout_add(10, (GSourceFunc) time_handler, (gpointer) window);
gtk_widget_show_all(window);
gtk_main();
return0;
}
在這個示例中,畫了一顆星星,然後平移它,旋轉它,縮放它。
|
先将星星平移到視窗中間,旋轉它,縮放它。(作者還真不是一般的羅嗦)
|
畫它!
|
這幾行代碼控制星星的縮放過程。
轉自 http://blog.csdn.net/haiwil/article/details/6771768