# P2Matrix to turn around axis

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
But I don’t find the right way to code it. Results are always on the down of the screen.
Where’s my code :

``````PVector green, blue;
PMatrix2D matrix;
int angle = 60;
void setup() {
size(360, 360);
smooth();
green = new PVector(0, 0);
blue = new PVector(0, 0);
}
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

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 within the PVector class that can be used to rotate a vector while maintaining its magnitude.

1 Like

Hello,

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

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

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

void setup()
{
size(360, 360);
smooth();
green = new PVector(200, 0); //source
blue = new PVector(0, 0);    //target
matrix = new PMatrix2D();
}

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.mult(green, blue);
}
`````` 1 Like

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 :

``````PVector green, blue;
PMatrix2D matrix;
int angle = -30;
void setup(){
size(360, 360);
smooth();
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.mult(green, blue);
}
``````

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

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 and preApply. The matrix that calls `apply` is the left operand; `preApply`, the right.

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

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

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? Animated Gif

``````// 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.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);
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

2 Likes

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

1 Like