# P2Matrix to turn around axis

**URL:** <https://discourse.processing.org/t/p2matrix-to-turn-around-axis/17031>\
**Category:** Coding Questions\
**Created:** [January 11, 2020, 4:25pm UTC](https://discourse.processing.org/t/p2matrix-to-turn-around-axis/17031 "2020-01-11T16:25:26Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![matheplica](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/matheplica/32/21035_2.png) [@matheplica](https://discourse.processing.org/u/matheplica)\
**Post date:** [January 11, 2020, 4:25pm UTC](https://discourse.processing.org/t/p2matrix-to-turn-around-axis/17031/1 "2020-01-11T16:25:26Z")

</div>

Hi, I’m trying to turn a PVector to 60 degree with a PMatrix2D.  
I found this formula : [https://en.wikipedia.org/wiki/Rotation\_matrix](https://en.wikipedia.org/wiki/Rotation_matrix)  
But I don’t find the right way to code it. Results are always on the down of the screen.  
Where’s my code :

```auto
PVector green, blue;
PMatrix2D matrix;
int angle = 60;
float rad;
void setup() {
  size(360, 360);
  smooth();
  rad = radians(angle);
  green = new PVector(0, 0);
  blue = new PVector(0, 0);
  matrix = new PMatrix2D(cos(rad), -sin(rad), sin(rad), cos(rad), 0, 1);
}
void draw() {
  background(144);
  scale(width, height);
  noStroke();
  fill(10, 205, 60);
  ellipse(green.x, green.y, 0.1, 0.1);
  fill(10, 60, 205);
  ellipse(blue.x, blue.y, 0.1, 0.1);
}
void keyPressed() {
  matrix.mult(green, blue);
}

```

Thanks

---

<div class="post-metadata">

**Author:** ![hotfooted](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hotfooted/32/3670_2.png) [@hotfooted](https://discourse.processing.org/u/hotfooted)\
**Post date:** [January 11, 2020, 9:47pm UTC](https://discourse.processing.org/t/p2matrix-to-turn-around-axis/17031/2 "2020-01-11T21:47:07Z")

</div>

i haven’t run your code but it seems you don’t apply the matrix anywhere. you would need to push/pop a matrix transform. anyways i just wanted to point out there is a [rotate method](https://processing.org/reference/PVector_rotate_.html) within the PVector class that can be used to rotate a vector while maintaining its magnitude.

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [January 12, 2020, 4:00am UTC](https://discourse.processing.org/t/p2matrix-to-turn-around-axis/17031/3 "2020-01-12T04:00:29Z")

</div>

Hello,

Your matrix should be:

```auto
  matrix = new PMatrix2D(cos(rad), -sin(rad), 0, 
                         sin(rad), cos(rad), 1);

```

Modified your code and rotates in 60 deg increments if key pressed:

```auto
PVector green, blue;
PMatrix2D matrix;
int angle = 60;
float rad;

void setup() 
  {
  size(360, 360);
  smooth();
  rad = radians(angle);
  green = new PVector(200, 0); //source
  blue = new PVector(0, 0); //target
  matrix = new PMatrix2D();
  //matrix.set(cos(rad), -sin(rad), 0, 
  // sin(rad), cos(rad), 1);
  }

void draw() 
  {
  background(144);
  translate(width/2, height/2);
  noStroke();
  strokeWeight(3);
  fill(10, 205, 60);
  stroke(10, 205, 60);
  line(0, 0, green.x, green.y);
  noStroke();
  ellipse(green.x, green.y, 10, 10);
  fill(10, 60, 205);
  stroke(10, 60, 205);
  line(0, 0, blue.x, blue.y);
  noStroke();
  ellipse(blue.x, blue.y, 10, 10);
  }

void keyPressed()
  {
  matrix.set(cos(rad), -sin(rad), 0, 
             sin(rad), cos(rad), 1);
  matrix.mult(green, blue);
  rad += TAU/6; //TAU/6 rad = TWO_PI/6 rad = 60 deg
  }

```

🙂

---

<div class="post-metadata">

**Author:** ![matheplica](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/matheplica/32/21035_2.png) [@matheplica](https://discourse.processing.org/u/matheplica)\
**Post date:** [January 13, 2020, 9:02am UTC](https://discourse.processing.org/t/p2matrix-to-turn-around-axis/17031/4 "2020-01-13T09:02:54Z")

</div>

Ok, acutally we are close to the solution but I need to use scale(width, height);  
This code is a pre-test to use with a texture on a triangle where value are normalized.  
I try this without sucess :

```auto
PVector green, blue;
PMatrix2D matrix;
int angle = -30;
float rad;
void setup(){
  size(360, 360);
  smooth();
  rad = radians(angle);
  green = new PVector(0.5, 0.5); //source
  blue = new PVector(0.8, 0.5); //target
  matrix = new PMatrix2D();
}
void draw() {
  background(144);
  scale(width, height);
  noStroke();
  fill(10, 205, 60);
  ellipse(green.x, green.y, 0.10, 0.10);
  fill(10, 60, 205);
  noStroke();
  ellipse(blue.x, blue.y, 0.10, 0.10);
}
void keyPressed() {
  matrix.set(cos(rad), -sin(rad), 0.5*(1-cos(rad))+0.5*(sin(rad)), 
    sin(rad), cos(rad), 0.5*(1-cos(rad))-0.5*(sin(rad)));//to turn around center
  matrix.mult(green, blue);
  rad -= TAU/6; //TAU/6 rad = TWO_PI/6 rad = 60 deg
}

```

---

<div class="post-metadata">

**Author:** ![matheplica](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/matheplica/32/21035_2.png) [@matheplica](https://discourse.processing.org/u/matheplica)\
**Post date:** [January 13, 2020, 5:51pm UTC](https://discourse.processing.org/t/p2matrix-to-turn-around-axis/17031/5 "2020-01-13T17:51:21Z")

</div>

I think I’m lost the way to write arguments in matrix.set( …).  
How to write to turn around 0.5 point ?

---

<div class="post-metadata">

**Author:** ![behreajj](https://avatars.discourse-cdn.com/v4/letter/b/b5a626/32.png) [@behreajj](https://discourse.processing.org/u/behreajj)\
**Post date:** [January 14, 2020, 11:47am UTC](https://discourse.processing.org/t/p2matrix-to-turn-around-axis/17031/6 "2020-01-14T11:47:47Z")

</div>

Hi @matheplica,

`PMatrix2D` is a 3 x 2 matrix in row-major order. The first column describes the right axis; the second, the up axis; the third column describes the translation. Transform matrices are usually described as square matrices, but the last row – 0.0, 0.0, 1.0 – is left out.

| m00: right axis x | m01: up axis x | m02: translation x |  
| m10: right axis y | m11: up axis y | m12: translation y |  
| 0.0 | 0.0 | 1.0 |

To combine a translation, rotation and scale matrices, you can use matrix multiplication. Matrix multiplication is not commutative, so there are two instance methods: [apply](https://github.com/processing/processing/blob/d6b30602a703e1d0280392c54794486ee34bca8c/core/src/processing/core/PMatrix2D.java#L273) and [preApply](https://github.com/processing/processing/blob/d6b30602a703e1d0280392c54794486ee34bca8c/core/src/processing/core/PMatrix2D.java#L328). The matrix that calls `apply` is the left operand; `preApply`, the right.

```auto
PMatrix2D t = new PMatrix2D();
PMatrix2D r = new PMatrix2D();
PMatrix2D s = new PMatrix2D();

t.translate(10.0, 20.0);
t.print();

r.rotate(radians(30.0));
r.print();

s.scale(40.0, 50.0);
s.print();

PMatrix2D m = new PMatrix2D();
m.apply(t);
m.apply(r);
m.apply(s);
m.print();

```

Just an opinion, but I imagine it’d be less confusing if you used only matrix operations – or only the renderer’s `translate`, `rotate` and `scale` – but not both.

As far as UV coordinates, are you looking to do something like this?

![0024](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/a/afa5be867747254e4d06601ffc290e7b49831687.png)  
[Animated Gif](https://giphy.com/gifs/XEy7od4E6OfXAjcdKc)

```auto
// Define triangle shape.
PVector a = new PVector(1.0, 0.0, 0.0);
PVector b = new PVector(-0.5, -0.86602545, 0.0);
PVector c = new PVector(-0.5, 0.86602545, 0.0);

// Define triangle uvs relative to real world coordinates.
PVector uvcenter = new PVector(0.5, 0.5);
PVector s = PVector.add(PVector.mult(a, 0.5), uvcenter);
PVector t = PVector.add(PVector.mult(b, 0.5), uvcenter);
PVector u = PVector.add(PVector.mult(c, 0.5), uvcenter);

// Create vectors to store uvs transformed by matrix.
PVector sp = new PVector();
PVector tp = new PVector();
PVector up = new PVector();

// A texture to use on the shape.
PImage txtr;

// Matrices to store the real world and uv transform.
PMatrix2D shapetr = new PMatrix2D();
PMatrix2D uvtr = new PMatrix2D();

void setup() {
  size(256, 256, P2D);
  noStroke();
  
  // Set uv coordinate range to [0.0, 1.0].
  // Specify that the texture will repeat when uv
  // coordinates exceed that range.
  textureWrap(REPEAT);
  textureMode(NORMAL);
  
  // To make the rotation easier to see, a very
  // small image is sampled with no smoothing.
  ((PGraphicsOpenGL)getGraphics()).textureSampling(2);
  txtr = rgb(16, 16);

  // Transform the shape.
  shapetr.translate(width * 0.5, height * 0.5);
  shapetr.rotate(radians(0.0));
  shapetr.scale(width * 0.485, height * 0.485);

  a = shapetr.mult(a, new PVector());
  b = shapetr.mult(b, new PVector());
  c = shapetr.mult(c, new PVector());
}

void draw() {

  // Animate the uv transform.
  uvtr.reset();
  uvtr.translate(0.5, 0.5);
  uvtr.rotate(frameCount * 0.03);
  uvtr.translate(-0.5, -0.5);

  // Apply the transform to the uv coords.
  uvtr.mult(s, sp);
  uvtr.mult(t, tp);
  uvtr.mult(u, up);

  // Display the shape.
  background(#fff7d5);
  beginShape(POLYGON);
  texture(txtr);
  vertex(a.x, a.y, sp.x, sp.y);
  vertex(b.x, b.y, tp.x, tp.y);
  vertex(c.x, c.y, up.x, up.y);
  endShape(CLOSE);
}

// Create a test image.
PImage rgb(int w, int h) {
  PImage result = createImage(w, h, ARGB);
  result.loadPixels();
  for (int i = 0, y = h - 1; y > -1; --y) {
    float gr = y * 255.0 / (h - 1);
    for (int x = 0; x < w; ++x, ++i) {
      float re = x * 255.0 / (w - 1);

      result.pixels[i] = color(
        re, gr, 127.0, 255.0);
    }
  }
  result.updatePixels();
  return result;
}

```

You can translate a matrix by the pivot, (0.5, 0.5), rotate, then shift back by translating with the negative pivot.

Hope that moves the ball forward,  
Jeremy

---

<div class="post-metadata">

**Author:** ![matheplica](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/matheplica/32/21035_2.png) [@matheplica](https://discourse.processing.org/u/matheplica)\
**Post date:** [January 14, 2020, 12:58pm UTC](https://discourse.processing.org/t/p2matrix-to-turn-around-axis/17031/7 "2020-01-14T12:58:47Z")

</div>

Ok Jeremy, thanks.  
I can continue now,  
hope to share one day my works but the road is long
