It turns out there already is a library that does the same thing. But only for the mouse position afaik. Also it has scaling as well, but not shear transforms (different scales for X and Y didn’t work too well though). It’s called “mouse 2D transformations” and can be installed from the Contributions Manager.
Here’s my test sketch changed to use that instead (just for completeness sake).
import mouse.transformed2D.*;
// mouse clicks make a test point that follows the following matrix "level"
final int testPointAtLevel = 2; // zero-based
// To track mouse coordinates in transformed matrices
MouseTransformed mouse = new MouseTransformed(this);
// Matrix transforms push/pop levels
final int levels = 3;
// Test figure, to show matrix transforms (translations / rotations)
TestFigure testFig[] = new TestFigure[levels];
// Initial test point coordinates
float tpx = 15;
float tpy = 20;
void setup() {
// test figures
testFig[0] = new TestFigure( 300, 300, 0, 0, 50, 100, 0, 0.01 );
testFig[1] = new TestFigure( 200, 0, 0, 0, 25, 50, 0, 0.02 );
testFig[2] = new TestFigure( 50, 50, -10, 20, 25, 10, 0, 0.015 );
//testFig[3] = new TestFigure( 25, -25, 0, 0, 20, 10, 0, 0.03);
size(600, 600);
ellipseMode(RADIUS);
}
void draw() {
background(128);
fill(255);
for(int i=0; i<levels; i++) {
stroke(0);
strokeWeight(1);
// track a new matrix transform
mouse.pushMatrix();
// transform current matrix
mouse.translate(testFig[i].x, testFig[i].y);
mouse.rotate(testFig[i].ang);
mouse.scale(1.1, 1.1);
// Indicate a matrix "level" with a figure
testFig[i].display();
testFig[i].update();
// Test point that follows a matrix
if (testPointAtLevel == i) testPoint();
}
// remove old matrix transforms before new frame
for (int i=0; i<levels; i++) {
mouse.popMatrix();
}
}
// Mouse click makes a point that follows current "level" of matrix transforms
void testPoint() {
if (mousePressed) {
tpx = mouse.mouseX(); // reverse screenX
tpy = mouse.mouseY(); // reverse screenY
}
strokeWeight(3);
stroke(#FF0000);
point(tpx, tpy);
}
// Test figure class, to show matrix transforms and rotations
class TestFigure {
float x, y; // x, y center position (matrix translation)
float xt, yt; // x, y additional offset
float ra, rb; // radius A and B (of figure)
float ang; // angle
float turnSpeed;
TestFigure( float ex, float ey, float ext, float eyt,
float era, float erb, float angle, float ts) {
x = ex;
y = ey;
xt = ext;
yt = eyt;
ra = era;
rb = erb;
ang = angle;
turnSpeed = ts;
}
void display() {
// Draw around offset from wherever origo (of matrix) is
ellipse(xt, yt, ra, rb);
//rect(xt-ra, yt-rb, 2*ra, 2*rb);
}
void update() {
ang += turnSpeed;
}
}