仮想計算機構

IT業界と無縁な派遣社員のブログ

【Python】ニュートンフラクタルの可視化


wikiの疑似コードを参考に実装します。

プログラム

import numpy as np
import cv2

Px,Py = 360,420
img = np.zeros((Px, Py,3), np.uint8)
roots = [1+0j,-0.5+np.sqrt(3)/2j, -0.5-np.sqrt(3)/2j]
r_hsv = cv2.cvtColor(np.uint8([[[255,0,0]]]),cv2.COLOR_RGB2HSV)[0][0]
g_hsv = cv2.cvtColor(np.uint8([[[0,255,0]]]),cv2.COLOR_RGB2HSV)[0][0]
b_hsv = cv2.cvtColor(np.uint8([[[0,0,255]]]),cv2.COLOR_RGB2HSV)[0][0]
colors = [r_hsv,g_hsv,b_hsv]
xmin,xmax = -2.5,1
ymin,ymax = -1,1
N = 100
tolerance = 0.001

def f(z):
    return z**3-1

def derivative_f(z):
    return 3*z**2

def get_color(x,y):
    zx = (xmax-xmin)*x/Px+xmin
    zy = (ymax-ymin)*y/Py+ymin
    z = zx+zy*1j

    for i in range(N):
        z -= f(z)/derivative_f(z)
        for j,root in enumerate(roots):
            diff = z - root
            if abs(diff.real)<tolerance and abs(diff.imag)<tolerance:
                h,s,v = colors[j]
                
                # Coloring 1
                '''
                r,g,b = cv2.cvtColor(np.uint8([[[h,s,v]]]),cv2.COLOR_HSV2RGB)[0][0]
                '''

                # Coloring 2
                '''
                M = 20
                v = v*(M-np.min([i,M-1]))/M
                r,g,b = cv2.cvtColor(np.uint8([[[h,s,v]]]),cv2.COLOR_HSV2RGB)[0][0]
                '''
                # Coloring 3
                h = (10*i)%180
                r,g,b = cv2.cvtColor(np.uint8([[[h,255,255]]]),cv2.COLOR_HSV2RGB)[0][0]
                
                return [r,g,b]
    return [0,0,0]

for x in range(Px):
    print(x)
    for y in range(Py):
        img[x][y] = get_color(x,y)

cv2.imwrite('test.png', img)

実行結果

色付けパターン1

f:id:riverta1992:20210624200926p:plain

色付けパターン2

解に到達するまでの反復回数に応じて色の明るさを決めます。
f:id:riverta1992:20210624201052p:plain

色付けパターン3

HSV色空間を使い、解に到達するまでの反復回数に応じて色相を変えます。OpenCVにおけるHSVは最大(180,255,255)であることに注意します。

f:id:riverta1992:20210624201210p:plain