4 stroke animation need help with rotate()

Hi all,

please try to help me undestanding translate() combined with rotate(radians()).
My left valve is working nearly as expected but the right valve get() function is not referencing the top of the valve.

Thanks a lot!
grillgemuese

//4 stroke animation 20.03.2019
//update names into eng
PImage engineblock, crankshaft, rod, piston, valve, camshaft;

final int camMidX = -11, camMidY = -19;
final int ignitionAngle = 15;
final color BGCol = #F0F0F0;

boolean engineState = true, spark = false;
int lastMs = 0, crankshaftDeg = 0;
int tx = 0, ty = 0;

int leftValvePos = 0, rightValvePos = 0;
color colRightValve = #F016E2, colLeftValve = #F016E2;

void setup()
{
  size(228, 400);
  frameRate(60);
  surface.setTitle("Engine");
  
  engineblock = loadImage("engineblock_transparent.png");
  crankshaft = loadImage("crankshaft_transparent.png");
  rod = loadImage("rod_transparent.png");
  valve = loadImage("valve_transparent.png");
  camshaft = loadImage("camshaft_transparent.png");
  piston = loadImage("piston_transparent.png");
}//void setup() END

void draw()
{
  background(BGCol);
  
  //fill(0);
  //textSize(15);
  //text("IN", 2, 128);
  //text("OUT", 195, 128);
  
  drawEngine();
  drawCrankshaft();
  
  drawRod();
  drawPiston();
 
  //rect(mouseX-10, mouseY-10, 20, 20);
  drawCamshafts();
  drawLeftValve();
  drawRightValve();
  
  println("tx:" + tx + " ty:" + ty);
  //print("x:" + mouseX, " y:" + mouseY + " = ");
  //println(hex(get(mouseX, mouseY)));
  
  if (engineState && millis() - lastMs >= 5)
  {
    lastMs = millis();
    crankshaftDeg += 2;
    if (crankshaftDeg >= 360*2) crankshaftDeg = 0;
    if (crankshaftDeg >= 360 - ignitionAngle && crankshaftDeg <= 360 + ignitionAngle + 5) spark = true; 
    else spark = false;
  }
  fill(#F01616);
  if (spark) rect(10, 10, 20, 20);
}//void draw() END

void keyPressed()
{
  if (key == 'w') ty--;
  else if (key == 's') ty++;
  else if (key == 'a') tx--;
  else if (key == 'd') tx++;
}

void drawEngine()
{
  pushMatrix();
    scale(2.0);
    image(engineblock, 17, 10);
  popMatrix();
}

void drawCrankshaft()
{
  pushMatrix();
    scale(2.0);
    translate(57, 142);
    rotate(radians(crankshaftDeg));
    image(crankshaft, -14, -19);
  popMatrix();
}

void drawRod()
{
  pushMatrix();
    scale(2.0);
    translate(47, 86);
    //rotate(radians(ty));
    //get()
    image(rod, 0, 0);
  popMatrix();
}

void drawPiston()
{
  pushMatrix();
    scale(2.0);
    translate(40, 75);
    image(piston, 0, 0+0);
  popMatrix();
}

void drawLeftValve()
{
  pushMatrix();
    scale(0.9);
    translate(31, 109);
    rotate(radians(-40));
    colRightValve = get(valve.width + leftValvePos, valve.height + leftValvePos + 5);
    //println("lVP:" + leftValvePos + " col:" + hex(colRightValve));
    if(colRightValve == BGCol)
    {
      leftValvePos--;
    }
    else if(colRightValve != BGCol)
    {
      leftValvePos++;
    }
    image(valve, 0, leftValvePos);
  popMatrix();
}

void drawRightValve()
{
  pushMatrix();
    scale(0.9);
    translate(196, 83);
    rotate(radians(40));
    colLeftValve = get(valve.width + rightValvePos, valve.height + rightValvePos + 5);
    //rect(valve.width + rightValvePos, valve.height + rightValvePos + 5, 10, 10);
    println("rVP:" + rightValvePos + " col:" + hex(colLeftValve));
    if(colLeftValve == BGCol)
    {
      rightValvePos--;
    }
    else if(colLeftValve != BGCol)
    {
      rightValvePos++;
    }
    image(valve, 0, rightValvePos);
  popMatrix();
}

void drawCamshafts()
{
  //left
  pushMatrix();
    scale(1.5);
    translate(18, 48);
    rotate(radians(crankshaftDeg / 2 + 90));
    image(camshaft, camMidX, camMidY);
  popMatrix();
  //right
  pushMatrix();
    scale(1.5);
    translate(136, 48);
    rotate(radians(crankshaftDeg / 2 - 90));
    image(camshaft, camMidX, camMidY);
  popMatrix();
}

camshaft_transparent crankshaft_transparent engineblock_transparent piston_transparent rod_transparent valve_transparent

1 Like

the

get(x,y)

uses absolute canvas pixel coordinates
( and insofar it should not matter when ( inside or outside push pop ) you execute it. )

looks like you want look like on a relative pix position ( n pix in front of object movement )
but after you do

push / trans / scale / rotate /

you actually not know where you are.
model X Y Z could give you that info
but no idea if

get(modelX(0,0,0)+ valve.width + leftValvePos, modelY(0,0,0)+valve.height + leftValvePos + 5);

would work.

actually better look for a other animation control ( as check color by get() )
like i try ( because i not have your pictures…)

// https://discourse.processing.org/t/4-stroke-animation-need-help-with-rotate/9510
int move=0, dir=1, lpos=0, rpos=0, hub=10;

void update() {
  move += dir; 
  if ( move >hub )  dir = -1; 
  if ( move < 0 )  dir = 1;
  lpos = move;
  rpos = hub-move;
  //println("move "+move+" lpos "+lpos+" rpos "+rpos);
}

void draw_l_object() {
  push();
  rotate(PI/2+PI/4.0);
  translate(lpos,0);
  rect(40, 0, 40, 20);
  pop();
}

void draw_r_object() {
  push();
  rotate(PI/2-PI/4.0);
  translate(rpos,0);
  rect(40, 0, 40, 20);
  pop();
}

void draw_block() {
  push();
  rotate(PI/4);
  if ( move < 3 || move > hub-3 ) fill(200,0,0);
  else                            fill(0,200,200);
  rect(0,0,40,40);
  pop();
}

void setup() {
  size(200, 200);
  rectMode(CENTER);
  frameRate(20);
}

void draw() {
  background(200, 200, 0);
  translate( width/2, height/2 );
  draw_block();
  update(); 
  draw_l_object();
  draw_r_object();
}

2 Likes

If you haven’t, review this tutorial:

and the section “Rotation the Correct Way”

1 Like