日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PyCairo 中的变换

發(fā)布時間:2024/4/11 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PyCairo 中的变换 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在 PyCairo 圖形學(xué)編程教程的這個部分,我們將討論變換。

一個 仿射變換 由 0 個或多個線性變換(旋轉(zhuǎn),放縮或切變)和平移(移位)組成。多個線性變換可以結(jié)合為以單個矩陣表示。 旋轉(zhuǎn) 是將一個剛體圍繞一個固定點移動的變換。放縮 是放大或縮小對象的變換。放縮系數(shù)在所有方向上都是相同的。平移 是在特定的方向上,將每個點都移動固定距離的變換。切變 是將物體垂直于給定軸移動,同時保持軸的一側(cè)的值比另一側(cè)的值大的變換。

是一個將一個對象正交的移動向給定的軸,同時保持軸某一側(cè)的值比另一側(cè)更大的變換。

來源: (wikipedia.org,freedictionary.com)

平移

下面的例子描述了一個簡單的平移。

def on_draw(self, wid, cr):cr.set_source_rgb(0.2, 0.3, 0.8)cr.rectangle(10, 10, 30, 30)cr.fill()cr.translate(20, 20)cr.set_source_rgb(0.8, 0.3, 0.2)cr.rectangle(0, 0, 30, 30)cr.fill()cr.translate(30, 30)cr.set_source_rgb(0.8, 0.8, 0.2)cr.rectangle(0, 0, 30, 30)cr.fill()cr.translate(40, 40)cr.set_source_rgb(0.3, 0.8, 0.8)cr.rectangle(0, 0, 30, 30)cr.fill()

這個例子先繪制了一個矩形。然后我們做平移,并多次繪制相同的矩形。

cr.translate(20, 20)

translate() 函數(shù)通過平移用戶空間原點修改當(dāng)前的變換矩陣。在我們的例子中,我們在兩個方向上將原點移動 20 個單位。

切變

在下面的例子中,我們執(zhí)行一個切變操作。切變是沿著一個特定的軸的物體變形。這個操作沒有切變方法。我們需要創(chuàng)建我們自己的變換矩陣。注意,每個仿射變換都可以通過創(chuàng)建變換矩陣來執(zhí)行。

def on_draw(self, wid, cr):cr.set_source_rgb(0.6, 0.6, 0.6)cr.rectangle(20, 30, 80, 50)cr.fill()mtx = cairo.Matrix(1.0, 0.5,0.0, 1.0,0.0, 0.0)cr.transform(mtx)cr.rectangle(130, 30, 80, 50)cr.fill()

在這段代碼中,我們執(zhí)行一個簡單的切變操作。

mtx = cairo.Matrix(1.0, 0.5,0.0, 1.0,0.0, 0.0)

這個變換將 y 值切變?yōu)?x 值的 0.5 倍。

cr.transform(mtx)

我們通過 transform() 方法執(zhí)行變換。

放縮

下一個例子演示放縮操作。放縮是將對象放大或縮小的變換操作。

def on_draw(self, wid, cr):cr.set_source_rgb(0.2, 0.3, 0.8)cr.rectangle(10, 10, 90, 90)cr.fill()cr.scale(0.6, 0.6)cr.set_source_rgb(0.8, 0.3, 0.2)cr.rectangle(30, 30, 90, 90)cr.fill()cr.scale(0.8, 0.8)cr.set_source_rgb(0.8, 0.8, 0.2)cr.rectangle(50, 50, 90, 90)cr.fill()

我們繪制三個 90 × 90 px 大小的矩形。對于其中的 2 個,我們執(zhí)行放縮操作。

cr.scale(0.6, 0.6)cr.set_source_rgb(0.8, 0.3, 0.2)cr.rectangle(30, 30, 90, 90)cr.fill()

我們均勻地用系數(shù) 0.6 縮小矩形。

cr.scale(0.8, 0.8)cr.set_source_rgb(0.8, 0.8, 0.2)cr.rectangle(50, 50, 90, 90)cr.fill()

這里我們用系數(shù) 0.8 執(zhí)行另一個放縮操作。如果我們查看圖片,我們將看到,第三個黃色矩形是最小的。即使我們已經(jīng)使用了另一個更小的放縮因子。這是由于變換操作是累積的。事實上,第三個矩形是由放縮因子 0.528 (0.6 ×0.8) 來放縮的。

隔離變換

變換操作是累積的。為了隔離各個操作,我們可以使用 save() 和 restore() 方法。save() 方法創(chuàng)建一份繪制上下文當(dāng)前狀態(tài)的拷貝,并將它存進一個保存狀態(tài)的內(nèi)部棧中。restore() 方法將重建上下文為保存的狀態(tài)。

def on_draw(self, wid, cr):cr.set_source_rgb(0.2, 0.3, 0.8)cr.rectangle(10, 10, 90, 90)cr.fill()cr.save()cr.scale(0.6, 0.6)cr.set_source_rgb(0.8, 0.3, 0.2)cr.rectangle(30, 30, 90, 90)cr.fill()cr.restore()cr.save()cr.scale(0.8, 0.8)cr.set_source_rgb(0.8, 0.8, 0.2)cr.rectangle(50, 50, 90, 90)cr.fill()cr.restore()

這個例子中我們放縮兩個矩形。這次我們隔離各個放縮操作。

cr.save()cr.scale(0.6, 0.6)cr.set_source_rgb(0.8, 0.3, 0.2)cr.rectangle(30, 30, 90, 90)cr.fill()cr.restore()

