"BOKU"のITな日常

BOKUが勉強したり、考えたことを頭の整理を兼ねてまとめてます。

Pythonでグラフィックス:再帰図形2つ「C曲線」と「樹形図」を描くクラス

f:id:arakan_no_boku:20210912183619p:plain

目次

C曲線

今回は、2種類の再帰図形「C曲線」と「樹木曲線」をPythonで実装します。

C曲線とは、このような図形です。

f:id:arakan_no_boku:20210918192118p:plain

なんとなく可愛くて、自分はこの図形が結構好きです。

これを描くクラスのソースコードはこちらです。

グラフの機能を利用して病害しているので、matplotlibが必要です。

タイトルを日本語で表示するために日本語フォントに変更しています。

arakan-pgm-ai.hatenablog.com

class_graphics.py

from matplotlib import pyplot as plt


class Ccurve():
    def __init__(self):
        self.__tx = [1.0]
        self.__ty = [2.0]
        self.__title = "C曲線を描く"

    def __move(self, lpx, lpy, dx, dy):
        self.__tx.append(lpx + dx)
        self.__ty.append(lpy + dy)

    def __draw(self, st_len=10.0, lpx=0.0, lpy=0.0, dx=2.0, dy=0.0):
        leng = st_len
        if(leng <= 0.0):
            self.__move(lpx, lpy, dx, dy)
        else:
            self.__draw(leng - 1.0,
                        self.__tx[-1],
                        self.__ty[-1],
                        (dx + dy) / 2,
                        (dy - dx) / 2)
            self.__draw(leng - 1.0,
                        self.__tx[-1],
                        self.__ty[-1],
                        (dx - dy) / 2,
                        (dy + dx) / 2)
        return self.__tx, self.__ty

    def draw(self):
        x, y = self.__draw()
        plt.plot(x, y)
        plt.title(self.__title)
        plt.show()

再帰図形です。

__draw()のパラメータを少しずつ小さくしながら、再帰的に呼び出しています。

使うときは。

from class_graphics import Ccurve

Ccurve().draw()

とすると、上記のグラフを表示します。

樹形図(樹木曲線)

ブロッコリーみたいだと自分は思ってますが・・樹形図です。

描いた図形はこんな感じです。

f:id:arakan_no_boku:20210918195209p:plain

これを描くクラスのソースコードです。

Numpyが必要なので、importを追加しています。

同じファイルにクラスを追記しています。

class_graphics.py

import matplotlib.pyplot as plt
import numpy as np

class TreeCurve():
    def __init__(self):
        self.__tx = [320.0]
        self.__ty = [380.0]
        self.__title = "樹形図(樹木曲線)を描く"

    def __move(self, leng, lpx, lpy, angle):
        x = lpx + leng * np.cos(angle * np.pi / 180.0)
        y = lpy + leng * np.sin(angle * np.pi / 180.0)
        self.__tx.append(x)
        self.__ty.append(y)
        return x, y

    def __draw(self, leng=120.0, lpx=320.0, lpy=380.0, angle=90.0, scale=0.7):
        if(leng >= 5.0):
            self.__tx.append(lpx)
            self.__ty.append(lpy)
            lpx, lpy = self.__move(leng, lpx, lpy, angle)
            self.__draw(leng * scale, lpx, lpy, angle + 20.0)
            self.__draw(leng * scale, lpx, lpy, angle - 20.0)
        return self.__tx, self.__ty

    def draw(self):
        x, y = self.__draw()
        plt.plot(x, y)
        plt.title(self.__title)
        plt.show()

これも再帰図形です。

__draw_tree()を小さくしつつ、20度ずつ角度を変えて再帰呼出しします。 

ポイントは、__drawe()の中で、一度原点に戻ってから、ラインを引く位置に移動(__move())していることで、この動きによって、樹形図っぽい図形になります。

使うときは。

from class_graphics import TreeCurve

TreeCurve().draw()

です。

ちなみに。

move()の中の以下の部分

y = lpy + leng * np.sin(angle * np.pi / 180.0)

これを、以下のように「-」に変更すると

y = lpy - leng * np.sin(angle * np.pi / 180.0)

上下逆転した図形になります。

f:id:arakan_no_boku:20181207000134j:plain

グラフィックスの他の記事

リンクをまとめておきます。

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

ではでは。