Jekyll2021-10-24T10:55:50+00:00https://herzamos.ch/feed.xmlAmos’ BlogAmos Herzherzamos@gmail.comThe Marching Cubes Algorithm 2: Meshes & Marching Squares2021-04-10T16:30:00+00:002021-04-10T16:30:00+00:00https://herzamos.ch/marching-cubes/2021/04/10/marching-cubes-2<h2 id="mesh">Mesh</h2>
<h3 id="first-steps-into-meshes">First steps into meshes</h3>
<p>The first thing I had to do was to Google what a mesh is, because I really had no clue. A quick Wikipedia read and I am now a meshes expert! If you are also confused like I was by this term, it turns out being a really simple concept:</p>
<blockquote>
<p>In 3D computer graphics and solid modeling, a polygon mesh is a collection of vertices, edges and faces that defines the shape of a polyhedral object.
(Courtesy of <a href="https://en.wikipedia.org/wiki/Polygon_mesh">Wikipedia</a>)</p>
</blockquote>
<p>Even though I was trying to accomplish it in 2D, I think you got the idea (and if you didn’t, you wil soon, just keep reading :p): I am going to try to smooth out the borders of the caves from <a href="https://www.herzamos.ch/marching-cubes/2021/04/09/marching-cubes-1.html">my previous post</a>.</p>
<h3 id="the-algorithm">The algorithm</h3>
<p>The algorithm is the same as the one we discussed before for the 3D case, but in 2D (that’s why it’s called “Marching Squares”). We start by dividing our space into squares, each one having his 4 vertices on 4 adjacent pixels in the drawing (see Figure 1 for an example).</p>
<div class="image" style="text-align:center;margin-bottom: 10px;margin-top: 10px;">
<img src="/assets/img/square-division.png" alt="Image couldn't be loaded" width="300" style="margin-bottom: 10px;" />
<figcaption>Figure 1: An example of how the cave is divided into squares, using the seed "Marching Cubes"</figcaption>
</div>
<p>Each one of these squares will have 4 control points, one on each one of the square’s edges. These points will then be connected based on which vertices have to be inside the wall and which have to be outside; figure 2 displays all the (16) possible combinations.</p>
<div class="image" style="text-align:center;margin-bottom: 10px;margin-top: 10px;">
<img src="/assets/img/look-up-table-marching-squares.png" alt="Image couldn't be loaded" width="300" style="margin-bottom: 10px;" />
<figcaption>Figure 2: All the possible combinations</figcaption>
</div>
<div class="image" style="text-align:center;margin-bottom: 10px;margin-top: 10px;">
<img src="/assets/img/close-up-marching-squares.png" alt="Image couldn't be loaded" width="300" style="margin-bottom: 10px;" />
<figcaption>Figure 3: Close up showing the "control points"</figcaption>
</div>Amos Herzherzamos@gmail.comMeshThe Marching Cubes Algorithm 1: Introduction & Procedural Cave Generation in 2D2021-04-09T16:30:00+00:002021-04-09T16:30:00+00:00https://herzamos.ch/marching-cubes/2021/04/09/marching-cubes-1<h2 id="the-marching-cubes-algorithm">The marching cubes algorithm</h2>
<h3 id="introduction">Introduction</h3>
<p>During the holydays, since ETH wasn’t giving me enough work to do, I decided to learn how to use <a href="https://unity.com/">Unity</a>.
While deciding the project to implement, I stumbled upon the marching cube algorithms, so now here we are!</p>
<h3 id="the-problem">The problem</h3>
<p>The main need the Marching Cube Algorithm tries to satisfy, is the need to form a facet approximation to an isosurface through a scalar field, sampled on a rectangle grid. A lot of big words huh? Let’s make this simple: imagine to have a lot of points nicely distributed on a section of space. We now decide which of these points we want to be contained in our 3d surface, and which not. There we are! We can now pass our “marching cube” over all the points and make it draw triangles to “exclude” external vertices: each triangle will have his vertices between an excluded cube vertex and an included one (see Figure 1 for a reference).</p>
<h3 id="the-algorithm">The algorithm</h3>
<p>The main problem of this algorithm is the amount of data we’d need to compute, but luckily someone has already done that for us, and pre-computed tables are <a href="http://paulbourke.net/geometry/polygonise/">available online</a>.
As everyone knows a cube has 8 vertices. Since each one of those vertices can be either inside the isosurface or outisde, there are \(2^{8} = 256\) possible combinations of vertices. Luckily (again!) only \(14\) of those are actually relevant, since all the other are just rotations or mirrorings of these “base” cases.</p>
<div class="image" style="text-align:center;margin-bottom: 10px;margin-top: 10px;">
<img src="/assets/img/cube-combinations.jpg" alt="Image couldn't be loaded" width="300" style="margin-bottom: 10px;" />
<figcaption>Figure 1: The fundamental cases of the marching cubes algorithm</figcaption>
</div>
<h2 id="cave-generation">Cave Generation</h2>
<h3 id="starting-slow">Starting slow</h3>
<p>Before going 3D, I thought starting with a 2D cave generator would have been a good idea to first learn the basics of Unity. That’s when I encountered <a href="https://www.youtube.com/watch?v=v7yyZZjF1z4">this</a> great video series, which helped me learn a lot.</p>
<h3 id="first-steps-into-unity">First steps into Unity</h3>
<p>The first thing I got to work was generating a 2D map, made of squares which are randomlz chosen to be black or white (Figure 2).</p>
<div class="image" style="text-align:center;margin-bottom: 10px;margin-top: 10px;">
<img src="/assets/img/cave-gen-1.png" alt="Image couldn't be loaded" width="300" style="margin-bottom: 10px;" />
<figcaption>Figure 2: A first approach to a random generated map</figcaption>
</div>
<p>As you maybe already noticed, this set-up really looks like the starting point of a <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Conway’s Game of Life</a> game. Indeed, the procedural map generation will be based on <a href="https://en.wikipedia.org/wiki/Cellular_automaton">cellular automation</a>, but not on the set of rules Conway had defined. <br />
The map generation is based on a seed system, and I also added some variables to play with for the map generation, such as a <code class="language-plaintext highlighter-rouge">fillPercent</code> field, with whom I could easily manage how much i wanted the map to be filled.</p>
<p>The rule I’ve used are failry simple:</p>
<ul>
<li>If the cell as more then 4 alive neighbour cells, make it alive;</li>
<li>If it has less than 4 alive neighbour cells, make it die;</li>
<li>If it has exactly 4 alive neighbours, let it be as it is;</li>
</ul>
<p>This precise rule is what I found working the best to generate a cave-resembling shape. Moreover, I’ve added some tweaks to the code to make sure that near walls more cells become alive, and ensure that the more we go towards the end of the cave, the thicker the walls are. I decided to apply the rule for 5 iterations, which seemed to work just fine. Some results can be obvserved below.</p>
<div class="image" style="text-align:center;margin-bottom: 10px;margin-top: 10px;">
<img src="/assets/img/cave-gen-results.png" alt="Image couldn't be loaded" width="600" style="margin-bottom: 10px;" />
<figcaption>Figure 3: Some of the results of the algorithm: on the left, two results displayed on a 128x64 grid; on the right, two bigger grids (500x250 on the top, 1000x500 on the bottom). All measures in "squares".</figcaption>
</div>
<p>In the end I played around with grid dimension, seeds, number of iterations and also tried changing the rule threshold (which was previously 4), but I didn’t get any result worth mentioning.</p>Amos Herzherzamos@gmail.comThe marching cubes algorithm