Skip to content

Instantly share code, notes, and snippets.

@maxim-saplin
Last active May 19, 2024 09:20
Show Gist options
  • Save maxim-saplin/8dad6ec5b4a38ccfea5527b7c6d2020d to your computer and use it in GitHub Desktop.
Save maxim-saplin/8dad6ec5b4a38ccfea5527b7c6d2020d to your computer and use it in GitHub Desktop.
Simple integration of Dart/Flutter and Python
# https://matplotlib.org/matplotblog/posts/animated-fractals/
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time
x_start, y_start = -2, -2 # an interesting region starts here
width, height = 4, 4 # for 4 units up and right
density_per_unit = 80 # how many pixles per unit
# real and imaginary axis
re = np.linspace(x_start, x_start + width, width * density_per_unit )
im = np.linspace(y_start, y_start + height, height * density_per_unit)
threshold = 10 # max allowed iterations
frames = 100000 # number of frames in the animation
# we represent c as c = r*cos(a) + i*r*sin(a) = r*e^{i*a}
r = 0.7885
a = np.linspace(0, 2*np.pi, round(frames/1000))
fig = plt.figure(figsize=(5, 5)) # instantiate a figure to draw
ax = plt.axes() # create an axes object
def julia_quadratic(zx, zy, cx, cy, threshold):
"""Calculates whether the number z[0] = zx + i*zy with a constant c = x + i*y
belongs to the Julia set. In order to belong, the sequence
z[i + 1] = z[i]**2 + c, must not diverge after 'threshold' number of steps.
The sequence diverges if the absolute value of z[i+1] is greater than 4.
:param float zx: the x component of z[0]
:param float zy: the y component of z[0]
:param float cx: the x component of the constant c
:param float cy: the y component of the constant c
:param int threshold: the number of iterations to considered it converged
"""
# initial conditions
z = complex(zx, zy)
c = complex(cx, cy)
for i in range(threshold):
z = z**2 + c
if abs(z) > 4.: # it diverged
return i
return threshold - 1 # it didn't diverge
def animate(iter):
start_time = time.time() # start timing
ax.clear() # clear axes object
ax.set_xticks([], []) # clear x-axis ticks
ax.set_yticks([], []) # clear y-axis ticks
iter = iter % 100
X = np.empty((len(re), len(im))) # the initial array-like image
cx, cy = r * np.cos(a[iter]), r * np.sin(a[iter]) # the initial c number
with open("io.txt", "w") as file:
file.write(str(iter))
# iterations for the given threshold
for i in range(len(re)):
for j in range(len(im)):
X[i, j] = julia_quadratic(re[i], im[j], cx, cy, threshold)
img = ax.imshow(X.T, interpolation="bicubic", cmap='magma')
elapsed_time = time.time() - start_time
print(f"\r{iter} : {round(elapsed_time * 1000, 2)} ms", end='', flush=True)
return [img]
anim = animation.FuncAnimation(fig, animate, frames=frames, interval=50, blit=True)
plt.show()
import 'dart:async';
import 'dart:io';
void main(List<String> args) async {
var p = await Process.start('python3', ['julia.py']);
_getUpdates(p);
}
void _getUpdates(Process p) {
var stopped = false;
p.exitCode.then((value) => stopped = true);
Timer.periodic(Duration(milliseconds: 500), (timer) {
var file = File('io.txt');
if (!file.existsSync()) {
return;
}
if (stopped) {
print('DONE');
timer.cancel();
return;
}
var lines = file.readAsLinesSync();
if (lines.isNotEmpty) {
stdout.write('\rFrames rendered: ${lines.first} ');
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment