/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.eWd$AyVnMAf/rev.767
*
* authors:
*
* Wolfe
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
/* @pjs preload="favicon.ico,/static/uploaded_resources/p.467/poppy.png"; */
// Mathematically rotating image pixel by pixel
// this is one of my "What happens if..."
// left / A >> rotate by center to left
// right / D >> rotate by center to right
// if pressed mouse button rotate whole image around mouse cursor
// mouse drag >> move image (translate)
// up / W >> scale - zoom in
// down / S >> scale - zoom out
// in zooming in you can see
// space >> swap image between "big" (cannon fodder) poppy (slow for js)
// and tiny sketchpad.cc logo (faster rotating)
PImage img;
ArrayList pixs;
float totalScale=1;
boolean imgSwap = true;
float totalX, totalY;
PVector lsUp = new PVector (0,1);
PVector lsRight = new PVector (1,0);
void setup() {
size(600, 400);
totalX=width/2;
totalY=height/2;
if (imgSwap) img = loadImage("favicon.ico");
else img = loadImage("/static/uploaded_resources/p.467/poppy.png");
//img = loadImage("pics/poppy.png");
pixs = new ArrayList();
for (int x = 0; x<img.width; x++) {
for (int y = 0; y<img.width; y++) {
pixs.add(new Pixel(x+width/2-img.width/2, y+height/2-img.height/2, img.get(x, y)));
}
}
imgSwap = !imgSwap;
}
/////////////////////////////////
void draw() {
// image(img, width/2-img.width/2, height/2-img.height/2);
if (imgSwap) background(0);
else background(255);
for (int i = pixs.size()-1; i >= 0; i--) {
Pixel pixel = (Pixel) pixs.get(i);
//pixel.paint(width/2-img.width/2, height/2-img.height/2);
pixel.paint();
}
}
void rotateLocalSpace(float anchorX, float anchorY, float angle){
PVector tempUp = lsUp.get();
PVector tempRight = lsRight.get();
angle = radians(angle);
lsUp.x = tempUp.x * cos(angle) - tempUp.y * sin(angle);
lsUp.y = tempUp.x * sin(angle) + tempUp.y * cos(angle);
lsRight.x = tempRight.x * cos(angle) - tempRight.y * sin(angle);
lsRight.y = tempRight.x * sin(angle) + tempRight.y * cos(angle);
}
/////////////// CLASS //////////////
class Pixel {
float x, y, angl, scal;
int clr;
Pixel(float _x, float _y, int _clr) {
x = _x;
y = _y;
clr = _clr;
}
void paint() {
paint(0, 0);
}
///////////
void paint(int _x, int _y) {
pushStyle();
fill(clr);
stroke(clr);
rectMode(CENTER);
if (clr != 0) rect(x+_x, y+_y, 1, 1);
popStyle();
}
///////////
void rotate(float anchorX, float anchorY, float angle) {
float rotX, rotY, origX, origY;
PVector temp = new PVector(x - anchorX,y - anchorY);
origX = rotX = x - anchorX;
origY = rotY = y - anchorY;
x -= rotX;
y -= rotY;
angle = radians(angle);
rotX = origX * cos(angle) - origY * sin(angle);
rotY = origX * sin(angle) + origY * cos(angle);
x += rotX; // get it back to absolute position on screen
y += rotY;
}
///////////
void translate(float newX, float newY) {
x += newX;
y += newY;
}
void scale(float scaleX, float scaleY) {
// x = x - width/2;
// y = y - height/2;
x = x - totalX;
y = y - totalY;
x *= scaleX;
y *= scaleY;
x = x + totalX;
y = y + totalY;
// x = x + width/2;
// y = y + height/2;
}
}
////////////////////////////////////////////////////
void keyPressed() {
float rotAmount = 10;
float scaleAmount = 1.05;
switch (keyCode) {
case RIGHT:
case 68:
for (int i = pixs.size()-1; i >= 0; i--) {
Pixel pixel = (Pixel) pixs.get(i);
if (mousePressed) pixel.rotate(mouseX, mouseY, rotAmount);
else pixel.rotate(totalX, totalY, rotAmount);
}
if (mousePressed) rotate(mouseX, mouseY, rotAmount);
break;
case LEFT:
case 65:
for (int i = pixs.size()-1; i >= 0; i--) {
Pixel pixel = (Pixel) pixs.get(i);
if (mousePressed) pixel.rotate(mouseX, mouseY, -rotAmount);
else pixel.rotate(totalX, totalY, -rotAmount);
}
if (mousePressed) rotate(mouseX, mouseY, -rotAmount);
break;
case UP:
case 87:
for (int i = pixs.size()-1; i >= 0; i--) {
Pixel pixel = (Pixel) pixs.get(i);
pixel.scale(scaleAmount, scaleAmount);
}
totalScale += scaleAmount;
break;
case DOWN:
case 83:
for (int i = pixs.size()-1; i >= 0; i--) {
Pixel pixel = (Pixel) pixs.get(i);
pixel.scale(1/scaleAmount, 1/scaleAmount);
}
totalScale -= scaleAmount;
break;
case 32: // restart = swap image
setup();
break
}
//println(totalScale);
}
void mouseDragged() {
for (int i = pixs.size()-1; i >= 0; i--) {
Pixel pixel = (Pixel) pixs.get(i);
pixel.translate(mouseX-pmouseX, mouseY-pmouseY);
}
totalX += mouseX - pmouseX;
totalY += mouseY - pmouseY;
//println(totalX+","+totalY);
}
void rotate(float anchorX, float anchorY, float angle) {
float rotX, rotY, origX, origY;
origX = rotX = totalX - anchorX;
origY = rotY = totalY - anchorY;
totalX -= rotX;
totalY -= rotY;
angle = radians(angle);
rotX = origX * cos(angle) - origY * sin(angle);
rotY = origX * sin(angle) + origY * cos(angle);
totalX += rotX;
totalY += rotY;
}