How To Continuously Draw Random Points In Procesisng
Introduction
"Reading well-nigh nature is fine, only if a person walks in the wood and listens advisedly, they can acquire more than what is in books." — George Washington Carver
Here we are: the beginning. Well, nigh the beginning. If it'south been a while since you've washed any programming in Processing (or whatsoever math, for that matter), this introduction will get your mind back into computational thinking before we approach some of the more than difficult and complex material.
In Chapter i, we're going to talk almost the concept of a vector and how it will serve as the building cake for simulating motion throughout this book. But before nosotros take that footstep, permit'due south think about what it means for something to simply move around the screen. Permit's begin with one of the best-known and simplest simulations of motion—the random walk.
I.1 Random Walks
Imagine you are standing in the middle of a residue beam. Every ten seconds, you flip a coin. Heads, accept a step forrard. Tails, take a step astern. This is a random walk—a path defined every bit a serial of random steps. Stepping off that remainder axle and onto the floor, you could perform a random walk in two dimensions by flipping that same coin twice with the following results:
| Flip 1 | Flip 2 | Effect |
|---|---|---|
| Heads | Heads | Stride forward. |
| Heads | Tails | Stride right. |
| Tails | Heads | Step left. |
| Tails | Tails | Step backward. |
Yes, this may seem similar a particularly unsophisticated algorithm. Nonetheless, random walks tin exist used to model phenomena that occur in the real world, from the movements of molecules in a gas to the behavior of a gambler spending a day at the casino. As for us, we begin this book studying a random walk with iii goals in mind.
-
Nosotros demand to review a programming concept fundamental to this book—object-oriented programming. The random walker will serve as a template for how we will use object-oriented design to make things that move around a Processing window.
-
The random walk instigates the 2 questions that nosotros will ask over and over once again throughout this book: "How practice we define the rules that govern the behavior of our objects?" so, "How practice we implement these rules in Processing?"
-
Throughout the book, nosotros'll periodically need a bones understanding of randomness, probability, and Perlin noise. The random walk will let us to demonstrate a few key points that will come in handy afterwards.
I.2 The Random Walker Class
Let's review a chip of object-oriented programming (OOP) first by building a Walker object. This will be only a cursory review. If you have never worked with OOP before, you may desire something more comprehensive; I'd suggest stopping here and reviewing the basics on the Processing website before continuing.
An object in Processing is an entity that has both data and functionality. We are looking to blueprint a Walker object that both keeps track of its data (where it exists on the screen) and has the adequacy to perform certain actions (such as draw itself or take a step).
A course is the template for building actual instances of objects. Think of a class equally the cookie cutter; the objects are the cookies themselves.
Let's begin by defining the Walker course—what it means to be a Walker object. The Walker simply needs ii pieces of data—a number for its 10-location and i for its y-location.
Every form must have a constructor, a special office that is called when the object is starting time created. You can recall of it as the object'south setup(). There, we'll initialize the Walker's starting location (in this case, the center of the window).
Finally, in addition to data, classes can be defined with functionality. In this example, a Walker has two functions. We first write a function that allows the object to brandish itself (as a white dot).
The 2d office directs the Walker object to take a footstep. Now, this is where things get a bit more interesting. Remember that floor on which we were taking random steps? Well, now we tin can utilize a Processing window in that same capacity. There are four possible steps. A step to the right tin can be simulated past incrementing 10 (x++); to the left by decrementing x (10--); forward past going down a pixel (y++); and backward by going up a pixel (y--). How practise we pick from these four choices? Earlier we stated that we could flip two coins. In Processing, even so, when we want to randomly choose from a list of options, nosotros can pick a random number using random().
The above line of code picks a random floating point number between 0 and 4 and converts it to an integer, with a result of 0, 1, two, or iii. Technically speaking, the highest number will never exist four.0, only rather 3.999999999 (with as many 9s as at that place are decimal places); since the procedure of converting to an integer lops off the decimal identify, the highest int we tin become is 3. Next, we take the appropriate step (left, right, up, or down) depending on which random number was picked.
Now that we've written the class, information technology's time to make an actual Walker object in the main part of our sketch—setup() and draw(). Assuming nosotros are looking to model a single random walk, we declare ane global variable of type Walker.
Then we create the object in setup() past calling the constructor with the new operator.
Example I.1: Traditional random walk
Each time yous see the above Instance heading in this book, it ways there is a corresponding code example available on GitHub.
Finally, during each bicycle through draw(), we ask the Walker to take a pace and draw a dot.
Since we but draw the background one time in setup(), rather than clearing it continually each time through describe(), nosotros run into the trail of the random walk in our Processing window.
There are a couple improvements nosotros could make to the random walker. For one, this Walker's footstep choices are express to iv options—up, down, left, and right. But whatever given pixel in the window has 8 possible neighbors, and a ninth possibility is to stay in the same place.
Effigy I.one
To implement a Walker object that tin can step to whatever neighboring pixel (or stay put), we could choice a number between 0 and 8 (nine possible choices). Nevertheless, a more efficient way to write the code would be to only pick from three possible steps forth the x-axis (-1, 0, or one) and three possible steps along the y-axis.
Taking this farther, we could utilise floating betoken numbers (i.e. decimal numbers) for 10 and y instead and motion according to an arbitrary random value between -one and ane.
All of these variations on the "traditional" random walk have 1 thing in mutual: at any moment in time, the probability that the Walker will have a footstep in a given direction is equal to the probability that the Walker volition take a step in any direction. In other words, if there are iv possible steps, in that location is a i in 4 (or 25%) risk the Walker will take whatsoever given step. With nine possible steps, it's a 1 in 9 (or 11.1%) chance.
Conveniently, this is how the random() role works. Processing's random number generator (which operates behind the scenes) produces what is known as a "uniform" distribution of numbers. We can examination this distribution with a Processing sketch that counts each time a random number is picked and graphs it as the elevation of a rectangle.
Example I.2: Random number distribution
The above screenshot shows the result of the sketch running for a few minutes. Notice how each bar of the graph differs in height. Our sample size (i.east. the number of random numbers we've picked) is rather pocket-sized and at that place are some occasional discrepancies, where certain numbers are picked more than oftentimes. Over time, with a practiced random number generator, this would fifty-fifty out.
Pseudo-Random Numbers
The random numbers we become from the random() office are not truly random; therefore they are known as "pseudo-random." They are the result of a mathematical function that simulates randomness. This part would yield a pattern over time, but that time menstruation is then long that for us, it'south only as good as pure randomness!
Do I.one
Create a random walker that has a tendency to move down and to the right. (We'll see the solution to this in the adjacent section.)
I.three Probability and Not-Uniform Distributions
Recall when you beginning started programming in Processing? Maybe you lot wanted to describe a lot of circles on the screen. So yous said to yourself: "Oh, I know. I'll draw all these circles at random locations, with random sizes and random colors." In a calculator graphics organization, it's often easiest to seed a organization with randomness. In this book, however, we're looking to build systems modeled on what we encounter in nature. Defaulting to randomness is non a particularly thoughtful solution to a design problem—in particular, the kind of problem that involves creating an organic or natural-looking simulation.
With a few tricks, we can change the mode we use random() to produce "not-compatible" distributions of random numbers. This will come in handy throughout the volume as we look at a number of different scenarios. When we examine genetic algorithms, for instance, we'll need a methodology for performing "selection"—which members of our population should exist selected to pass their Dna to the next generation? Retrieve the concept of survival of the fittest? Allow'south say we have a population of monkeys evolving. Non every monkey will have a equal chance of reproducing. To simulate Darwinian evolution, we can't simply pick two random monkeys to be parents. Nosotros need the more than "fit" ones to be more likely to be chosen. Nosotros need to ascertain the "probability of the fittest." For example, a particularly fast and stiff monkey might have a 90% chance of procreating, while a weaker one has simply a 10% run a risk.
Let'southward intermission hither and take a look at probability's basic principles. First we'll examine single upshot probability, i.east. the likelihood that a given event will occur.
If you have a system with a certain number of possible outcomes, the probability of the occurrence of a given event equals the number of outcomes that qualify as that consequence divided by the total number of all possible outcomes. A money toss is a elementary instance—information technology has simply two possible outcomes, heads or tails. There is only one way to flip heads. The probability that the coin volition plough upward heads, therefore, is ane divided by two: one/ii or l%.
Take a deck of fifty-two cards. The probability of drawing an ace from that deck is:
number of aces / number of cards = 4 / 52 = 0.077 = ~ 8%
The probability of drawing a diamond is:
number of diamonds / number of cards = 13 / 52 = 0.25 = 25%
We can also calculate the probability of multiple events occurring in sequence. To exercise this, we simply multiply the individual probabilities of each effect.
The probability of a money turning up heads three times in a row is:
(1/2) * (1/2) * (1/ii) = ane/8 (or 0.125)
…meaning that a coin volition turn up heads three times in a row one out of eight times (each "time" being 3 tosses).
Exercise I.2
What is the probability of drawing two aces in a row from a deck of fifty-2 cards?
There are a couple of ways in which we can employ the random() function with probability in lawmaking. One technique is to make full an array with a pick of numbers—some of which are repeated—so choose random numbers from that array and generate events based on those choices.
Running this lawmaking volition produce a 40% chance of printing the value 1, a 20% adventure of printing 2, and a forty% risk of press 3.
Nosotros tin can too enquire for a random number (let'southward make it uncomplicated and just consider random floating point values between 0 and 1) and permit an upshot to occur only if our random number is within a certain range. For example:
This method tin can also be applied to multiple outcomes. Let'southward say that Event A has a 60% risk of happening, Outcome B, a 10% chance, and Effect C, a 30% take chances. Nosotros implement this in code by picking a random float and seeing into what range it falls.
-
betwixt 0.00 and 0.60 (60%) –> Effect A
-
betwixt 0.60 and 0.70 (ten%) –> Upshot B
-
between 0.lxx and ane.00 (30%) –> Result C
We could use the in a higher place methodology to create a random walker that tends to move to the right. Here is an example of a Walker with the following probabilities:
-
chance of moving upward: xx%
-
run a risk of moving downwards: 20%
-
take a chance of moving left: 20%
-
gamble of moving correct: 40%
Example I.3: Walker that tends to move to the right
Exercise I.3
Create a random walker with dynamic probabilities. For example, tin can you requite it a 50% chance of moving in the direction of the mouse?
I.4 A Normal Distribution of Random Numbers
Let's get back to that population of simulated Processing monkeys. Your program generates a thousand Monkey objects, each with a pinnacle value between 200 and 300 (as this is a earth of monkeys that have heights betwixt 200 and 300 pixels).
Does this accurately describe the heights of real-world beings? Think of a crowded sidewalk in New York City. Pick any person off the street and it may appear that their height is random. However, it'south not the kind of random that random() produces. People'south heights are not uniformly distributed; there are a dandy deal more people of boilerplate height than there are very tall or very short ones. To simulate nature, we may want information technology to exist more likely that our monkeys are of average acme (250 pixels), however all the same permit them to be, on occasion, very short or very alpine.
A distribution of values that cluster around an average (referred to as the "mean") is known as a "normal" distribution. It is also called the Gaussian distribution (named for mathematician Carl Friedrich Gauss) or, if you are French, the Laplacian distribution (named for Pierre-Simon Laplace). Both mathematicians were working concurrently in the early nineteenth century on defining such a distribution.
When you graph the distribution, you get something that looks similar the following, informally known every bit a bell curve:
Figure I.ii
Figure I.3
The curve is generated by a mathematical part that defines the probability of any given value occurring as a function of the mean (oftentimes written equally μ, the Greek letter of the alphabet mu) and standard deviation (σ, the Greek letter sigma).
The mean is pretty like shooting fish in a barrel to understand. In the case of our peak values between 200 and 300, you probably have an intuitive sense of the mean (i.e. average) every bit 250. However, what if I were to say that the standard departure is iii or 15? What does this mean for the numbers? The graphs above should give us a hint. The graph on the left shows united states the distribution with a very low standard departure, where the majority of the values cluster closely around the mean. The graph on the right shows us a higher standard divergence, where the values are more evenly spread out from the boilerplate.
The numbers work out as follows: Given a population, 68% of the members of that population will have values in the range of one standard deviation from the mean, 98% inside two standard deviations, and 99.7% within three standard deviations. Given a standard deviation of v pixels, only 0.3% of the monkey heights volition be less than 235 pixels (three standard deviations below the mean of 250) or greater than 265 pixels (three standard deviations above the mean of 250).
Calculating Mean and Standard Divergence
Consider a class of x students who receive the following scores (out of 100) on a test:
85, 82, 88, 86, 85, 93, 98, 40, 73, 83
The mean is the average: 81.3
The standard deviation is calculated as the square root of the average of the squares of deviations effectually the mean. In other words, take the difference from the hateful for each person and square information technology (variance). Summate the boilerplate of all these values and take the square root as the standard difference.
| Score | Difference from Mean | Variance |
|---|---|---|
| Average Variance: | 254.23 | |
| 85 | 85-81.3 = 3.7 | (3.7)two = thirteen.69 |
| 40 | 40-81.3 = -41.3 | (-41.3)ii = 1705.69 |
| etc. |
The standard departure is the foursquare root of the average variance: 15.13
Luckily for us, to use a normal distribution of random numbers in a Processing sketch, we don't accept to do any of these calculations ourselves. Instead, we can make employ of a class known every bit Random, which we get for free every bit function of the default Java libraries imported into Processing (meet the JavaDocs for more information).
To use the Random class, we must first declare a variable of type Random and create the Random object in setup().
If we want to produce a random number with a normal (or Gaussian) distribution each time nosotros run through draw(), it's every bit easy as calling the role nextGaussian().
Here's the thing. What are we supposed to do with this value? What if nosotros wanted to employ it, for example, to assign the x-position of a shape we depict on screen?
The nextGaussian() office returns a normal distribution of random numbers with the following parameters: a mean of zero and a standard deviation of one. Permit's say we want a mean of 320 (the center horizontal pixel in a window of width 640) and a standard deviation of 60 pixels. We can adjust the value to our parameters by multiplying it by the standard deviation and adding the mean.
Example I.4: Gaussian distribution
By drawing the ellipses on top of each other with some transparency, nosotros can actually encounter the distribution. The brightest spot is near the center, where most of the values cluster, but every then ofttimes circles are drawn further to the right or left of the centre.
Exercise I.4
Consider a simulation of paint splatter fatigued every bit a collection of colored dots. Most of the paint clusters around a central location, but some dots practise splatter out towards the edges. Can you use a normal distribution of random numbers to generate the locations of the dots? Can y'all also use a normal distribution of random numbers to generate a color palette?
Exercise I.5
A Gaussian random walk is defined every bit 1 in which the step size (how far the object moves in a given direction) is generated with a normal distribution. Implement this variation of our random walk.
I.5 A Custom Distribution of Random Numbers
At that place will come a time in your life when you practise not want a uniform distribution of random values, or a Gaussian one. Permit's imagine for a moment that you are a random walker in search of food. Moving randomly around a space seems like a reasonable strategy for finding something to swallow. Later all, y'all don't know where the food is, so you might likewise search randomly until you detect it. The problem, as you may accept noticed, is that random walkers render to previously visited locations many times (this is known equally "oversampling"). 1 strategy to avoid such a problem is to, every so oft, take a very large pace. This allows the walker to forage randomly around a specific location while periodically jumping very far away to reduce the amount of oversampling. This variation on the random walk (known equally a Lévy flight) requires a custom ready of probabilities. Though non an exact implementation of a Lévy flight, we could state the probability distribution as follows: the longer the step, the less likely it is to be picked; the shorter the pace, the more likely.
Earlier in this prologue, we saw that we could generate custom probability distributions past filling an array with values (some duplicated so that they would be picked more than frequently) or past testing the event of random(). We could implement a Lévy flight past saying that there is a one% chance of the walker taking a big step.
Withal, this reduces the probabilities to a stock-still number of options. What if we wanted to make a more than general rule—the higher a number, the more than probable it is to be picked? 3.145 would exist more likely to be picked than 3.144, fifty-fifty if that likelihood is just a tiny chip greater. In other words, if x is the random number, we could map the likelihood on the y-axis with y = x.
Figure I.4
If we can figure out how to generate a distribution of random numbers according to the above graph, so nosotros will be able to use the same methodology to whatever bend for which we accept a formula.
I solution is to selection 2 random numbers instead of one. The get-go random number is simply that, a random number. The second one, however, is what we'll call a "qualifying random value." Information technology will tell united states whether to use the first i or throw it abroad and pick another i. Numbers that have an easier time qualifying will be picked more oftentimes, and numbers that rarely authorize will exist picked infrequently. Hither are the steps (for now, permit's consider only random values between 0 and 1):
-
Option a random number: R1
-
Compute a probability P that R1 should qualify. Let'south try: P = R1.
-
Pick another random number: R2
-
If R2 is less than P, then we take establish our number—R1!
-
If R2 is non less than P, go back to step 1 and start over.
Here we are maxim that the likelihood that a random value volition qualify is equal to the random number itself. Let'due south say we pick 0.1 for R1. This ways that R1 will take a x% chance of qualifying. If we pick 0.83 for R1 so information technology will have a 83% chance of qualifying. The college the number, the greater the likelihood that nosotros will actually use it.
Here is a role (named for the Monte Carlo method, which was named for the Monte Carlo casino) that implements the higher up algorithm, returning a random value between 0 and 1.
Exercise I.6
Use a custom probability distribution to vary the size of a step taken by the random walker. The stride size can be adamant past influencing the range of values picked. Can you map the probability exponentially—i.due east. making the likelihood that a value is picked equal to the value squared?
(Later nosotros'll run into how to do this more efficiently using vectors.)
I.six Perlin Noise (A Smoother Approach)
A good random number generator produces numbers that have no relationship and show no discernible design. Equally nosotros are beginning to meet, a little bit of randomness can be a good thing when programming organic, lifelike behaviors. Nonetheless, randomness as the unmarried guiding principle is non necessarily natural. An algorithm known as "Perlin noise," named for its inventor Ken Perlin, takes this concept into account. Perlin developed the noise function while working on the original Tron movie in the early 1980s; it was designed to create procedural textures for computer-generated effects. In 1997 Perlin won an Academy Laurels in technical achievement for this work. Perlin dissonance can be used to generate diverse effects with natural qualities, such every bit clouds, landscapes, and patterned textures like marble.
Perlin noise has a more organic advent because information technology produces a naturally ordered ("smooth") sequence of pseudo-random numbers. The graph on the left beneath shows Perlin noise over fourth dimension, with the x-axis representing fourth dimension; notation the smoothness of the curve. The graph on the right shows pure random numbers over time. (The code for generating these graphs is bachelor in the accompanying book downloads.)
Effigy I.5: Noise
Effigy I.6: Random
Processing has a congenital-in implementation of the Perlin dissonance algorithm: the function noise(). The racket() function takes one, two, or three arguments, as dissonance is computed in ane, 2, or three dimensions. Permit's kickoff by looking at one-dimensional dissonance.
Dissonance Detail
The Processing dissonance reference tells us that noise is calculated over several "octaves." Calling the noiseDetail() function will modify both the number of octaves and their importance relative to i another. This in plow changes how the racket function behaves.
An online lecture by Ken Perlin lets yous learn more almost how noise works from Perlin himself.
Consider drawing a circle in our Processing window at a random 10-location.
Now, instead of a random x-location, we want a Perlin dissonance x-location that is "smoother." Y'all might think that all you lot need to do is replace random() with dissonance(), i.e.
While conceptually this is exactly what we desire to practice—calculate an 10-value that ranges between 0 and the width according to Perlin noise—this is not the correct implementation. While the arguments to the random() part specify a range of values between a minimum and a maximum, racket() does not work this way. Instead, the output range is fixed—it e'er returns a value between 0 and ane. We'll see in a moment that we can get around this easily with Processing's map() function, but first nosotros must examine what exactly dissonance() expects us to laissez passer in as an argument.
We can think of one-dimensional Perlin dissonance as a linear sequence of values over time. For example:
| Fourth dimension | Noise Value |
|---|---|
| 0 | 0.365 |
| 1 | 0.363 |
| ii | 0.363 |
| 3 | 0.364 |
| 4 | 0.366 |
Now, in gild to access a particular noise value in Processing, we have to pass a specific "moment in fourth dimension" to the racket() office. For example:
According to the above table, noise(3) will render 0.364 at fourth dimension equals 3. We could improve this by using a variable for fourth dimension and asking for a noise value continuously in draw().
The in a higher place code results in the same value printed over and over. This happens because we are asking for the result of the dissonance() function at the same point in time—3—over and over. If we increment the time variable t, yet, nosotros'll get a different upshot.
How quickly nosotros increment t also affects the smoothness of the racket. If we make large jumps in fourth dimension, then we are skipping ahead and the values volition exist more random.
Effigy I.vii
Try running the lawmaking several times, incrementing t by 0.01, 0.02, 0.05, 0.i, 0.0001, and you will see different results.
Mapping Noise
Now nosotros're set up to answer the question of what to exercise with the racket value. Once we have the value with a range between 0 and 1, information technology's up to us to map that range to what we want. The easiest way to do this is with Processing's map() function. The map() function takes five arguments. First upwardly is the value we desire to map, in this case n. And so nosotros have to give information technology the value's current range (minimum and maximum), followed by our desired range.
Figure I.8
In this instance, we know that noise has a range betwixt 0 and 1, merely we'd similar to draw our circle with a range between 0 and the window's width.
We can apply the exact aforementioned logic to our random walker, and assign both its x- and y-values co-ordinate to Perlin noise.
Example I.five: Perlin noise walker
Notice how the above example requires an additional pair of variables: tx and ty. This is because we need to proceed rails of 2 time variables, one for the ten-location of the Walker object and 1 for the y-location. But there is something a scrap odd near these variables. Why does tx start at 0 and ty at 10,000? While these numbers are arbitrary choices, nosotros take very specifically initialized our 2 time variables with different values. This is because the noise role is deterministic: it gives you the same issue for a specific fourth dimension t each and every time. If nosotros asked for the noise value at the same time t for both x and y, then ten and y would ever be equal, meaning that the Walker object would just move forth a diagonal. Instead, nosotros simply use 2 different parts of the noise space, starting at 0 for x and 10,000 for y so that ten and y can announced to act independently of each other.
Effigy I.nine
In truth, there is no actual concept of time at play here. It's a useful metaphor to help us sympathize how the noise function works, but really what we have is space, rather than time. The graph above depicts a linear sequence of noise values in a one-dimensional infinite, and nosotros can ask for a value at a specific x-location whenever we want. In examples, you will often see a variable named xoff to indicate the x-kickoff along the racket graph, rather than t for time (as noted in the diagram).
Exercise I.7
In the in a higher place random walker, the result of the noise part is mapped straight to the Walker's location. Create a random walker where you lot instead map the result of the racket() office to a Walker's step size.
Ii-Dimensional Racket
This idea of noise values living in a 1-dimensional space is important considering information technology leads united states of america right into a discussion of two-dimensional space. Let's call up about this for a moment. With one-dimensional racket, we take a sequence of values in which any given value is similar to its neighbour. Because the value is in one dimension, it merely has two neighbors: a value that comes earlier it (to the left on the graph) and one that comes after it (to the right).
Figure I.10: 1D Noise
Figure I.11: 2d Noise
2-dimensional noise works exactly the same fashion conceptually. The difference of course is that we aren't looking at values along a linear path, but values that are sitting on a grid. Think of a piece of graph paper with numbers written into each cell. A given value volition be similar to all of its neighbors: in a higher place, below, to the right, to the left, and along any diagonal.
If you were to visualize this graph paper with each value mapped to the effulgence of a color, you would get something that looks like clouds. White sits next to light greyness, which sits next to gray, which sits next to dark gray, which sits next to black, which sits next to dark gray, etc.
This is why noise was originally invented. You tweak the parameters a bit or play with color to make the resulting image look more than like marble or woods or any other organic texture.
Permit'south have a quick await at how to implement two-dimensional racket in Processing. If you wanted to colour every pixel of a window randomly, you would need a nested loop, one that accessed each pixel and picked a random brightness.
To color each pixel according to the noise() office, we'll do exactly the same thing, merely instead of calling random() we'll call noise().
This is a overnice start conceptually—it gives you a dissonance value for every (10,y) location in our two-dimensional space. The problem is that this won't take the cloudy quality we desire. Jumping from pixel 200 to pixel 201 is as well large of a leap through noise. Remember, when we worked with one-dimensional noise, we incremented our fourth dimension variable by 0.01 each frame, not by i! A pretty skilful solution to this problem is to only utilise unlike variables for the dissonance arguments. For example, we could increment a variable called xoff each fourth dimension we motion horizontally, and a yoff variable each time we move vertically through the nested loops.
Example I.vi: second Perlin noise
Do I.8
Play with color, noiseDetail(), and the charge per unit at which xoff and yoff are incremented to achieve different visual furnishings.
Do I.9
Add a third argument to noise that increments once per bike through draw() to animate the ii-dimensional noise.
Practise I.10
Utilise the racket values as the elevations of a landscape. Run across the screenshot below as a reference.
We've examined several traditional uses of Perlin racket in this department. With i-dimensional racket, we used smoothen values to assign the location of an object to requite the appearance of wandering. With ii-dimensional dissonance, we created a cloudy pattern with smoothed values on a plane of pixels. Information technology's important to remember, however, that Perlin noise values are just that—values. They aren't inherently tied to pixel locations or color. Any example in this book that has a variable could be controlled via Perlin racket. When we model a current of air forcefulness, its strength could be controlled by Perlin dissonance. Same goes for the angles betwixt the branches in a fractal tree pattern, or the speed and direction of objects moving forth a grid in a flow field simulation.
Figure I.12: Tree with Perlin noise
Figure I.13: Flow field with Perlin noise
I.seven Onward
We began this chapter past talking well-nigh how randomness tin can be a crutch. In many ways, it'due south the most obvious respond to the kinds of questions we inquire continuously—how should this object motion? What color should information technology be? This obvious answer, however, can also be a lazy one.
As nosotros stop off the introduction, it'due south too worth noting that we could just every bit hands autumn into the trap of using Perlin noise as a crutch. How should this object motility? Perlin noise! What color should it be? Perlin noise! How fast should it abound? Perlin noise!
The indicate of all of this is not to say that you should or shouldn't employ randomness. Or that you should or shouldn't use Perlin noise. The point is that the rules of your system are defined by you, and the larger your toolbox, the more choices yous'll have as you lot implement those rules. The goal of this book is to fill your toolbox. If all you know is random, then your design thinking is limited. Certain, Perlin racket helps, merely you lot'll need more than. A lot more.
I think we're gear up to begin.
Source: https://natureofcode.com/book/introduction/
Posted by: harveyterfew1943.blogspot.com

0 Response to "How To Continuously Draw Random Points In Procesisng"
Post a Comment