Page 5: Lots of Walking Objects

CS559 Spring 2023 Sample Solution

This page and its exercise and advanced problems are more about graphics programming than fundamental graphics concepts.

Basically, the methods you’re going to experiment with have a bunch of simple objects that each make individual “steering” decisions, and maintain their speeds. This is sometimes referred to as “flocking.” The first person to really write about it in the graphics literature was Craig Reynolds who not only wrote the original flocking paper, but also maintains a good page with information about it. The “creatures” that flock are sometimes referred to as “boids” since they aren’t always birds (sometimes they are fish, or pedestrians, or …).

Boids are a fun programming project, and thus there are a number of implementations on the web. If you want, check out this pretty Online Boids Demo or this fun YouTube video by Sebastian Lague.

See also 2008 Boids Demo for a more interactive demo. You can see the source code, but it’s so archaic that it probably won’t help you - we don’t recommend looking at it.

Creating flocking was a project in the old games class. Some of those old 2010 projects still run (the joy of web programming!)

Those projects were multi-week things, with pairs of students. This assignment has lower ambitions. But, if you want to learn more about flocking, it can be fun.

Walking Boids

As an initial step, we’ll keep a collection of objects. Each one has a position, and a velocity. Unlike in previous workbooks, we will create this using an actual JavaScript class. The code is in 04-05-01.js - you will do this exercise by changing this file (and possibly 04-05-01.html). We will provide you with some help understanding the JavaScript objects - see Traditional Object Oriented Programming in JavaScript.

Throughout this assignment, we’ll maintain that each object (1) stays within the Canvas, and (2) has a constant speed (the magnitude of the velocity vector should remain constant). We’ll do this by making the velocity vector always be a unit vector. Note: the real speed of movement will depend on the browser’s redraw speed, so it might not actually be constant. It should be close enough.

Right now, this is really simple. The initial boids just fly straight and wrap around. But you can make it cooler.

These changes are for “basic points” - we recommend that you do them order as they are designed to help you learn the code. The rubric (bottom of the page) tells you how many points each is worth.

  1. Change the “Add” button so that when it is clicked, 10 new boids are placed at random locations with random directions. Remember, the velocity vectors must have unit magnitude.
  2. Change the “Clear” button so that when it is clicked, all the boids are removed. This will be useful for starting over.
  3. Change things so that the boids are not drawn just as circles or squares. The objects should point in the direction they are going. You could add a marker to the circles, or change the shape to a triangle (that points in the direction of the velocity), or something fancier.
  4. Right now, the objects “wrap around” when they hit the edge. Change it so they “bounce” off the edge instead. So, for example, when an object hits the right edge, its velocity changes to that its moving to the left instead. If it hits a side wall, only the horizontal component of the velocity needs to change. Hint: while technically the “collision” happens in the middle of the step, it is OK to treat it as if it happens at the beginning of the step. That is, you can check if a Boid would go off the screen in the next step and change it’s direction before it takes that step. And if a Boid does go off screen, you can move it back to the edge and change its direction.
  5. Objects bounce when they collide. When two boids hit (see 5 above), they change direction. Remember: the velocities stay constant. You don’t need to get the physics exact (since we’re maintaining velocities) - a simple version is to draw a line between the center of the two objects, and have the objects move away from each other in the directions of the line. This should go into the steer method of the boids.
  6. After a boid hits something, it changes color briefly. For example, it turns red after hitting something. They should stay the “alternate” color for a few frames. One type of collision is when they hit a wall. You also get points for having them change color when they hit another boid. For checking collisions between boids, it is OK to treat the boids as small circles or squares - rather than checking for collisions between complex shapes (which is much harder).

NEW requirements for 2024 Now, let’s make these boids/ants/spiders walk:

  1. Add at least 4 legs (6 legs for ants, 8 legs for spiders) to the boids. A leg can just be one rectangle or two connected rectangles.
  2. The legs should be moving while the boids are moving. They can just rotate like the propellers on the quadcopters, but if you do that you will not get points for the next item.
  3. The legs should be moving in a way that resembles walking ants or spiders: they should be rotating in a symmetric way and the rotation angle should be clamped between two numbers (i.e. not 360-degree rotations). More realistic movement can earn advanced points.
  4. The movement should involve some randomness, for example, make a small random change in direction, while maintaining velocity, every few frames. The changes should not be too frequent and the random change in direction should not be too large.

The remaining features are for advanced points. Implement as many (or as few) as you like. See the rubric for the number of points for each item. You must list and explain the advanced points you believe you have implemented in the text file in the last page ( 04-workbook.txt).

  1. Add obstacles to the scene. You could put shapes into the Canvas (circles or rectangles are good enough), and have the boids stay outside of these regions. This means you need to have the boids collide with the edges (just as they do with the boundaries of the Canvas). You also need to make sure your method for randomly placing boids doesn’t put things inside the shapes.

  2. Implement “steering” behaviors (outlined below). They are implemented by having a boid on each step make a small adjustment to its direction vector. These decisions are completely local: there is no planning (it only decides what to do immediately), there is no central decision making (each boid decides on its own), and the boid can only make small changes to its direction (it keeps its velocity and cannot turn too sharply). Despite the fact that these steering behaviors are so limited, interesting effects (like flock formation) can emerge. All of these can be added to the steer method of the Boids.

    Note that you get some points for getting “some steering to create interesting behavior” - you will get this from picking some of the things on the list below, and getting them so they provide some decent looking behavior (grader’s discretion). If you implement steering behaviors, list them in the 04-05-01.txt file. You will also get advanced points for each steering behavior that you (1) describe in the txt file and (2) the grader thinks it looks like it works.

    We aren’t telling you how to do steering (like cohesion)… if you want to figure it out you will need to look at the hints and the references.

