Skip to content

Commit 886cbc4

Browse files
committed
resolve conflicts
1 parent 4a81890 commit 886cbc4

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

contents/barnsley/barnsley.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ In this chapter, I hope to provide a slightly more satisfying answer by introduc
2424

2525
| Hutchinson Operator | Attractor |
2626
| ------------------- | --------- |
27-
| $$\begin{align} f_1(P) &= \begin{bmatrix} 0 &0 \\ 0 &0.16 \end{bmatrix}P + \begin{bmatrix} 0 \\ 0 \end{bmatrix} \\ f_2(P) &= \begin{bmatrix} 0.85 &0.04 \\ -0.04 &0.85 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix} \\ f_3(P) &= \begin{bmatrix} 0.2 &-0.26 \\ 0.23 &022 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix} \\ f_4(P) &= \begin{bmatrix} -0.15 &0.28 \\ 0.26 &0.24 \end{bmatrix}P + \begin{bmatrix} 0 \\ 0.44 \end{bmatrix} \end{align}$$ | <img class="center" src="res/full_fern.png" alt="Barnsley Chaos Game" style="width:100%"> |
27+
| $$\begin{align} f_1(P) &= \begin{bmatrix} 0 &0 \\ 0 &0.16 \end{bmatrix}P + \begin{bmatrix} 0 \\ 0 \end{bmatrix} \\ f_2(P) &= \begin{bmatrix} 0.85 &0.04 \\ -0.04 &0.85 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix} \\ f_3(P) &= \begin{bmatrix} 0.2 &-0.26 \\ 0.23 &0.22 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix} \\ f_4(P) &= \begin{bmatrix} -0.15 &0.28 \\ 0.26 &0.24 \end{bmatrix}P + \begin{bmatrix} 0 \\ 0.44 \end{bmatrix} \end{align}$$ | <img class="center" src="res/full_fern.png" alt="Barnsley Chaos Game" style="width:100%"> |
2828

2929
At first glance, this set of functions looks like an incomprehensible mess of magic numbers to create a specific result, and in a sense, that is precisely correct.
3030
That said, we will go through each function and explain how it works, while also providing a simple chaos game implementation in code.
@@ -54,7 +54,7 @@ Now let's hop into disecting the Barnsley fern by seeing how each transform affe
5454
| -------- | --------- |
5555
| $$f_1(P) = \begin{bmatrix} 0 &0 \\ 0 &0.16 \end{bmatrix}P + \begin{bmatrix} 0 \\ 0 \end{bmatrix}$$ <p> This operation moves every point to a single line. | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/affine_rnd_0.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
5656
| $$f_2(P) = \begin{bmatrix} 0.85 &0.04 \\ -0.04 &0.85 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix}$$ <p> This operation moves every point up and to the right. | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/affine_rnd_1.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
57-
| $$f_3(P) = \begin{bmatrix} 0.2 &-0.26 \\ 0.23 &022 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix}$$ <p> This operation rotates every point to the left. | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/affine_rnd_2.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
57+
| $$f_3(P) = \begin{bmatrix} 0.2 &-0.26 \\ 0.23 &0.22 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix}$$ <p> This operation rotates every point to the left. | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/affine_rnd_2.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
5858
| $$f_4(P) = \begin{bmatrix} -0.15 &0.28 \\ 0.26 &0.24 \end{bmatrix}P + \begin{bmatrix} 0 \\ 0.44 \end{bmatrix}$$ <p> This operation flips every point and rotates to the right.| <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/affine_rnd_3.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
5959

6060
At this stage, it *might* be clear what is going on, but it's not exactly obvious.
@@ -71,7 +71,7 @@ The easiest way to make sense of this is to show the operations on the Barnsley
7171
| -------- | --------- |
7272
| $$f_1(P) = \begin{bmatrix} 0 &0 \\ 0 &0.16 \end{bmatrix}P + \begin{bmatrix} 0 \\ 0 \end{bmatrix}$$ | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/affine_fern_0.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
7373
| $$f_2(P) = \begin{bmatrix} 0.85 &0.04 \\ -0.04 &0.85 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix}$$ | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/affine_fern_1.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
74-
| $$f_3(P) = \begin{bmatrix} 0.2 &-0.26 \\ 0.23 &022 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix}$$ | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/affine_fern_2.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
74+
| $$f_3(P) = \begin{bmatrix} 0.2 &-0.26 \\ 0.23 &0.22 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix}$$ | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/affine_fern_2.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
7575
| $$f_4(P) = \begin{bmatrix} -0.15 &0.28 \\ 0.26 &0.24 \end{bmatrix}P + \begin{bmatrix} 0 \\ 0.44 \end{bmatrix}$$ | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/affine_fern_3.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
7676

