Processing Maths Related Questions

Before I begin I'd like to say that I submitted this post one day ago on the Processing forum but have not received a reply. The code is of a Java based framework called Processing and my problem is mainly with how the maths works in the class. Hopefully someone here will be able to help explain it to me.

---

The code below is taken from my programming course. It is the full program. The program is of a ship that you can move around and rotate, changing the direction of movement, based on keyboard input.

I have a few questions about the class Ship.

Why does the PVector velocity have values of (0, -1)?

Why is velocity.x assigned sin(theta) and why is velocity.y assigned -cos(theta)?

My understanding of trigonometry is a bit rough, but I thought that to find a point to rotate to (the x and y coordinates), relative to the origin of the object you are rotating, you had to multiply the trigonometry functions by the radius of the object. Here, however that does not seem to be the case.

Why do you need to translate by position.x and position.y?

How does rotate(theta) work?

I am not entirely clear on how everything else works, but these are the main things I don't understand. I hope that by understanding these key points the rest will fall into place.

Thank you for your help, it's much appreciated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Ship ship;
 
void setup()
{
  size(800, 800);
 
  ship = new Ship();
}
 
void draw()
{
  background(0);
 
  ship.update();
  ship.render();
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class Ship
{
  PVector position;
  PVector velocity;
  float shipWidth;
  float theta;
 
  Ship()
  {
    // Constructor Chaining
    this(width / 2, height / 2, 50);
  }
 
  Ship(float x, float y, float w)
  {
    position = new PVector(x, y);
    velocity = new PVector(0, -1);
    shipWidth = w;
    theta = 0.0f;
  }
 
  void update()
  {
    velocity.x = sin(theta);
    velocity.y = -cos(theta);
 
    velocity.mult(5);
 
    if(keyPressed)
    {
      if(key == CODED)
      {
        if(keyCode == UP)
        { 
          position.add(velocity);
        }
 
        if(keyCode == LEFT)
        {
          theta -= 0.1f;
        }
 
        if(keyCode == RIGHT)
        {
          theta += 0.1f;
        }
      }
    }
  }
 
  void render()
  {
    stroke(255);
    pushMatrix();
    translate(position.x, position.y);
    rotate(theta);
    line(-shipWidth / 2, shipWidth / 2, 0, -shipWidth / 2);
    line(shipWidth / 2, shipWidth / 2, 0, -shipWidth / 2);
    line(0, 0, shipWidth / 2, shipWidth / 2);
    line(0, 0, -shipWidth / 2, shipWidth / 2);
    popMatrix();
  }
}
Why does the PVector velocity have values of (0, -1)?

It has to start out with some value. Why not that one?

Why is velocity.x assigned sin(theta) and why is velocity.y assigned -cos(theta)?

So velocity is affected by the orientation of the ship.

My understanding of trigonometry is a bit rough, but I thought that to find a point to rotate to (the x and y coordinates), relative to the origin of the object you are rotating, you had to multiply the trigonometry functions by the radius of the object.

This is calculating velocity. Not "finding a point to rotate to."

Why do you need to translate by position.x and position.y?

If you don't, you'll always be drawing to the same space?

Why does the PVector velocity have values of (0, -1)?

It has to start out with some value. Why not that one?

Initially this makes sense as with position.add(velocity), you are adding the PVector velocity to position which means position.y decrements by 1, thus moving the ship upwards along the y axis. Where this stops making sense is when you rotate the angle at which the ship is pointing around its own axis. If the ship is pointing down for example and you press UP, how does the ship move downwards if you are taking away from the y axis?

I think that with pushMatrix and popMatrix, you are limiting the scope of rotation to the width of the ship. Could it be that when you rotate the ship you are actually rotating the axis on which it sits? So that when the ship is pointing left, the y axis has revolved counter clockwise to the left also?


This is calculating velocity. Not "finding a point to rotate to."

I don't understand this.

In my course, whenever we have utilised the trig functions it has been to find an x and a y coordinate to draw to based on an angle (theta) multiplied by a radius. In this program however, no radius is included in the calculation. Why?


If you don't, you'll always be drawing to the same space?

I think I get that. Continuously translating to the newly updated position of the ship ensures that the center point of the ship remains the origin of translation, and so the lines continue to be drawn to the new positions rather than a fixed position like the middle of the screen. Is that right?

Thanks for taking the time to help me with this by the way. Maths is not my strongest point, but I try to improve bit by bit.
Initially this makes sense as with position.add(velocity), you are adding the PVector velocity to position which means position.y decrements by 1, thus moving the ship upwards along the y axis.
Initially is the only place this happens as the code in question is only executed when the object is created. [Edit: Note that the value it is initialized to is completely irrelevant because it is always assigned another value before it is used.]


If the ship is pointing down for example and you press UP, how does the ship move downwards if you are taking away from the y axis?

The velocity, which is calculated based on the ships rotation or orientation, is added to the position in the update function.


I think that with pushMatrix and popMatrix, you are limiting the scope of rotation to the width of the ship.

You are limiting the scope of the translation/rotation transformations to betwixt the two. It doesn't have anything to do with the width of the ship.


Could it be that when you rotate the ship you are actually rotating the axis on which it sits? So that when the ship is pointing left, the y axis has revolved counter clockwise to the left also?

No.


In my course, whenever we have utilised the trig functions it has been to find an x and a y coordinate to draw to based on an angle (theta) multiplied by a radius. In this program however, no radius is included in the calculation. Why?

The program is not finding an x and y coordinate to draw to. It is calculating the velocity based on the orientation (or rotation) of the ship.


think I get that. Continuously translating to the newly updated position of the ship ensures that the center point of the ship remains the origin of translation, and so the lines continue to be drawn to the new positions rather than a fixed position like the middle of the screen. Is that right?

That's a reasonable way to think of it, yes.
Last edited on
1
2
velocity.x = sin(theta);
velocity.y = -cos(theta);

I think my main problem revolves around these two lines. I don't understand how they work or what exactly they do.

Okay, so when velocity = (0, -1), sin(0) makes velocity.x = 0 and -cos(0) makes velocity.y = -1. This is added to position making position = (x, y - 1), moving the ship up.

When you press LEFT or RIGHT, you change theta (so it's no longer 0). Let's say you press RIGHT, making theta 0.5. sin(0.5) is some long positive decimal number less than 1 and so is cos(0.5), however the minus turns it negative.
This added to position makes position = (x + num, y - num), moving the ship RIGHT and UP.

As you change the value of theta, various positive and negative values are added to position, making the ship move around the screen.

That's kind of as much as I know, and it could be wrong. Why do the trig functions need to be used? Why can't you calculate velocity.x and y based on just theta? This really is the main thing, how do the trig functions work and why are they necessary?
Why do the trig functions need to be used? Why can't you calculate velocity.x and y based on just theta? This really is the main thing, how do the trig functions work and why are they necessary?


Given a position and an angle, can you work out the slope of the line the ship would folllow and the position the ship would be at if it traveled exactly one unit?

sine is length of opposite side/length of hypotenuse and
cosine is length of adjacent side /length of hypotenuse

We could solve for the x and y distances using the Pythagorean theorem (but we don't have another point on the line, do we?) However, we do know the distance we want to travel is one and when the length of the hypotenuse is 1, the sine is the length of the opposite side, and the cosine is the length of the adjacent side. So, the slope is sin theta / cos theta.. except, for some reason they've decided that a theta of 0 is facing up which should be an angle of pi/2 radians, not 0. So the slope should be inverted (cos theta/sin theta.) And the y velocity should be negated to account for the flipped y-axis.

Which makes -cos theta the change in y and sin theta the change in x.. hello, velocity. Of course, the actual distance traveled is 5, which is what that multiplier is doing in the update function.
Last edited on
I think I understand a bit better now.

My confusion is cleared up as to why no hypotenuse/radius is being incorporated into the trig calculations. It's because we are basing these calculations on the unit circle and so the radius is 1. Anything multiplied by 1 is just itself, hence the radius is unnecessary.

As for the trig functions, well I ran a few sums through the calculator and that's given me a clearer idea of what they do.

For example, I tried sin(45) and -cos(45), which gave back the values 0.707 and -0.707, respectively. What this equates to when velocity is added to position is that the position moves slightly forward on the x axis and slightly upward on the y axis.

Other calcs:
sin(315), -cos(315) = (-0.707, -0.707) = LEFT and UP equally
sin(180), -cos(180) = (0, 1) = straight DOWN
sin(200), -cos(200) = (-0.342, 0.939) = LEFT slightly and DOWN
sin(70), -cos(70) = (0.939, -0.342) = RIGHT and slightly UP

Anyway, you get the idea. It still seems like magic to me, I don't know how the underlying mechanics work, but at least I have a better idea as to why the trig functions are necessary. They always give you a perfect distance to move by based on a given angle.

I also understand now that the physical rotation of the lines you see on the screen has nothing to do with the trig functions. It is solely based on how much the screen is rotated, which is based on an angle, which just so happens to be the theta used to determine the distance moved.

Do I have that right, or am I missing anything?

Also, it's kind of strange in this case that sin is used to give you the x value and cos is used to give the y value, as on the processing website it's the other way around. I tried switching them around in the program but the movement became messed up. Do you know why they are implemented the way they are and why changing them doesn't work?
Bogeyman wrote:
Also, it's kind of strange in this case that sin is used to give you the x value and cos is used to give the y value, as on the processing website it's the other way around. I tried switching them around in the program but the movement became messed up. Do you know why they are implemented the way they are and why changing them doesn't work?


The author of that code is arbitarily treating a theta of 0 as pointing in the direction one would normally associate with 90 degrees (pi/2 radians). I mentioned it in the previous post.
Hey cire, just letting you know that I managed to get help from the lecturer so everything is cleared up now. Thank you very much for all your help.
Topic archived. No new replies allowed.