Processing: Cube rotating stay in one place while

2019-08-22 06:03发布

问题:

In the Processing program, I have to make a cube to move in place where the cube moves when pressing lowercase x for counterclockwise of x axis, or pressing capital X for clockwise of x axis, and pressing lowercase y for counterclockwise of y axis, or pressing capital Y for clockwise of y axis, and pressing lowercase z for counterclockwise of z axis, and pressing capital Z for for clockwise for z axis. The problem is that the cube moves out of place, but it does rotate. How do I rotate, but not move out of place? Please help check this code. The code works however it moves out of place. Also, it spins on the first time the button is pressed. How do I fix that?

float theta = 0;
void setup() {
  size(600, 600, P3D);
}

void draw() {
  background(255);
  fill(127, 127);
  String s1 = "Press x for counterclockwise of x axis, X for clockwise of x axis"; 
  String s2 = "Press y for counterclockwise of y axis, Y for clockwise of y axis ";
  String s3 = "Press z for counterclockwise of z axis, Z for for clockwise for z axis";
  text(s1, 0, width/2 + 100);
  text(s2, 0, width/2 + 125);
  text(s3, 0, width/2 + 150);
  // if(pressLowX() == true) 
  // cubeBox(.5, .5, .5);
  pressButtons();
  pushMatrix();
  translate(width/2, height/2);
  cubeBox(.5, .5, .5);
  popMatrix();
}


void cubeBox(float x, float y, float z) {
  translate(x, y, z);
  rotate(theta);
  beginShape(QUADS);

  fill(255, 0, 0);
  vertex(100, 100, 100);
  vertex(-100, 100, 100);
  vertex(-100, -100, 100);
  vertex(100, -100, 100);

  fill(255, 255, 0);
  vertex(-100, -100, -100);
  vertex(100, -100, -100);
  vertex(100, 100, -100);
  vertex(-100, 100, -100);

  fill(0, 255, 0);
  vertex(100, 100, 100);
  vertex(100, -100, 100);
  vertex(100, -100, -100);
  vertex(100, 100, -100);

  fill(0, 255, 255);
  vertex(-100, -100, 100);
  vertex(-100, -100, -100);
  vertex(-100, 100, -100);
  vertex(-100, 100, 100);

  fill(0, 0, 255);
  vertex(-100, -100, 100);
  vertex(-100, -100, -100);
  vertex(100, -100, -100);
  vertex(100, -100, 100);

  fill(255, 0, 255);
  vertex(100, 100, 100);
  vertex(-100, 100, 100);
  vertex(-100, 100, -100);
  vertex(100, 100, -100);
  // rotate(-theta);
  // translate(-x, -y, -z); 
  endShape(CLOSE);
}

void pressButtons() {
  if (key == 'x') { 
    theta = theta - .05;
    rotateX(radians(0));
  } else if (key == 'X') {
    theta = theta + .05;
    rotateX(radians(0));
  } else if (key == 'y') {
    theta = theta - .05;
    rotateY(radians(90));
  } else if (key == 'Y') {
    theta = theta + .05;
    rotateY(radians(90));
  } else if (key == 'z') {
    theta = theta - .05;
    rotateZ(radians(60));
  } else if (key == 'Z') {
    theta = theta + .05;
    rotateZ(radians(60));
  }
}

回答1:

To rotate a geometry in place, the rotation has to be applied to the geometry before the translation:

P' = translation * rotation * P

This means you have to do the the instructions in this order:

e.g.

  translate(x, y, z);
  rotateX(theta);

The issue is that the rotation by the angle theta is done before translate, in the function pressButtons.

To solve your issue, create a global variable which notice the last pressed key and change the state of the variable in the function pressButtons

char actKey = 0;
void pressButtons() {
    if (key == 'x' || key == 'X' || key == 'y' || key == 'Y' || key == 'z' || key == 'Z')
        actKey= key;
}

Create a new function, which performs the rotation, dependent on the state of actKey

void addRotation() {
    if (actKey == 'x') { 
        theta = theta - .05;
        rotateX(theta);
    } else if (actKey == 'X') {
        theta = theta + .05;
        rotateX(theta);
    } else if (actKey == 'y') {
        theta = theta - .05;
        rotateY(theta);
    } else if (actKey == 'Y') {
        theta = theta + .05;
        rotateY(theta);
    } else if (actKey == 'z') {
        theta = theta - .05;
        rotateZ(theta);
    } else if (actKey == 'Z') {
        theta = theta + .05;
        rotateZ(theta);
    }
}

Perform the translation followed by the rotation at the begin of cubeBox:

void cubeBox(float x, float y, float z) {

    translate(x, y, z);
    addRotation();

    // [...]

}