こうかの雑記

こうかの雑記

昔の懐かしいこと、ubuntuのこと、その他いろいろ

pythonとtkinterでグラフィック・アートその2

 前に投稿した「pythonとtkinterでグラフィック・アート」と同じ「パソコン・グラフィックス・アート」(著者:工学博士 竹村伸一 発行元:株式会社オーム社)という本の中の一つです。
 残念ながら陰線処理は出来ていませんが、3D画像が面白いので載せてみました。

 何年か前の話ですが、この本のプログラムをぼちぼちと書き換えることで、ようやくpythonに慣れ始めることが出来ました。実際に書いてみないと覚えられないものですね。そしてpythonのオブジェクト志向の技法を試してみたいということがあって、適切な例ではなかったと思いますがチャレンジしたのがこのスクリプトです。良い練習になったと思います。
 この例ではオブジェクト志向のメリットよりもデメリットの方が目立ってしまい、従来の技法を使ったほうが良かったと思いました。というのは"self."を沢山書かなくてはならない事になり、面倒でした。
 pythonはオブジェクト志向を強要する言語ではないので、何がなんでもオブジェクト志向というよりは、目的に応じて従来技法と使い分けた方が良いと思いました。
 でもお陰で理解は深まりました。

画像

f:id:koukaforest:20191129121353p:plain

 

以下、pythonスクリプトを載せます。

 

#!/usr/bin/env python3
"""
sombrero_c.py クラス版 陰線処理なし
原典 パソコン・グラフィック・アート 著者:竹村伸一 発売元:株式会社オーム社
コンバート: sk
classを使った例
"""
import tkinter as tk
import math

class App(tk.Frame):
    def func(self):
        self.q = math.sqrt(self.x * self.x + self.z * self.z) / 80
        if self.q == 0 :
            self.y = 100 * math.pi
        else:
            self.y = 100 * math.sin(self.q * math.pi) / self.q
    def rotation(self):
        self.x1 = self.x
        self.y1 = self.y  * math.cos(self.xa) - self.z  * math.sin(self.xa)
        self.z1 = self.y  * math.sin(self.xa) + self.z  * math.cos(self.xa)
        self.x2 = self.x1 * math.cos(self.ya) - self.z1 * math.sin(self.ya)
        self.y2 = self.y1
        self.z2 = self.x1 * math.sin(self.ya) + self.z1 * math.cos(self.ya)
        self.x3 = self.x2 * math.cos(self.za) - self.y2 * math.sin(self.za)
        self.y3 = self.x2 * math.sin(self.za) + self.y2 * math.cos(self.za)
        self.z3 = self.z2
    def graphics(self):
        self.gx = 300 + self.x3
        self.gy = 300 - self.y3
        if self.gx < 0 or self.gx > 600 :
            self.g = 0
        else :
            if self.gy < 0 or self.gy > 600 :
                self.g = 0
            else :
                if self.g == 0 :
                    self.l2  = self.c0.create_line(self.gx,self.gy,
                        self.gx,self.gy,fill='SteelBlue')
                    self.gx2 = self.gx
                    self.gy2 = self.gy
                    self.g   = 1
                else :
                    self.l2  = self.c0.create_line(self.gx2,self.gy2,
                        self.gx,self.gy,fill='SteelBlue')
                    self.gx2 = self.gx
                    self.gy2 = self.gy
                    self.g=1
    def cmd(self):
        self.xa = 0.8
        self.ya = 0.2
        self.za = 0
        self.g  = 0
        for self.z in range(240,-240,-10):
            for self.x in range(-240, 240, 10):
                self.func()
                self.rotation()
                self.graphics()
            self.g = 0
        print('end')
    def __init__(self, master=None):
        tk.Frame.__init__(self,master)
        f = tk.Frame(master)
        f.pack()
        self.c0 = tk.Canvas(f, width=600, height=600, bg='black')
        #self.l0 = self.c0.create_line(0,300,600,300, fill='white')
        #self.l1 = self.c0.create_line(300,0,300,600,fill='white')
        self.c0.pack()
        b = tk.Button(f,text="描画",command=self.cmd)
        b.pack()
		
if __name__ == '__main__':
    a = App()
    a.mainloop()