solub
solub

Reputation: 1363

Rotating, inverting and translating a PShape object in Processing

I would like to:

so as the whole thing act as an articulated arm that can be bent either to the right or the left.

To be as clear as possible I've made some graphics.

enter image description here


enter image description here


enter image description here


enter image description here


enter image description here

I know that I can:

enter image description here

PROBLEM

When combining the 3 together I end up with this:

https://media.giphy.com/media/lkACPOxBLOhtk20gzD/giphy.gif

The angle of rotation seems correct but obviously there's something off with the translation (either on the X or Y axis) and I can't figure out what exactly.

I suspect a missing translation for the pivot, or an incorrect order of transformations (or maybe both).

I would really appreciate if someone could help me understand what I'm doing wrong and how to fix this problem.

int W = 40;
int H = 40;
int offset = 10; 

float[] p0 = {-W/2, -H/2};
float[] p1 = {-W/2,  H/2};
float[] p2 = {W/2, H/2};
float[] p3 = {W/2, -H/2 - offset};

PShape object;


void setup(){
    size(600, 600, P2D);
    smooth(8);
    noFill();
}


void draw(){
    background(255);

    pushMatrix();
    translate(width>>1, height>>1);

    float angle = atan2(p3[1] - p0[1], p3[0] - p0[0]);

    for (int i = 0; i < 6; i++){

        int factor = (i % 2 == 0) ? 1 : -1;

        //Height translation
        translate(0, H*factor);

        //Flip all quads except 1st one
        if (i > 0){
          scale(1, -1);
        }

        //Rotate once every 2 quads
        if (i%2 == 1){
          rotate(-angle*2);
        }

        object();
      }

    popMatrix();

}


void object() {
    beginShape(QUADS);

    vertex(p0[0], p0[1]);
    vertex(p1[0], p1[1]);
    vertex(p2[0], p2[1]);
    vertex(p3[0], p3[1]);

    endShape();
}

Upvotes: 5

Views: 628

Answers (1)

solub
solub

Reputation: 1363

Finally found a workaround

Fixes:

  • the vertices order of the QUADS was incorrect
  • the computation of the pivot height was missing (based on @Rabbid76's help)
  • the translation based on that height needs to be operated before and after the rotation (not sure to understand the reason)
  • the rotation angle has to be multiplied by -1 (negative angle) in order to change the bending side

enter image description here

add_library('controlP5')

W, H = 40, 40
nQuads = 8
offset = 0

p0 = PVector(-W/2, -H/2)
p1 = PVector(-W/2,  H/2)
p2 = PVector(W/2, H/2)
p3 = PVector(W/2, -H/2)


def setup():
    size(600, 600, P2D)
    noFill()
    smooth(8)

    global cp5, slider
    cp5 = ControlP5(this)
    slider = cp5.addSlider('Bend').setPosition(width/2-50, height-150).setSize(100,10).setHandleSize(40).setDecimalPrecision(1).setColorBackground(color(100)).setColorForeground(color(140)).setColorActive(color(240)).setRange(-H, H).setValue(offset).setSliderMode(Slider.FLEXIBLE)


def draw():
    background(255)

    global off1, off2
    if slider.getValue() >= 0:
        factor = -1
        off1 = slider.getValue()
        off2 = 0
    else:
        factor = 1
        off2 = abs(slider.getValue())
        off1 = 0

    pushMatrix()
    translate(width>>1, height>>1)


    angle = atan2(p3.y - p0.y - abs(slider.getValue()), p3.x - p0.x)
    H2 = -H/2 + W *tan(angle)/2

    for i in range(nQuads):

        pivotHeight = H2 if i%2 == 1 else H/2

        #Height translation
        if i > 0:
            translate(0 , pivotHeight)

        #Rotate once every 2 quads
        if i%2 == 1:
            rotate(angle*2*factor) 

        #Height translation
        if i > 0:
            translate(0 , pivotHeight)            

        #Flip all quads except 1st one
        if i > 0:
            scale(1, -1)        

        object()

    popMatrix()


def object():

    beginShape(QUADS)
    vertex(p0.x, p0.y - off1) 
    vertex(p1.x, p1.y) 
    vertex(p2.x, p2.y)
    vertex(p3.x, p3.y - off2)
    endShape()

Upvotes: 4

Related Questions