我們通過將 scale() 方法放到 save() 和 restore() 方法之間來隔離放縮操作。

現(xiàn)在第三個黃色矩形比第二個紅色的大。

甜甜圈

在下面的例子中,我們通過旋轉(zhuǎn)一束橢圓創(chuàng)建一個復(fù)雜的形狀。

#!/usr/bin/python''' ZetCode PyCairo tutorialThis program creates a 'donut' shape in PyCairo.author: Jan Bodnar website: zetcode.com last edited: August 2012 '''import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk import cairo import mathclass Example(Gtk.Window):def __init__(self):super(Example, self).__init__()self.init_ui()def init_ui(self):darea = Gtk.DrawingArea()darea.connect("draw", self.on_draw)self.add(darea)self.set_title("Donut")self.resize(350, 250)self.set_position(Gtk.WindowPosition.CENTER)self.connect("delete-event", Gtk.main_quit)self.show_all()def on_draw(self, wid, cr):cr.set_line_width(0.5)w, h = self.get_size()cr.translate(w / 2, h / 2)cr.arc(0, 0, 120, 0, 2 * math.pi)cr.stroke()for i in range(36):cr.save()cr.rotate(i * math.pi / 36)cr.scale(0.3, 1)cr.arc(0, 0, 120, 0, 2 * math.pi)cr.restore()cr.stroke()def main():app = Example()Gtk.main()if __name__ == "__main__":main()

我們將執(zhí)行旋轉(zhuǎn)和放縮操作。我們也將保存和恢復(fù) PyCairo 上下文。

cr.translate(w / 2, h / 2)cr.arc(0, 0, 120, 0, 2 * math.pi)cr.stroke()

在 GTK 窗口中間,我們創(chuàng)建一個圓形。這將是我們的橢圓形的邊界圓形。

for i in range(36):cr.save()cr.rotate(i * math.pi / 36)cr.scale(0.3, 1)cr.arc(0, 0, 120, 0, 2 * math.pi)cr.restore()cr.stroke()

我們沿著我們的邊界圓形路徑創(chuàng)建 36 個橢圓形。我們通過save() 和 restore() 方法,將各個旋轉(zhuǎn)和放縮操作隔離開。

星形

下一個例子展示一個旋轉(zhuǎn)和放縮的星形。

#!/usr/bin/python''' ZetCode PyCairo tutorialThis is a star example which demonstrates scaling, translating and rotating operations in PyCairo.author: Jan Bodnar website: zetcode.com last edited: August 2012 '''import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GLib import cairoclass cv(object):points = ((0, 85),(75, 75),(100, 10),(125, 75),(200, 85),(150, 125),(160, 190),(100, 150),(40, 190),(50, 125),(0, 85))SPEED = 20TIMER_ID = 1class Example(Gtk.Window):def __init__(self):super(Example, self).__init__()self.init_ui()self.init_vars()def init_ui(self):self.darea = Gtk.DrawingArea()self.darea.connect("draw", self.on_draw)self.add(self.darea)self.set_title("Star")self.resize(400, 300)self.set_position(Gtk.WindowPosition.CENTER)self.connect("delete-event", Gtk.main_quit)self.show_all()def init_vars(self):self.angle = 0self.scale = 1self.delta = 0.01GLib.timeout_add(cv.SPEED, self.on_timer)def on_timer(self):if self.scale < 0.01:self.delta = -self.deltaelif self.scale > 0.99:self.delta = -self.deltaself.scale += self.deltaself.angle += 0.01self.darea.queue_draw()return Truedef on_draw(self, wid, cr):w, h = self.get_size()cr.set_source_rgb(0, 0.44, 0.7)cr.set_line_width(1)cr.translate(w / 2, h / 2)cr.rotate(self.angle)cr.scale(self.scale, self.scale)for i in range(10):cr.line_to(cv.points[i][0], cv.points[i][1])cr.fill()def main():app = Example()Gtk.main()if __name__ == "__main__":main()

在這個例子中,我們創(chuàng)建一個星形對象。我們將平移它,旋轉(zhuǎn)它并放縮它。

class cv(object):points = ((0, 85),(75, 75),(100, 10),(125, 75),(200, 85), . . .

星形對象將從這些點創(chuàng)建。

def init_vars(self):self.angle = 0self.scale = 1self.delta = 0.01. . .

在 init_vars() 方法中,我們初始化三個變量。self.angle 被用于旋轉(zhuǎn),self.scale 被用于放縮星形對象。self.delta 變量控制何時星形不斷放大而何時又不斷縮小。

GLib.timeout_add(cv.SPEED, self.on_timer)

每隔 cv.SPEED ms,on_timer() 方法會被調(diào)用。

if self.scale < 0.01:self.delta = -self.deltaelif self.scale > 0.99:self.delta = -self.delta

這幾行控制星形是逐漸變大還是變小。

cr.translate(w / 2, h / 2)cr.rotate(self.angle)cr.scale(self.scale, self.scale)

我們將星形移動到窗口的中心。旋轉(zhuǎn)并放縮它。

for i in range(10):cr.line_to(cv.points[i][0], cv.points[i][1])cr.fill()

我們在這里繪制星形對象。

在 PyCairo 教程的這個部分,我們討論了變換。

原文

Done.

總結(jié)

以上是生活随笔為你收集整理的PyCairo 中的变换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。