Sentaro様から「面白いモノはナーイ ?」との事で、fx-CG50 upython をしばき倒す(?) 「Pickovers' Biomorph」のコードを動かしてみました。
当方が、Pickovers' Biomorph を知った、そのネタ元と言いますと、昔、図書館で読んだ、日経サイエンス誌の連載「コンピューター・リクリエーション」(A. K. Dewdney) なのですが、Pickover biomorphs で検索すると、およその所が解ると思います。
Mandelbrot set graphics の作業の様ですが、少し異なる部分もあります。
詳細はコードをご参照ください。
Pickovers' Biomorphs の場合、繰り返す計算式を色々と変更する事で、描かれる画像が多様に変化します。
このコードでは、
z = z*z+cを繰り返しますが、これを、例えばつぎの行にある様に、
z = cmath.sin(z*z)-cとかに変更すると、画像が大きく変化するのです。
複素数平面の座標値に数式を繰り返し適用するため、複素数を扱う関数が必要になりますが、残念ながら、fx-CG50 には cmath module が用意されておりません。
そこで、急ごしらえで cmath module を用意しました。 残念ながら、asin() などはまだ、用意できておりませんが、チョット遊ぶなら、この辺りから始めても十分であると思います。
実行は、プログラムを読み込んだ後、
biom()
と入力する事で実行されます。
ループ中の数式を変更する事でも、画像が大きく変化するのですが、定数 c を変える事でも、微妙に画像が変化します。
定数 c も複素数ですが、biom(c.real, c.imag) の様に、実部と虚部をカンマで分けて指定する事で与えられます。
残念ながら、cmath module が system binary ではなく、実行速度が大変遅いという哀しい部分はありますが、
じわじわとグラフィクスが描かれる様を眺めるのも、手のひらで動く電卓ならではの愉しみであると思います。
追記 on 2024-10-05
過日、K 様にコメント戴き、sqrt() を更新いたしました。
math.copysign() が fx-CG50 には無いため、自家製の copysign() もどき csign() を付け足しましたヨ。これにより、計算速度が向上したという具合には行きませんが、ネタとしては色々と面白かったので、後日、別記したく思います。
謝謝 !
リスト biom.py
# title : biom.py - Pickovers' Biomorph for fx-CG50 # begin : 2024-09-28 19:33:39 from casioplot import * import math import cmath def biom(re=0, im=0) : width = 383 height = 191 xs=-3.8 xe= 3.8 ys=-1.9 ye= 1.9 c = re - im*1j # Biomorph for j in range(height): for i in range(width): z = (i*(xe-xs)/width +xs) + 1j*(j*(ys-ye)/height+ye) # repeating core k = 0 while abs(z) <= 10 and k < 10: z = z*z+c #z = cmath.sin(z*z)-c k=k+1 # if abs(z.real) < 10 or abs(z.imag) < 10 : set_pixel(int(i), int(j)) # show graphix progressively show_screen()
リスト cmath.py
## title : [WIP] cmath module for fx-CG50
## begin : 2024-09-28 00:38
import math
# copysign() like something ...
def csign(x, y) :
if y == 0.0 :
if str(y) == '-0.0' :
return -abs(x)
else :
return abs(x)
else :
if y < 0 :
return -abs(x)
else :
return abs(x)
#
def phase(x) :
return math.atan2(x.imag, x.real)
##
def exp(x) :
return pow(math.e, x)
##
def ln(x) :
return math.log(abs(x)) + phase(x)*1j
##
def log(x, base=math.e) :
return ln(x) / ln(base)
## thanks K sama ! on 2024-10-04
def sqrt(x) :
# return pow(x, 0.5)
return math.sqrt((abs(z)+z.real)/2) + 1j* csign(math.sqrt((abs(z)-z.real)/2), z.imag)
##
def sin(c) :
return math.sin(c.real)*math.cosh(c.imag) + (math.cos(c.real)*math.sinh(c.imag))*1j
##
def cos(c) :
return math.cos(c.real)*math.cosh(c.imag) - (math.sin(c.real)*math.sinh(c.imag))*1j
##
def tan(c) :
return sin(c) / cos(c)