「Krita」と「Python」でオリジナルの幾何学模様を作ろう

幾何学模様をアニメーションさせよう
サンプルスクリプト「dlg_bezier4.py」に追加して、次のスクリプトを第11回のアニメーション作成とほとんど同じように追記します。ベジェ曲線を自由に変形して"幾何学模様の作成"ボタンを押せば、徐々にベジェ曲線が直線から曲線に変形しながら幾何学模様のアニメーションが作成されます(図6)。アニメーションは描画した図形をPNGファイルに保存して、それをアニメーションタイムラインに配置します。
アニメーションを見るには全ての画像が完成するまで待ちます。それからPythonスクリプトを実行したダイアログを閉じて「ウィンドウ」→「ワークスペース」→「Animation」ワークスペースにして、アニメーションタイムラインの「▶(再生)」ボタンを押します。
アニメーションの仕組みは、徐々に増える0.0~1.0の数値をベジェ曲線の2つのコントロールポイントのXY座標にそれぞれ乗算することで「放射状の幾何学模様」~「作ったベジェ曲線の幾何学模様」に徐々に変形しながら近づけていきます。
・サンプルスクリプト「dlg_bezier5.py」# モジュール import tempfile import shutil from PyQt5.Qt import * from PyQt5.QtWidgets import QDialog, QHBoxLayout, QSpinBox, QLabel, QPushButton from krita import * # 全フレーム数 MAX_FRAME = 120 # ダイアログクラス class Dialog(QDialog): (中略) # アニメーションフレーム def insertFrames(self, nbFrames): tmpPath = tempfile.mkdtemp() files = [] for imgNumber in range(nbFrames): fileName = os.path.join(tmpPath, f"tmp{imgNumber:04}.png") files.append(fileName) image = self.draw_bezier(360,imgNumber) image.save(fileName) self.doc.importAnimation(files, 0, 1) self.doc.setFullClipRangeEndTime(nbFrames - 1) shutil.rmtree(tmpPath) # 幾何学模様の描画 def draw_bezier(self,num,frame): pixmap = QPixmap(self.doc.bounds().size()) pixmap.fill(QColor(255,255,255)) painter = QPainter() pen = QPen(QColor(0,0,0,255)) painter.setPen(pen) painter.begin(pixmap) painter.setRenderHint(QPainter.Antialiasing,True) cx = int(self.doc.width()/2) cy = int(self.doc.height()/2) for i in range(0,num,5): painter.save() painter.translate(cx,cy) painter.rotate(i) self.bezier(painter,frame) painter.restore() painter.end() return pixmap.toImage() # ベジェ曲線の描画 def bezier(self,painter,frame): path = QPainterPath() ctrl_x1 = self.sb_ctrl_x1.value() * frame / MAX_FRAME ctrl_y1 = self.sb_ctrl_y1.value() * frame / MAX_FRAME ctrl_x2 = self.sb_ctrl_x2.value() * frame / MAX_FRAME ctrl_y2 = self.sb_ctrl_y2.value() * frame / MAX_FRAME path.cubicTo(ctrl_x1,ctrl_y1,ctrl_x2,ctrl_y2,200,0) painter.drawPath(path) # ボタンが押されたら幾何学模様の描画 def click_button(self): self.doc.setFramesPerSecond(30) self.insertFrames(MAX_FRAME) # スピンボックスが押されたら1本のベジェ曲線の描画 def click_sb(self): self.img = self.draw_bezier(1,MAX_FRAME) self.set_layer() self.doc.refreshProjection() (後略)
【サンプルスクリプトの解説】
ファイルを扱うモジュールを読み込みます。
「insertFrames」メソッドでアニメーション画像を1ファイルずつ作り、Kritaのアニメーションタイムラインに配置してファイルはフォルダごと削除します。
「draw_bezier」メソッドと「bezier」メソッドで「frame」引数を追加します。
「bezier」メソッドで2つのコントロールポイントのXY座標に0/120~120/120を乗算した数値をベジェ曲線にセットします。
"幾何学模様の作成"ボタンが押されたら「click_button」メソッドが呼ばれ、30FPSでアニメーションの作成を開始します。
スピンボックスが押された場合に「click_sb」メソッドが呼ばれ、「draw_bezier」メソッドの呼び出しでframe引数を追加します。
今回の幾何学模様のアイデアは、20年ぐらい前にNHK-BSでやっていたTV番組「デジタルスタジアム(通称デジスタ)」に採用された作品にインスパイアされました。デジスタは若手アーティストの登竜門的番組で、TV番組で初めてグッドデザイン賞を受賞したほどのコンテスト番組でした。
その作品ではPhotoshopで、針金クリップを滅茶苦茶に曲げたような適当な曲線を描いて複製ツールで回転しながら何百個もコピーした幾何学模様を描いていました。「こんなに簡単に綺麗な幾何学模様になるんだ」と感心したものでした。それを20年ぶりぐらいに思い出し、KritaでPythonをプログラミングしてやってみたというわけです。
おわりに
今回は、ベジェ曲線の2つのコントロールポイントを自由に移動して、そのベジェ曲線を回転させながら描画して幾何学模様を描きました。さらにアニメーションも作れるようにしました。皆さんも気に入った幾何学模様ができたらファイルに保存してみてください。