Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

deutsche Version

Processing

p5.js uses a Cartesian coordinate system. It is important to note that the zero , where the zero point is in the upper left corner in processing. The X axis is from left to right and the Y axis is from top to bottom. While this might seem odd, it comes from the tradition that bitmaps were always read in that order. In computer graphics the cartesian coordinate system is almost always used.

Image Added

In processing p5.js we can simplify the drawing of objects in many cases by assigning them their own local coordinate system.

Imagine an animation of a car moving across the screen. If you draw this in processing you could You can add a value to the the x and y coordinates for every detail of the car to move it across the screen. When it comes to the wheels, it would get complicated as we would not only change the position relative to the car, but also rotate every detail it in relation to the wheel axis! But if we

There are however ways to modify the coordinate systems this becomes a lot simpler. Such coordinate system changes are called transformationssystem, called transformations, which can make calculations much simpler. There are three basic types of such transformations:


Translation

...

/ Shifting  

translate(x, y, [z])

Rotation 

rotate(angle, [axis])


Scaling 

scale(s, [y], [z])

It should be noted that such transformations are not ARE NOT commutative. That means the order that you make the transformations will effect the output. In processing, the commands look like this:

translate(float x, float y)
rotate(float angle)
scale(float xScale, float yScale)

If  If you work in 3D mode, there is a the third parameter is used for the [z axis] axis


Frequently, local and global coordinate systems will be used. The global coordinate system is the original coordinate system, in processing p5.js this is the one fixed to the upper left corner. If the original coordinate system is transformed, then the result is local coordinate system (in reference to the global). To switch between these coordinate systems, there are two commands from Processing:

  • pushMatrix() – save the current coordinate system
  • popMatrix() – return to the last saved coordinate system

These two commands work according to the stack principle. This is an very old form of working with computer memory. Just imagine a stack of graph paper: when you call pushMatrix, the stack is increased by one sheet. On this page we would describe the current data of our coordinate system. Now you can rotate, scale and transform as you want. If you now want to bring the coordinate system back to the position of the last pushMatrix call, you must call popMatrix. push() and pop() store information related to the current transformation state and style settings.

With an example program, this should be easer easier to understand:

void
Code Block
languagejs
linenumberstrue
function setup()
{
  sizecreateCanvas(400,400);      // def.define window size
  strokeWeight(15);    // line thickness 
}
 
voidfunction draw()
{
  background(255);    // def.define background colour
  floatvar radius = dist(mouseX, mouseY, width/2, height/2);  // calculate the distance from the mouse curser to the center of the screen 
  radius = map(radius, 0, width, 1,4 3);                     // modify the radius to keep it within a specific range. 
 
  pushMatrixpush(); // begin a new drawing state
  translate(200,200);
    width/2,height/2); //make this the center point of coordinate system
  rotate(calcAngle());
    scale(radius);
 
  smiley();          // function call
  popMatrix();
 
  pushMatrix();
    translate(30,30);
    scale(.2);
    smileypop();          // restore functionthe calloriginal state
 popMatrix();
}

 //
funktion
voidfunction smiley()
{
  noFill();
  ellipse(0,0,180,180);  // head
 
  fill(0);
  ellipse(0 - 30,0 - 30,20,20);  // left eye
  ellipse(0 + 30,0 - 30,20,20);  // right eye
 
  noFill();
  arc(0,0,100,100,radians(20),radians(180-20));  // mouth
}
 
// calculate the angle from the screen middle to the mouse cursor
// the angle is in radians 
floatfunction calcAngle()
{
  return -atan2(mouseX - (width / 2),mouseY - (height / 2));
}

...

This example introduces a couple of new things starting on line 13:


float var radius = dist(mouseX, mouseY, width/2, height/2);

Here Calculates the distance from the mouse pointer to the window centre is determined (see Pythagoras).


var radius = map(radius, 0, width, 1, 43);

The original range is from 0 to the width of the window. The target range is from 1-43. Now radius is transformed from original range to the target range.


-atan2(mouseX - (width / 2), mouseY - (height / 2)); 

The atan2 function returns the angle in radians at a given coordinate from the 0 point. In this example we shift the 0 point to the centre of the screen in relation to the mouse position by subtracting width/2 from X mouseX and height/2 from YmouseY.

Image Modified

Image Credit: wikipedia

Exercise 8

Create a new program where a simple car follows the mouse on the screen from left to right. The car should be drawn from the side, and include wheels that rotate. You may use the example code to get started.


Code Block
languagejava
intvar rotation;
void
function setup()
{
  sizecreateCanvas(900, 400);      // def. window size
  stroke(0);
  strokeWidth(2);
}
 
voidfunction draw()
{
  rotation++;
}
 
voidfunction cardrawCar(int x, int y) {
  fill(100);

  beginShape();
  vertex(0, 0);
  vertex(5, -50);
  vertex(50, -50);
  vertex(70, -80);
  vertex(150, -80);
  vertex(190, -50);
  vertex(265, -45);
  vertex(270, 0);
  vertex(0, 0);
  endShape();

  wheeldrawWheel(60, 0);
  wheeldrawWheel(210, 0);
}
 
voidfunction wheeldrawWheel(int x, int y) {
  intlet radius = 25;
  fill(150);
  stroke(0);
  strokeWeight(7);
  ellipse(0, 0, radius*2, radius*2);
  strokeWeight(4);
  line(0-radius, 0, 0+radius, 0);
  line (0, 0-radius, 0, 0+radius);
  noStroke();
}

...

Possible Solution: 

Code Block
languagejavajs
titleSolution to exercise
linenumberstrue
collapsetrue
intvar rotation;
boolean forward = true;
int var xScale = 1;

voidfunction setup()
{
  sizecreateCanvas(900, 400);
}

voidfunction draw() {
  background(255);
  int
  var mouseMovement = mouseX - pmouseX; //pmousex gives us our mouse x value from the last frame. Subtracting from the current position give us the distance moved per frame
  if (mouseMovement<0) { // if the movement is negative, then we flip everthing backwards with a negative xcale
    xScale = -1;
  }
  if (mouseMovement>0) { // if the movement is positive, then our xscale is positive
    xScale = 1;
  }
  
  rotation += abs(mouseMovement);
  cardrawCar(mouseX, height/2);
  
  
}

voidfunction cardrawCar(int x, int y) {
  
  pushMatrixpush();
      translate(x, y);
      scale(xScale, 1);
      fill(100);
      beginShape();
      vertex(0, 0);
      vertex(5, -50);
      vertex(50, -50);
      vertex(70, -80);
      vertex(150, -80);
      vertex(190, -50);
      vertex(265, -45);
      vertex(270, 0);
      vertex(0, 0);
      endShape();
      wheeldrawWheel(60, 0);
      wheeldrawWheel(210, 0);
  popMatrixpop();
}

voidfunction wheeldrawWheel(int x, int y) {
  intlet radius = 25;
  fill(150);
  stroke(0);
  
pushMatrix  push();
  translate(x, y);
  rotate(radians(rotationmouseX));
  
  strokeWeight(7);
  ellipse(0, 0, radius*2, radius*2);
  strokeWeight(4);
  line(0-radius, 0, 0+radius, 0);
  line (0, 0-radius, 0, 0+radius);
  noStroke();
  popMatrixpop();
  
}