<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 變換 > 原文: [https://zetcode.com/gfx/cairo/transformations/](https://zetcode.com/gfx/cairo/transformations/) 在 Cairo 圖形編程教程的這一部分中,我們將討論變換。 仿射變換由零個或多個線性變換(旋轉,縮放或剪切)和平移(移位)組成。 幾個線性變換可以組合成一個矩陣。 旋轉是使剛體繞固定點移動的變換。 縮放比例是一種放大或縮小對象的變換。 比例因子在所有方向上都是相同的。 變換是一種變換,可以使每個點在指定方向上移動恒定的距離。 剪切是一種將對象垂直于給定軸移動的變換,該值在軸的一側比另一側更大。 數據來源:(wikipedia.org,freedictionary.com) ## 平移 以下示例描述了一個簡單的平移。 ```c static void do_drawing(cairo_t *cr) { cairo_set_source_rgb(cr, 0.2, 0.3, 0.8); cairo_rectangle(cr, 10, 10, 30, 30); cairo_fill(cr); cairo_translate(cr, 20, 20); cairo_set_source_rgb(cr, 0.8, 0.3, 0.2); cairo_rectangle(cr, 0, 0, 30, 30); cairo_fill(cr); cairo_translate(cr, 30, 30); cairo_set_source_rgb(cr, 0.8, 0.8, 0.2); cairo_rectangle(cr, 0, 0, 30, 30); cairo_fill(cr); cairo_translate(cr, 40, 40); cairo_set_source_rgb(cr, 0.3, 0.8, 0.8); cairo_rectangle(cr, 0, 0, 30, 30); cairo_fill(cr); } ``` 該示例畫一個矩形。 然后,我們進行平移并再次繪制相同的矩形。 ```c cairo_translate(cr, 20, 20); ``` `cairo_translate()`函數通過變換用戶空間原點來修改當前變換矩陣。 在我們的例子中,我們在兩個方向上將原點移動了 20 個單位。 ![Translation](https://img.kancloud.cn/92/a5/92a56884d3b90a426ed1801762727430_252x206.jpg) 圖:平移 ## 剪切 在以下示例中,我們執行剪切操作。 剪切是沿特定軸的對象變形。 此操作沒有剪切功能。 我們需要創建自己的變換矩陣。 注意,可以通過創建變換矩陣來執行每個仿射變換。 ```c static void do_drawing(cairo_t *cr) { cairo_matrix_t matrix; cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_rectangle(cr, 20, 30, 80, 50); cairo_fill(cr); cairo_matrix_init(&matrix, 1.0, 0.5, 0.0, 1.0, 0.0, 0.0); cairo_transform(cr, &matrix); cairo_rectangle(cr, 130, 30, 80, 50); cairo_fill(cr); } ``` 在此代碼示例中,我們執行一個簡單的剪切操作。 ```c cairo_matrix_t matrix; ``` `cairo_matrix_t`是具有仿射變換的結構。 ```c cairo_matrix_init(&matrix, 1.0, 0.5, 0.0, 1.0, 0.0, 0.0); ``` 此變換將 y 值剪切為 x 值的 0.5。 ```c cairo_transform(cr, &matrix); ``` 我們使用`transform()`方法執行變換。 ![Shearing](https://img.kancloud.cn/6a/4d/6a4d03c15ceb4c32f2cb3b5bb6f0018a_342x266.jpg) 圖:抖動 ## 縮放 下一個示例演示了縮放操作。 縮放是一種變換操作,其中對象被放大或縮小。 ```c static void do_drawing(cairo_t *cr) { cairo_set_source_rgb(cr, 0.2, 0.3, 0.8); cairo_rectangle(cr, 10, 10, 90, 90); cairo_fill(cr); cairo_scale(cr, 0.6, 0.6); cairo_set_source_rgb(cr, 0.8, 0.3, 0.2); cairo_rectangle(cr, 30, 30, 90, 90); cairo_fill(cr); cairo_scale(cr, 0.8, 0.8); cairo_set_source_rgb(cr, 0.8, 0.8, 0.2); cairo_rectangle(cr, 50, 50, 90, 90); cairo_fill(cr); } ``` 我們繪制三個`90x90px`的矩形。 在其中兩個上,我們執行縮放操作。 ```c cairo_scale(cr, 0.6, 0.6); cairo_set_source_rgb(cr, 0.8, 0.3, 0.2); cairo_rectangle(cr, 30, 30, 90, 90); cairo_fill(cr); ``` 我們將矩形均勻縮放 0.6 倍。 ```c cairo_scale(cr, 0.8, 0.8); cairo_set_source_rgb(cr, 0.8, 0.8, 0.2); cairo_rectangle(cr, 50, 50, 90, 90); cairo_fill(cr); ``` 在這里,我們以 0.8 的系數執行另一個縮放操作。 如果看圖片,我們看到第三個黃色矩形是最小的矩形。 即使我們使用了較小的比例因子。 這是因為變換操作是累加的。 實際上,第三個矩形的縮放比例為 0.528(`0.6x0.8`)。 ![Scaling](https://img.kancloud.cn/e0/24/e024ccb53be4d319933995239727a775_262x206.jpg) 圖:縮放 ## 隔離變換 變換操作是累加的。 為了將一個操作與另一個操作隔離開,我們可以使用`cairo_save()`和`cairo_restore()`函數。 `cairo_save()`函數可復制圖形上下文的當前狀態,并將其保存在已保存狀態的內部棧中。 `cairo_restore()`函數將把上下文重新建立為保存狀態。 ```c static void do_drawing(cairo_t *cr) { cairo_set_source_rgb(cr, 0.2, 0.3, 0.8); cairo_rectangle(cr, 10, 10, 90, 90); cairo_fill(cr); cairo_save(cr); cairo_scale(cr, 0.6, 0.6); cairo_set_source_rgb(cr, 0.8, 0.3, 0.2); cairo_rectangle(cr, 30, 30, 90, 90); cairo_fill(cr); cairo_restore(cr); cairo_save(cr); cairo_scale(cr, 0.8, 0.8); cairo_set_source_rgb(cr, 0.8, 0.8, 0.2); cairo_rectangle(cr, 50, 50, 90, 90); cairo_fill(cr); cairo_restore(cr); } ``` 在示例中,我們縮放了兩個矩形。 這次我們將縮放操作相互隔離。 ```c cairo_save(cr); cairo_scale(cr, 0.6, 0.6); cairo_set_source_rgb(cr, 0.8, 0.3, 0.2); cairo_rectangle(cr, 30, 30, 90, 90); cairo_fill(cr); cairo_restore(cr); ``` 我們通過將`cairo_save()`和`cairo_restore()`函數之間的`cairo_scale()`函數隔離縮放操作。 ![Isolating transformations](https://img.kancloud.cn/78/c8/78c89624543c0d2f1a3669cb3c9bb26e_252x206.jpg) 圖:隔離轉換 現在,第三個黃色矩形大于第二個紅色矩形。 ## 甜甜圈 在下面的示例中,我們通過旋轉一堆橢圓來創建復雜的形狀。 ```c #include <cairo.h> #include <gtk/gtk.h> #include <math.h> static void do_drawing(cairo_t *, GtkWidget *widget); static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { do_drawing(cr, widget); return FALSE; } static void do_drawing(cairo_t *cr, GtkWidget *widget) { GtkWidget *win = gtk_widget_get_toplevel(widget); gint width, height; gtk_window_get_size(GTK_WINDOW(win), &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; for (i = 0; i < 36; i++) { cairo_save(cr); 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); } } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *darea; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); darea = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER (window), darea); g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(on_draw_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_window_set_title(GTK_WINDOW(window), "Donut"); gtk_widget_show_all(window); gtk_main(); return 0; } ``` 我們將進行旋轉和縮放操作。 我們還將保存和恢復 Cairo 上下文。 ```c cairo_translate(cr, width/2, height/2); cairo_arc(cr, 0, 0, 120, 0, 2 * M_PI); cairo_stroke(cr); ``` 在 GTK+ 窗口的中間,我們創建了一個圓。 這將是我們橢圓的邊界圓。 ```c gint i; for (i = 0; i < 36; i++) { cairo_save(cr); 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); } ``` 我們沿著邊界圓的路徑創建了 36 個橢圓。 我們使用`cairo_save()`和`cairo_restore()`方法將每個旋轉和縮放操作相互隔離。 ## 星星 下一個示例顯示了一個旋轉和縮放的星星。 ```c #include <cairo.h> #include <gtk/gtk.h> static void do_drawing(cairo_t *, GtkWidget *widget); 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 } }; static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { do_drawing(cr, widget); return FALSE; } static void do_drawing(cairo_t *cr, GtkWidget *widget) { static gdouble angle = 0; static gdouble scale = 1; static gdouble delta = 0.01; GtkWidget *win = gtk_widget_get_toplevel(widget); gint width, height; gtk_window_get_size(GTK_WINDOW(win), &width, &height); 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; } static gboolean time_handler(GtkWidget *widget) { gtk_widget_queue_draw(widget); return TRUE; } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *darea; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); darea = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER (window), darea); g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(on_draw_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), 400, 300); gtk_window_set_title(GTK_WINDOW(window), "Star"); g_timeout_add(10, (GSourceFunc) time_handler, (gpointer) window); gtk_widget_show_all(window); gtk_main(); return 0; } ``` 在此示例中,我們創建一個星形對象。 我們將對其進行平移,旋轉和縮放。 ```c int points[11][2] = { { 0, 85 }, { 75, 75 }, { 100, 10 }, ... ``` 從這些點將構造星形對象。 ```c static gdouble angle = 0; static gdouble scale = 1; static gdouble delta = 0.01; ``` 我們初始化三個重要變量。 角度用于旋轉,比例用于縮放星形對象。 `delta`變量控制星星何時生長以及何時收縮。 ```c cairo_translate(cr, width/2, height/2); cairo_rotate(cr, angle); cairo_scale(cr, scale, scale); ``` 我們將星星移到窗口中間。 旋轉并縮放比例。 ```c 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); ``` 在這里,我們繪制星形對象。 ```c if ( scale < 0.01 ) { delta = -delta; } else if (scale > 0.99) { delta = -delta; } ``` 這些線控制星形對象的生長或收縮。 在 Cairo 圖形教程的這一部分中,我們討論了變換。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看