105 lines
4.3 KiB
HTML
105 lines
4.3 KiB
HTML
<html>
|
|
<title>Midpoint Displacement</title>
|
|
|
|
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
|
|
<link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet">
|
|
<link rel"shortcut icon" type"image/ico" href"/Media/iconImage.ico">
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
|
|
<button id="backButton" onclick="window.location.href='/#tutorials'">Back</button>
|
|
|
|
<head>
|
|
|
|
<h1>Midpoint Displacement</h1>
|
|
|
|
<p>Midpoint displacement is a common way to generate terrains in video
|
|
games. Instead of manually creating a stage you can make an
|
|
algorithm create one based off randomness. This is faster to
|
|
calculate than a perlin noise stage which is why it can be found
|
|
frequently in older video game titles.</p><br>
|
|
<p>Psudo code:</p>
|
|
<div class="psudoCode">
|
|
<ul>
|
|
<li>Create two points.</li>
|
|
<li>Find the center x coordinate.</li>
|
|
<li>Create a new point in between the two first points with some
|
|
offset in the y coorindate.</li>
|
|
<li>Repeat. (can be recursive)</li>
|
|
</div>
|
|
<br>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<p>This canvas starts off with two points in an array called
|
|
<a>points[]</a>, one at <a>height/2</a> and one at
|
|
<a>math.random(-vertical_displacement, vertical_displacement)</a>.
|
|
The center point is found and a new point is made and added to the
|
|
array. This new point is offset on the y-axis by an amount however
|
|
we can't use the same <a>vertical_displacement</a> as we did before
|
|
as we'd end up with a very jagged terrain.
|
|
</p>
|
|
<img class="examples" src="Jagged_Terrain.jpg">
|
|
|
|
<p>Instead we have to iterate our variable -
|
|
<a>vertical_displacement</a> - based on the iteration number of the
|
|
sketch, in order to generate a smooth stage/terrain.
|
|
</p>
|
|
|
|
<div class="psudoCode">
|
|
<a>vertical_displacement = points[0].y + points[1].y / 2;</a><br>
|
|
<a>vertical_displacement *= 2 ** (-roughness);</a>
|
|
</div>
|
|
|
|
<p>The top formula is the inital value. The second is applied very
|
|
iteration of the sketch.</p>
|
|
<p>Right now we can add one point to the list, time to add several! This
|
|
means for loops. But before we can loop through our array how do we
|
|
know which point should connect to which? We need to sort the array
|
|
based on x value, so that the points read off from left to right.
|
|
</p>
|
|
<p>I just used a bubble sort for simplicity however it's worth pointing
|
|
out that the number of points grows exponetially - <a>O(2^n)</a>
|
|
where n = iterations - so after just 10 iterations <a>points.length
|
|
= 1024</a>. A merge sort could be used to speed up computation
|
|
times.</p>
|
|
<p>Now we can use a for loop to go through our array and compare the ith
|
|
item to the (i+1)th item, and then update <a>iterations</a> and
|
|
<a>vertical_displacement</a>.
|
|
</p>
|
|
|
|
<div class="psudoCode">
|
|
<a>var pLength = points.length;</a><br><br>
|
|
|
|
<a> for (var i = 0; i < pLength - 1; i++){</a><br>
|
|
|
|
<a> var midX = (points[i].x + points[i +
|
|
1].x) / 2;</a><br>
|
|
<a> var midY = (points[i].y + points[i +
|
|
1].y) / 2;</a><br>
|
|
<a> midY += random(-vertical_displacement,
|
|
vertical_displacement);</a><br>
|
|
|
|
<a> points[pLength + i] = new point(midX,
|
|
midY);</a><br>
|
|
<a> }</a><br><br>
|
|
|
|
<a>iterations += 1;</a><br>
|
|
<a>vertical_displacement *= 2 ** (-roughness);</a><br>
|
|
|
|
<a>bubbleSort();</a><br>
|
|
</div>
|
|
<h2>NOTE: Do not use points.length to define your for loop as we are
|
|
increasing the length of the array within the loop</h2>
|
|
<!--<span id="c1"></span>-->
|
|
</body>
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.2.0/p5.min.js"
|
|
integrity="sha512-b/htz6gIyFi3dwSoZ0Uv3cuv3Ony7EeKkacgrcVg8CMzu90n777qveu0PBcbZUA7TzyENGtU+qZRuFAkfqgyoQ=="
|
|
crossorigin="anonymous"></script>
|
|
<script src="sketch.js"></script>
|
|
<script src="dot.js"></script>
|
|
|
|
|
|
</html>
|