0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

再帰でお絵かきしてみた

Posted at

はじめに

 フラクタルを再帰処理で描画できるという話を聞いて、面白そうだったので、自然界にある再帰で描けそうなものを題材にお絵かきしてみました。

image.png

import pygame
import math
import random

pygame.init()
win = pygame.display.set_mode((750, 650))
win.fill((255, 255, 255))

def drawTree(a, b, pos, deepness):
    if deepness:
        branch1 = random.randint(1,15)
        branch2 = random.randint(1,15)
        c = a + int(math.cos(math.radians(pos)) * deepness * branch1)
        d = b + int(math.sin(math.radians(pos)) * deepness * branch2)
        pygame.draw.line(win, (128,64,0), (a, b), (c, d), int(1.3**deepness))
        drawTree(c, d, pos - 20, deepness - 1)
        drawTree(c, d, pos + 20, deepness - 1)
    else:
        pygame.draw.circle(win,(0,192,0),(a,b),random.randint(1, 4),0)

drawTree(370, 650, -90, 10)
pygame.display.flip()
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

この記事のコードを拝借して、色とか枝の太さとかを調整しました

雪の結晶

image.png

import pygame
import math

pygame.init()
win = pygame.display.set_mode((750, 650))
win.fill((255, 255, 255))

def drawKochLine(start, end, depth):
    if depth == 0:
        pygame.draw.line(win, (0, 0, 255), start, end, 2)
        return

    x1, y1 = start
    x5, y5 = end
    x2 = x1 + (x5 - x1) / 3
    y2 = y1 + (y5 - y1) / 3
    x4 = x1 + (x5 - x1) * 2 / 3
    y4 = y1 + (y5 - y1) * 2 / 3

    angle = math.radians(60)
    x3 = (x2 + x4) / 2 - (y4 - y2) * math.tan(angle)
    y3 = (y2 + y4) / 2 + (x4 - x2) * math.tan(angle)

    drawKochLine((x1, y1), (x2, y2), depth - 1)
    drawKochLine((x2, y2), (x3, y3), depth - 1)
    drawKochLine((x3, y3), (x4, y4), depth - 1)
    drawKochLine((x4, y4), (x5, y5), depth - 1)

def drawHexagon(center, size, depth):
    x, y = center
    points = []
    for i in range(6):
        angle = math.radians(60 * i)
        px = x + size * math.cos(angle)
        py = y + size * math.sin(angle)
        points.append((px, py))

    for i in range(6):
        drawKochLine(points[i], points[(i+1) % 6], depth)

drawHexagon((375, 325), 150, 4)
pygame.display.flip()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

コッホ曲線をベースに、六角形を取り入れてくれという曖昧な指示で、AIが割と上手に書いてくれました

アンモナイト

image.png

import pygame
import math

pygame.init()
win = pygame.display.set_mode((750, 650))
win.fill((248, 240, 216))

# フィボナッチ数列の生成
def fibonacci(n = None):
    a, b = 1, 1
    if n is None:
        while True:
            yield a
            a, b = b, a + b
    for _ in range(n):
        yield a
        a, b = b, a + b

def drawFibonacciSpiral(start, num_steps):
    prev_x, prev_y = start
    fib_sequence = fibonacci()

    directions = [(-1, 1), (1, 1), (1, -1), (-1, -1)]  # 左下→右下→右上→左上
    angles = [(math.radians(90), math.radians(180)), 
              (math.radians(180), math.radians(270)), 
              (math.radians(270), math.radians(0)), 
              (math.radians(0), math.radians(90))]  # 始点と終点の角度
    center_directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]  #始点から見た中心の方向

    for i in range(num_steps):
        step = i % 4
        fib = next(fib_sequence)
        dx, dy = directions[step]
        x_next = prev_x + fib * dx
        y_next = prev_y + fib * dy

        # 円弧の中心位置を調整
        center_x = prev_x + fib * center_directions[step][0]
        center_y = prev_y + fib * center_directions[step][1]
        radius = fib

        # 扇形を描画(開始角度と終了角度の調整)
        s_angle, e_angle = angles[step]
        rect = (center_x - radius, center_y - radius, radius * 2, radius * 2)

        # 始点と終点を曲線で結ぶ
        pygame.draw.arc(win, (150, 75, 0), rect, s_angle, e_angle, 1)

        prev_x, prev_y = x_next, y_next

drawFibonacciSpiral((375, 325), 13)
pygame.display.flip()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

 アンモナイトというか、アンモナイトの貝殻の螺旋なんですが、フィボナッチ数列で表せるので書いてみました。弧線を書く時の長さを90度分じゃなくて一周にすると変なバラみたいなのが書けます

image.png

最後に

 ここまで読んで下さりありがとうございました。単純に面白そうって理由だけでやってみましたが、再帰の練習とか、頭の体操にはちょうどいい題材だと思いました。特に木とか、自分で書くよりも、よっぽどうまく書けますね。逆に言えば、自分で書くときも再帰処理を意識して書けばいいってことでしょうか。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?