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.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?
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.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