Steering Behaviors for Advanced Points

The steering behaviors are detailed in the references, but past students have made really cool things based just on these descriptions and some experimentation.

The steering behaviors have the boids look at their “neighbors” (other boids within a radius) and adjusting their direction based on what they see.

  • Implement “alignment” steering. On each step, the boid looks at the other nearby Boids and turns to go in the same direction as the average. This works best if the average is weighted (nearby ones have more weight).
  • Implement “separation” steering. On each step, the boid tries to turn away from its neighbors to avoid hitting them.
  • Implement “cohesion” steering. On each step, the boid looks at its neighbors and tries to steer to be in the middle of them.
  • Mouse attraction - have boids turn towards the mouse. They should turn gradually (there should be a limit to how fast they turn).
  • Implement some other steering behavior based on some of the references above.

The steering behaviors require tweaking - you need to tune the parameters to get them to work well. Try it with the old demo. You will probably want to add sliders to help you experiment with the parameters. For example, in my testing (to try out the assignment), we limited the turning to 1 or 2 degrees per step. Also, the steering behaviors are most interesting when you combine different ones (e.g., alignment and separation).

If you implement steering behaviors you can add sliders to tune them - but have the default values for the sliders be set to things that look nice. Being able to switch off a steering behavior (or set its strength to 0) using a slider or checkbox is a good way to test things (and helps us check that things work).

Note that the behaviors “count twice” in the scoring scheme. For example, if you correctly implement alignment or separation, you will get the points for “alignment” but also “Visually obvious flocking behavior” (assuming it is visually obvious - which it should be). You can get the “visually obvious” points only once (see rubric).

You should do this exercise by editing 04-05-01.html and 04-05-01.js. The graders will look at these files.

Box 04-05-01 Rubric (39 points total)
Points (23):
Box 04-05-01
3 pt
boids - add 10 boids when button is clicked, random locations and directions (but all with the correct speed)
Box 04-05-01
2 pt
boids - clear when button is clicked
Box 04-05-01
3 pt
draw boids so the direction they are facing is clear
Box 04-05-01
3 pt
boids bounce, not wrap
Box 04-05-01
2 pt
boids change color (briefly) when they hit a wall
Box 04-05-01
2 pt
boids bounce off each other
Box 04-05-01
2 pt
boids change color (briefly) when they hit another boid (either overlap or come very close)
Box 04-05-01
1 pt
boids has at least 4 legs like ants or spiders
Box 04-05-01
1 pt
boids has legs that move while they move
Box 04-05-01
2 pt
boids has legs that move in a way that resembles walking (not like the propellers of the quadcopters)
Box 04-05-01
2 pt
boids randomly make infrequent small changes in direction while walking (and maintain velocity)
Advanced points (16):
Box 04-05-01
2 pt
cool or more realistic movements of the legs
Box 04-05-01
2 pt
boids bounce off obstacles
Box 04-05-01
2 pt
visually obvious flocking behavior (alignment, separation, cohesion)
Box 04-05-01
2 pt
alignment flocking behavior (adds to `visually obvious')
Box 04-05-01
2 pt
separation flocking behavior (adds to `visually obvious')
Box 04-05-01
2 pt
cohesion flocking behavior (adds to `visually obvious')
Box 04-05-01
2 pt
mouse attraction flocking behavior (adds to `visually obvious')
Box 04-05-01
2 pt
added slider or checkbox that alters steering behavior
Hints
  1. Do the required changes in the order suggested. This will help you learn the code.
  2. Read the references on Craig Reynold’s pages for ideas on how to do steering. Craig Reynolds Steering Behavior is an advanced article (that includes the basic ideas).
  3. Many of the steering behaviors are easier if you represent the velocity as orientation, speed (rather than as x velocity, y velocity). You could change over all of the code. I found I was converting back and forth within the steer function. Math.atan2 is your friend (see the Mozilla atan2 documentation).
  4. When working with angles, be careful about wraparound! (angle + 360 degrees = angle)
  5. Be sure to document what you are trying to do so we appreciate what you did! (give a list of which requirements you did and which advanced things you did).
  6. You are allowed to change the starter code as much as you want (for example, to add or remove things from the constructor).
  7. You can use whatever canvas drawing commands (functions) you think are appropriate (you can use transform, rotate, translate and/or any of the others). There is no requirement that you use the transformation functions.
  8. To combine multiple steering behaviors, the standard approach is to blend them together (weighted addition). However, there are other things you can do as well.
Next: Hand-in and Gallery