Вращение, инвертирование и перевод объекта PShape в Processing - PullRequest
0 голосов
/ 06 января 2019

Я бы хотел:

  • перевод , инвертирование и поворот один четырехугольник (объект PShape) несколько раз
  • затем изменить высоту одной из двух верхних вершин

так что все это действует как шарнирное плечо , которое можно согнуть вправо или влево .

Чтобы было как можно яснее, я сделал несколько рисунков.

enter image description here


enter image description here


enter image description here


enter image description here


enter image description here

Я знаю, что могу:

  • перевод четырехугольника с использованием translate()
  • Отразить (инвертировать) с помощью scale(1, -1)
  • поверните , используя функцию atan2()

enter image description here

ПРОБЛЕМА

При объединении 3 вместе я получаю следующее:

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

Угол поворота кажется правильным, но, очевидно, что-то не так с переводом (по оси X или Y), и я не могу понять, что именно.

Я подозреваю, что отсутствует перевод для стержня или неправильный порядок преобразований (или, может быть, оба).

Я был бы очень признателен, если бы кто-нибудь помог мне понять, что я делаю неправильно и как решить эту проблему.

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();
}

1 Ответ

0 голосов
/ 06 января 2019

Наконец-то нашли обходной путь

Исправления

  • неправильный порядок вершин QUADS
  • вычисление высоты разворота отсутствовало (на основе помощи @ Rabbid76)
  • перевод, основанный на этой высоте, должен выполняться до и после вращения (не уверен, чтобы понять причину)
  • угол поворота необходимо умножить на -1 (отрицательный угол), чтобы изменить сторону изгиба

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()
...