From d814811e9a68afb1554c5944d3e44b1a4bdb8591 Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Tue, 3 Jun 2025 14:54:13 -0700 Subject: [PATCH 1/3] feat: Fractal generation --- Manifest.toml | 7 +++++- Project.toml | 2 ++ src/fractal.jl | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/image.jl | 8 +++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 src/fractal.jl create mode 100644 src/image.jl diff --git a/Manifest.toml b/Manifest.toml index ae3e78a..cac0bfb 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.11.4" manifest_format = "2.0" -project_hash = "0a18a0873213e0e8660a5eb202a1fa9f1621a652" +project_hash = "6ff2a6774137725477bae8d2113d6856bc327396" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -1093,6 +1093,11 @@ git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" version = "0.3.2" +[[deps.Ranges]] +git-tree-sha1 = "b5dd6c6cba97d1fa0641797cb08d4fd913c5fcd5" +uuid = "eb7db99b-64ae-4b81-85c2-3439b6569b78" +version = "0.1.0" + [[deps.Ratios]] deps = ["Requires"] git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" diff --git a/Project.toml b/Project.toml index 9661941..73bcad6 100644 --- a/Project.toml +++ b/Project.toml @@ -7,10 +7,12 @@ version = "0.1.0" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0" Luxor = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc" +Ranges = "eb7db99b-64ae-4b81-85c2-3439b6569b78" VideoIO = "d6d074c3-1acf-5d4c-9a43-ef38773959a2" [compat] FileIO = "1.17.0" Images = "0.26.2" Luxor = "4.2.0" +Ranges = "0.1.0" VideoIO = "1.1.1" diff --git a/src/fractal.jl b/src/fractal.jl new file mode 100644 index 0000000..a941e3e --- /dev/null +++ b/src/fractal.jl @@ -0,0 +1,60 @@ +using Luxor, Ranges +include("image.jl") + +function sample(m, u, v) + width, height = size(m) + i = trunc(Int, u * width) + j = trunc(Int, v * height) + if i <= 0 || i > width || j <= 0 || j > height + return 0. + else + return greyscale(m[i,j]) + end +end + +function is_stable(m, z1, z2, z) + iter = 1000 + x1 = real(z1) + y1 = imag(z1) + x2 = real(z2) + y2 = imag(z2) + c = z + for _ in 1:iter + if abs(z) > 2 + return false + end + # Sample the image at position z + u = (real(z) - x1) / (x2 - x1) + v = (imag(z) - y1) / (y2 - y1) + f = sample(m, u, v) + if f == 0 + z = z^2 + else + z = z^2 + c + end + end + true +end + +function mandel(m, z1::Complex, z2::Complex) + width, height = size(m) + buffer = zeros(ARGB32, width, height) + for (i, x) in enumerate(range(real(z1), real(z2), width)) + for (j, y) in enumerate(range(imag(z1), imag(z2), height)) + t = greyscale(m[i,j]) + s = is_stable(m, z1, z2, x + y * im) + if t > 0.5 + if s + buffer[i,j] = colorant"white" + else + buffer[i,j] = colorant"blue" + end + else + if s + buffer[i,j] = colorant"red" + end + end + end + end + return buffer +end diff --git a/src/image.jl b/src/image.jl new file mode 100644 index 0000000..3eaf2f9 --- /dev/null +++ b/src/image.jl @@ -0,0 +1,8 @@ +using Images + +""" +Converts image to grayscale +""" +function greyscale(c::Images.RGB)::Real + return Real(c.r) +end -- 2.44.1 From 76e2c11911f73175440171e9055e01e4ede34936 Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Tue, 3 Jun 2025 15:08:18 -0700 Subject: [PATCH 2/3] feat: Stabilize fractal shape --- README.md | 19 +++++++++++++++++++ src/fractal.jl | 13 +++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f19f8ab..65efb96 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,22 @@ # Boundary Bad Apple!! Boundary-aware Bad Apple!! animation generation + +## Fractal + +Usage: + +Load an image with `Images` + +```julia +using Images, FileIO +img = load("examples/frame.png") +``` +Then generate the fractal using the pseudomandelbrot function + +```julia +include("src/fractal.jl") +mandel(img, -3-2im, 2+2im) +``` +The coördinates specified are the bottom left and top right, respectively. + diff --git a/src/fractal.jl b/src/fractal.jl index a941e3e..a6d19a5 100644 --- a/src/fractal.jl +++ b/src/fractal.jl @@ -12,23 +12,24 @@ function sample(m, u, v) end end -function is_stable(m, z1, z2, z) +function is_stable(m, z1, z2, c) iter = 1000 x1 = real(z1) y1 = imag(z1) x2 = real(z2) y2 = imag(z2) - c = z + z = c for _ in 1:iter - if abs(z) > 2 + r = abs(z) + if r > 4 return false end # Sample the image at position z u = (real(z) - x1) / (x2 - x1) v = (imag(z) - y1) / (y2 - y1) f = sample(m, u, v) - if f == 0 - z = z^2 + if f < 0.5 + z = z^2/8 + c else z = z^2 + c end @@ -42,7 +43,7 @@ function mandel(m, z1::Complex, z2::Complex) for (i, x) in enumerate(range(real(z1), real(z2), width)) for (j, y) in enumerate(range(imag(z1), imag(z2), height)) t = greyscale(m[i,j]) - s = is_stable(m, z1, z2, x + y * im) + s = !is_stable(m, z1, z2, x + y * im) if t > 0.5 if s buffer[i,j] = colorant"white" -- 2.44.1 From 2783589cc0d6c69405e7f9aaf500b020066c8cc2 Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Tue, 3 Jun 2025 15:24:36 -0700 Subject: [PATCH 3/3] feat: Use perturbed Mandelbrot iterant --- README.md | 2 +- src/fractal.jl | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 65efb96..5dfe3b9 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Then generate the fractal using the pseudomandelbrot function ```julia include("src/fractal.jl") -mandel(img, -3-2im, 2+2im) +mandel(img, -0.53+0.60im, -0.51+0.62im) ``` The coördinates specified are the bottom left and top right, respectively. diff --git a/src/fractal.jl b/src/fractal.jl index a6d19a5..9165781 100644 --- a/src/fractal.jl +++ b/src/fractal.jl @@ -18,6 +18,9 @@ function is_stable(m, z1, z2, c) y1 = imag(z1) x2 = real(z2) y2 = imag(z2) + u = (real(c) - x1) / (x2 - x1) + v = (imag(c) - y1) / (y2 - y1) + f = sample(m, u, v) z = c for _ in 1:iter r = abs(z) @@ -29,7 +32,7 @@ function is_stable(m, z1, z2, c) v = (imag(z) - y1) / (y2 - y1) f = sample(m, u, v) if f < 0.5 - z = z^2/8 + c + z = z^2*0.99 + c else z = z^2 + c end -- 2.44.1