7777
Here, the self-similar nature of the fern becomes apparent.
@@ -86,7 +86,7 @@ To account for this, each function is also given a probability of being chosen:
8686
| -------- | ----------- |
8787
| $$f_1(P) = \begin{bmatrix} 0 &0 \\ 0 &0.16 \end{bmatrix}P + \begin{bmatrix} 0 \\ 0 \end{bmatrix}$$ | 0.01 |
8888
| $$f_2(P) = \begin{bmatrix} 0.85 &0.04 \\ -0.04 &0.85 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix}$$ | 0.85 |
89-
| $$f_3(P) = \begin{bmatrix} 0.2 &-0.26 \\ 0.23 &022 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix}$$ | 0.07 |
89+
| $$f_3(P) = \begin{bmatrix} 0.2 &-0.26 \\ 0.23 &0.22 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix}$$ | 0.07 |
9090
| $$f_4(P) = \begin{bmatrix} -0.15 &0.28 \\ 0.26 &0.24 \end{bmatrix}P + \begin{bmatrix} 0 \\ 0.44 \end{bmatrix}$$ | 0.07 |
9191

9292
## Playing around a bit...
@@ -98,7 +98,7 @@ Here are a few examples of ferns that can be generated by modifying constituent
9898
| -------- | --------- |
9999
| $$f_1(P) = \begin{bmatrix} \tau &0 \\ 0 &0.16 \end{bmatrix}P + \begin{bmatrix} 0 \\ 0 \end{bmatrix}$$ <p> where $$-0.5 < \tau < 0.5 $$ <p> Turning stems to leaves | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/fern_twiddle_0.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
100100
| $$f_2(P) = \begin{bmatrix} 0.85 & \tau \\ -0.04 &0.85 \end{bmatrix}P + \begin{bmatrix} 0 \\ 1.6 \end{bmatrix}$$ <p> where $$ -0.01 < \tau < 0.09 $$ <p> Changing fern tilt | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/fern_twiddle_1.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
101-
| $$f_3(P) = \begin{bmatrix} 0.2 &-0.26 \\ 0.23 &022 \end{bmatrix}P + \begin{bmatrix} \tau \\ 1.6 \end{bmatrix}$$ <p> where $$-0.5 < \tau < 0.5$$ <p> Plucking left leaves | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/fern_twiddle_2.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
101+
| $$f_3(P) = \begin{bmatrix} 0.2 &-0.26 \\ 0.23 &0.22 \end{bmatrix}P + \begin{bmatrix} \tau \\ 1.6 \end{bmatrix}$$ <p> where $$-0.5 < \tau < 0.5$$ <p> Plucking left leaves | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/fern_twiddle_2.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
102102
| $$f_4(P) = \begin{bmatrix} -0.15 &0.28 \\ 0.26 &0.24 \end{bmatrix}P + \begin{bmatrix} \tau \\ 0.44 \end{bmatrix}$$ <p> where $$-0.5 < \tau < 0.5$$ <p> Plucking right leaves | <div style="text-align:center"> <video style="width:100%" controls loop> <source src="res/fern_twiddle_3.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> |
103103

104104
As an important note: the idea of modifying a resulting image by twiddling the knobs of an affine transform is the heart of many interesting methods, including fractal image compression where a low resolution version of an image is stored along with a reconstructing function set to generate high-quality images on-the-fly {{ "fractal-compression" | cite }}{{ "saupe1994review" | cite }}.
@@ -135,6 +135,8 @@ The biggest differences between the two code implementations is that the Barnsle
135135
[import, lang:"java"](code/java/Barnsley.java)
136136
{% sample lang="coco" %}
137137
[import, lang:"coconut"](code/coconut/barnsley.coco)
138+
{% sample lang="hs" %}
139+
[import, lang:"haskell"](code/haskell/Barnsley.hs)
138140
{% endmethod %}
139141

140142
### Bibliography
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import Data.Array (Array, bounds, listArray, (!))
2+
import Data.List (intercalate)
3+
import System.Random
4+
5+
data Point = Point Double Double
6+
7+
chaosGame :: RandomGen g => g -> Int -> [Double] -> Array Int (Point -> Point) -> [Point]
8+
chaosGame g n probabilities hutchinson = take n points
9+
where
10+
(x, g') = random g
11+
(y, g'') = random g'
12+
13+
picks = randomRs (0, 1) g''
14+
cumulProbabilities = scanl1 (+) probabilities
15+
to_choice x = (+ 1) $ length $ takeWhile (x >) cumulProbabilities
16+
17+
points = Point x y : zipWith (hutchinson !) (map to_choice picks) points
18+
19+
main :: IO ()
20+
main = do
21+
g <- newStdGen
22+
23+
let affine [xx, xy, yx, yy] [a, b] (Point x y) =
24+
Point (a + xx * x + xy * y) (b + yx * x + yy * y)
25+
barnsley =
26+
listArray
27+
(1, 4)
28+
[ affine [0, 0, 0, 0.16] [0, 0],
29+
affine [0.85, 0.04, -0.04, 0.85] [0, 1.6],
30+
affine [0.2, -0.26, 0.23, 0.22] [0, 1.6],
31+
affine [-0.15, 0.28, 0.26, 0.24] [0, 0.44]
32+
]
33+
probabilities = [0.01, 0.85, 0.07, 0.07]
34+
points = chaosGame g 100000 probabilities barnsley
35+
showPoint (Point x y) = show x ++ "\t" ++ show y
36+
37+
writeFile "out.dat" $ intercalate "\n" $ map showPoint points

0 commit comments

Comments
 (0)