Python递归画树 - 画蕨类植物 - 画窗格 - 搭建分形平台

@


画树

import numpy as np
import cv2
import math


def draw_tree(img, origin, length, angle, scale, left_angle, left_scale, right_angle, right_scale):
    if length < 4:
        return  # 当length小于2的时候,停止画线(也可以用下面两行代码,表示当length小于2的时候,再画一次停止)

        # end = to_int(get_point(origin, length * scale, angle))
        # cv2.line(img, origin, end, (0, 255, 0))

    else:
        end = to_int(get_point(origin, length*scale, angle))
        cv2.line(img, origin, end, (0, 255, 0))
        # cv2.imshow('MyTree', img)
        # cv2.waitKey(100)

        draw_tree(img, end, length*left_scale, angle+left_angle, scale, left_angle, left_scale, right_angle, right_scale)
        draw_tree(img, end, length*right_scale, angle+right_angle, scale, left_angle, left_scale, right_angle, right_scale)


def get_point(origin, length, angle):
    x, y = origin
    angle *= math.pi / 180
    x += length * math.cos(angle)
    y += length * math.sin(angle)
    return x, y


def to_int(p):
    return int(p[0] + 0.5), int(p[1] + 0.5)


if __name__ == '__main__':
    height = 300
    width = 400
    img = np.zeros([height, width, 3])  # H,W,C
    draw_tree(img, (width//2, height), height, -90, 0.4, -40, 0.5, 30, 0.6)  # BRG
    cv2.imshow('MyTree', img)
    cv2.waitKey()

效果图如下:


画蕨类植物

import numpy as np
import cv2
import math


def draw_tree(img, origin, length, angle, scale, left_angle, left_scale, right_angle, right_scale):
    if length < 4:
        return  # 当length小于2的时候,停止画线(也可以用下面两行代码,表示当length小于2的时候,再画一次停止)

        # end = to_int(get_point(origin, length * scale, angle))
        # cv2.line(img, origin, end, (0, 255, 0))

    else:
        end = to_int(get_point(origin, length*scale, angle))
        cv2.line(img, origin, end, (0, 255, 0))
        # cv2.imshow('MyTree', img)
        # cv2.waitKey(100)

        draw_tree(img, end, length*left_scale, angle+left_angle, scale, left_angle, left_scale, right_angle, right_scale)
        draw_tree(img, end, (1-scale) * length, angle - 10, scale, left_angle, left_scale, right_angle, right_scale)
        draw_tree(img, end, length*right_scale, angle+right_angle, scale, left_angle, left_scale, right_angle, right_scale)


def get_point(origin, length, angle):
    x, y = origin
    angle *= math.pi / 180
    x += length * math.cos(angle)
    y += length * math.sin(angle)
    return x, y


def to_int(p):
    return int(p[0] + 0.5), int(p[1] + 0.5)


if __name__ == '__main__':
    height = 300
    width = 400
    img = np.zeros([height, width, 3])  # H,W,C
    draw_tree(img, (width//2, height), height, -90, 0.2, -40, 0.3, 30, 0.3)  # BRG
    cv2.imshow('MyTree', img)
    cv2.waitKey()

效果图如下:


画窗格

import numpy as np
import cv2
import math


def draw_window(img, origin, length, angle):
    if length < 20:
        end = to_int(get_point(origin, length, angle))
        cv2.line(img, to_int(origin), end, (0, 255, 0))
        # cv2.imshow('img', img)
        # cv2.waitKey(1000)

    else:
        length /= 3
        draw_window(img, origin, length, angle)
        end = to_int(get_point(origin, length, angle))

        draw_window(img, end, length, angle - 60)
        end = to_int(get_point(end, length, angle-60))

        draw_window(img, end, length, angle + 60)
        end = to_int(get_point(end, length, angle+60))

        draw_window(img, end, length, angle)


def get_point(origin, length, angle):
    x, y = origin
    angle *= math.pi / 180
    x += length * math.cos(angle)
    y += length * math.sin(angle)
    return x, y


def to_int(p):
    return int(p[0] + 0.5), int(p[1] + 0.5)


if __name__ == '__main__':
    height = 300
    width = 400
    img = np.zeros([height, width, 3])
    draw_window(img, (0, height // 2), width, 0)
    cv2.imshow('img', img)
    cv2.waitKey()

效果图如下:


分形平台

import cv2
import numpy as np
import math


class Env:
    def __init__(self, origin, alpha, length, color, limit=4):
        self.origin = origin
        self.alpha = alpha
        self.length = length
        self.color = color
        self.limit = limit

    def copy(self):
        env2 = Env(self.origin, self.alpha, self.length, self.color, self.limit)
        return env2


class Graphics:
    # def __init__(self):
    #     self.fraction = None

    def draw(self, env):
        raise Exception('The draw() method is not override!')


class Fraction(Graphics):
    def __init__(self):
        self.gs = []

    def add(self, g: Graphics):
        g.fraction = self
        self.gs.append(g)

    def draw(self, env):
        for g in self.gs:
            g.draw(env)


class LR(Graphics):
    def __init__(self, len_scale, alpha_adjust, move):
        self.len_scale = len_scale
        self.alpha_adjust = alpha_adjust
        self.move = move


class Line(LR):
    def __init__(self, len_scale, alpha_adjust, move=True):
        super(Line, self).__init__(len_scale, alpha_adjust, move)

    def draw(self, env):
        end = to_int(get_end(env.origin, self.len_scale * env.length, env.alpha + self.alpha_adjust))
        cv2.line(img, env.origin, end, env.color)

        if self.move:
            env.origin = end


def get_end(origin, length, alpha):
    x, y = origin[0], origin[1]
    alpha = alpha * math.pi / 180
    x += length * math.cos(alpha)
    y += length * math.sin(alpha)
    return x, y

def to_int(coord):
    return int(coord[0] + 0.5), int(coord[1] + 0.5)


class Recur(LR):
    def __init__(self, len_scale, alpha_adjust, move=False):
        super(Recur, self).__init__(len_scale, alpha_adjust, move)

    def draw(self, env):
        length = self.len_scale * env.length
        alpha = self.alpha_adjust + env.alpha
        end = to_int(get_end(env.origin, length, alpha))

        if length <= env.limit:
            cv2.line(img, env.origin, end, env.color)
        else:
            env2 = env.copy()
            env2.length = length
            env2.alpha = alpha
            self.fraction.draw(env2)

        if self.move:
            env.origin = end


if __name__ == '__main__':
    f = Fraction()
    f.add(Line(0.4, 0, True))
    f.add(Recur(0.5, -20, False))
    f.add(Recur(0.6, 40, False))
    h, w = 600, 900
    img = np.zeros((h, w, 3))
    env = Env((w//6, h), -90, h, (0, 0, 255))
    f.draw(env)

    f = Fraction()
    f.add(Recur(0.333, 0, True))
    f.add(Recur(0.333, -60, True))
    f.add(Recur(0.333, 60, True))
    f.add(Recur(0.333, 0))
    env = Env((w//3, h * 3//4), 0, w//3, (255, 0, 0), limit=20)
    f.draw(env)

    f = Fraction()
    f.add(Line(0.2, 0, True))
    f.add(Recur(0.3, -30, False))
    f.add(Recur(0.8, -10, False))
    f.add(Recur(0.3, 35, False))
    env = Env((w * 5//6, h), -90, h, (0, 255, 0))
    f.draw(env)

    cv2.imshow('MyImage', img)
    cv2.waitKey()

效果图如下:

posted @ 2023-03-14 21:17  Just-1080Ti  阅读(1252)  评论(0)    收藏  举报