RSS Amplifier

Addison Crump · Feb 2, 2025

Playing with Brownian Motion

0
Sign in to vote or save

This page cannot be shown here. You can still read it on the original site — the toolbar below keeps your place in the directory.

This page comes about because of two things: an assignment for my computer graphics course, and a bit of inspiration from a computer graphics YouTuber, acerola , who recently did some work with fractal motion . Though the page was actually a requirement for the course, so, you tell me what inspired this page more :P The theme for our competition in our course was "Chaos in Harmony". If we can find…

This page comes about because of two things: an assignment for my computer graphics course, and a bit of inspiration from a computer graphics YouTuber, acerola</a>, who recently did some work with fractal motion</a>. Though the page was actually a requirement for the course, so, you tell me what inspired this page more :P</p>

The theme for our competition in our course was "Chaos in Harmony". If we can find a good, stable random function that we can efficiently raytrace over, that'd be really nice. The chaos would literally</em> be in harmony.</p>

In the video linked above, there was a claim along the lines of, "we can't draw a good bounding box for all the points, because there is no general solution for this". And I wondered: are there specific cases where we can? Could we use that to implement a raytracer?</p>

A bit of background</h3>

I knew I wanted to do something with fractals for my project, so I turned to a book: "The Science of Fractal Images". It was in this book that I encountered a method for fractal Brownian motion (effectively, noise produced by random choices) that operated by splitting a line at its midpoint, over and over, and applying a decaying random displacement to the line at each of these points.</p>

To illustrate this effect, you can see a simple implementation of this pattern below, iterated through its steps:</p>

A line, growing in complexity over several stages, which are marked with n=1, n=2, and so on</p>

The implementation here is actually quite simple, and differs from the book in a number of ways. Namely, the random displacement at the midpoint is determined as a random offset chosen below some noise N</code>, minus N/2</code>. At each iteration, N</code> is multiplied by some decay factor r</code>, so the real displacement is in [-(r^I)N/2, (r^I)N/2]</code> with I</code> iterations. This allows us to very easily find the actual bounds on the height of displacement after infinite iterations by simply applying the corresponding geometric sum formula.</p>

This was the first iteration of my implementation. We can easily generalise it to higher dimensions by identifying that the number of points we need to compute is always the number of 2^D-1</code> where D</code> are the number of controlling</em> dimensions (i.e. the dimensions we split across, not the final height dimension we produce by random generation). Conveniently, all the midpoints we need to split are defined by the binary encodings of 1..=2^D</code>, where an offset in each dimension is either present as identified by 1 in binary or not present when identified by 0. This works because this successfully identifies all combinations of dimensions we need to split, e.g., in 1 dimension, along the line; in 2 dimensions, along both axes and the diagonal away from the origin; in three dimensions, each axis and diagonal along a cube; and so forth.</p>

And, like before, we can visualise this in a gif:</p>

A line, growing in complexity over several stages, which are marked with n=1, n=2, and so on</p>

Since my initial implementation was actually in Rust, we can very easily take this and actually just slam it into the site. You can play with the Brownian noise generator below:</p>

Read on addisoncrump.info

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.