2

New to programming, for one of my first projects I am following a code for a boid simulation and I am unsure what the sin and cos functions are doing in this part of the code.

N = numer of boids

angles = 2*math.pi*np.random.rand(N)

vel = np.array(list(zip(np.sin(angles), np.cos(angles))))

In a general the code is setting up random vectors for the boids, but why are random angles on their own not sufficient?

What are the sin and cos functions doing which is important for the definition of unit velocity?

Does it provide a terms of reference for the individually calculated boid velocities?

2 Answers2

2

TL;DR

angles are an array of random directions. cos and sin decompose unit vectors pointing along these directions into their x and y components.

Longer explanation

This snippet initializes N unit velocity vectors pointing in random directions. The most logical (and easiest) way to do this is to

  1. initialize N random angles uniformly distributed between 0 and 2π, and
  2. for each angle theta, convert the unit vector (1, theta) from polar coordinates to Cartesian coordinates, for which the conversion is

    x = cos(theta)
    y = sin(theta)
    

Step 1. is accomplished with

angles = 2 * math.pi * np.random.rand(N)

Step 2. can be decomposed into

# arrays of x- and y-coordinates
velx = np.cos(angles)
vely = np.sin(angles)

# create (x, y) pairs and convert to np.array
vel = np.array(list(zip(velx, vely)))

Note that in your code, np.sin(angles) is used as the x-coordinate, which isn't strictly correct, but it doesn't matter since the angles are random and uniform anyway.


Just FYI, another way to create the (x, y) pairs is

vel = np.vstack([velx, vely]).T

This is much faster since it deals exclusively with Numpy objects, without the intermediate Python list.


Edit

To elaborate on my point regarding using sin and cos for x and y, here is a picture.

sin vs. cos

The top row shows velocity vectors for small angles (0 < theta < π / 4), in which case swapping sin and cos makes a difference, and you have to be careful to keep track of how you want to measure the angle.

The bottom row shows velocity vectors for uniformly random angles, where swapping the coordinates leaves the result looking pretty similar.

Igor Raush
  • 15,080
  • 1
  • 34
  • 55
  • You mentioned that strictly speaking np.sin(angles) used as the x-coordinate is not correct. What would be correct? –  Apr 22 '16 at 18:00
  • `np.cos(angles)` is the "proper" x-coordinate. This is assuming your angles are measured counter-clockwise from the horizontal. For your purposes, it doesn't matter where the angles are measured from, since you are just looking to initialize random directions. – Igor Raush Apr 22 '16 at 18:04
  • Could both be calculated with cos as they are independent series before being paired? –  Apr 22 '16 at 18:25
  • Please ignore above comment, does your comment equally apply to y as it does to x? I.e. the code reverses the relationship of sin and cos? –  Apr 22 '16 at 18:34
  • If you used `cos` for both, you wouldn't get unit vectors. – Igor Raush Apr 22 '16 at 18:34
  • If you use `sin` for the x-coordinate and `cos` for the y-coordinate, your angles will be interpreted as measuring clockwise from the vertical rather than counter-clockwise from the horizontal. The latter is the standard interpretation of directional angles, but for your use case it makes no difference. – Igor Raush Apr 22 '16 at 18:48
0

In this case, the velocity is not just the (scalar) speed. It is a vector, so that it describes both the direction and the speed. The actual speed in units/sec is then the length of the velocity vector.

It seems that in this code (that is similar to the example implementation here) the initial velocity of each Boid is 1, even though they're headed in every possible direction.

The same happens in this implementation in Processing.