Frage

Ich versuche, einen Weg in 3d zu extrudieren. Nichts Besonderes, doch nur einige Punkte folgen und ein regelmäßiges Vieleck für ‚Schlauch‘ verwenden. Ich verwende Verarbeitung für jetzt schnell zum Prototyp, aber später den Code in OpenGL aktivieren.

Mein Problem dreht die ‚Gelenke‘ in dem rechten Winkel. Ich glaube, ich habe eine grobe Vorstellung davon, wie die Winkel zu bekommen, nicht sicher.

Ich habe von einer Probe von Simon Greenwold (Herstellung> Datei> Beispiele> 3D> Form> Vertices) .Hier ist mein Versuch bisher gestartet:

UPDATE> Refactoring / Vereinfachtes CODE

Here is the main sketch code:
int pointsNum = 10;
Extrusion star;

int zoom = 0;

void setup() {
  size(500, 500, P3D);

  PVector[] points = new PVector[pointsNum+1];
  for(int i = 0 ; i <= pointsNum ; i++){
    float angle = TWO_PI/pointsNum * i;
    if(i % 2 == 0)
      points[i] = new PVector(cos(angle) * 100,sin(angle) * 100,0);
    else
      points[i] = new PVector(cos(angle) * 50,sin(angle) * 50,0);
  }

  star = new Extrusion(10,10,points,3);
}

void draw() {
  background(0);
  lights();
  translate(width / 2, height / 2,zoom);
  rotateY(map(mouseX, 0, width, 0, PI));
  rotateX(map(mouseY, 0, height, 0, PI));
  rotateZ(-HALF_PI);
  noStroke();
  fill(255, 255, 255);
  translate(0, -40, 0);
  star.draw();
}

void keyPressed(){
  if(key == 'a') zoom += 5;
  if(key == 's') zoom -= 5;
}

Und hier ist die Extrusion Klasse:

Import processing.core.PMatrix3D;

class Extrusion{

  float topRadius,bottomRadius,tall,sides;
  int pointsNum;
  PVector[] points;

  Extrusion(){}

  Extrusion(float topRadius, float bottomRadius, PVector[] points, int sides) {
    this.topRadius = topRadius;
    this.bottomRadius = bottomRadius;
    this.points = points;
    this.pointsNum = points.length;
    this.sides = sides;
  }

  void draw() {
    if(pointsNum >= 2){  
      float angle = 0;
      float angleIncrement = TWO_PI / sides;

      //begin draw segments between caps
      angle = 0;
      for(int i = 1; i < pointsNum ; ++i){
        beginShape(QUAD_STRIP);
        for(int j = 0; j < sides + 1; j++){
          vertex(points[i-1].x + cos(angle) * topRadius, points[i-1].y, points[i-1].z + sin(angle) * topRadius);
          vertex(points[i].x + cos(angle) * bottomRadius, points[i].y, points[i].z + sin(angle) * bottomRadius);

          angle += angleIncrement;
          }
        endShape();
      }
      //begin draw segments between caps
    }else println("Not enough points: " + pointsNum);
  }
}

UPDATE

Hier ist, wie meine Skizze wie folgt aussieht:

Verarbeitung extrudieren http://doc.gold.ac.uk/~ma802gp/extrude.gif

Das Problem ist, die Gelenke sind nicht im richtigen Winkel, so dass die extrudieren sehen falsch. Dies ist nicht ein sehr gutes Beispiel, wie dies mit einer Drehmaschine erreicht werden kann. Wenn ich eine Drehmaschine bekommen kann mit einer beliebigen Menge von Punkten und eine Achse zu arbeiten, das groß sein. Ich bin mit der Extrusion weil ich geometrischen Körper basierte auf der Kunst von Liviu Stoicoviciu.

zu schaffen versuchen

Hier sind einige Beispiele:

star Malerei http://doc.gold.ac.uk/~ma802gp/star_painting.jpg

star Papier Skulptur http://doc.gold.ac.uk/~ma802gp/star_paper_sculpture.jpg

Dreiecke http://doc.gold.ac.uk/~ma802gp/triangles_pencil.jpg

Es tut uns Leid über die schlechte Qualität.

Wie Sie in der Dreiecke Bild sehen können, dass mit Profilen erreicht werden würde.

UPDATE

Hier ist mein Versuch drhirsch Hilfe bei der Auslosung Methode zu verwenden:

void draw() {
    if(pointsNum >= 2){  
      float angle = 0;
      float angleIncrement = TWO_PI / sides;

      //begin draw segments between caps
      angle = 0;
      for(int i = 1; i < pointsNum ; ++i){
        beginShape(QUAD_STRIP);
        for(int j = 0; j < sides + 1; j++){

          PVector s = new PVector(0,0,1);
          PVector cn = new PVector();
          points[i].normalize(cn);
          PVector r = s.cross(cn);
          float a = acos(s.dot(cn));
          PMatrix3D rot = new PMatrix3D(1,0,0,0,
                                        0,1,0,0,
                                        0,0,1,0,
                                        0,0,0,1);
          rot.rotate(a,r.x,r.y,r.z);
          PVector rotVec = new PVector();
          rot.mult(points[i],rotVec);
          rotVec.add(new PVector(cos(angle) * topRadius,0,sin(angle) * topRadius));

          vertex(points[i-1].x + cos(angle) * topRadius, points[i-1].y, points[i-1].z + sin(angle) * topRadius);
          vertex(rotVec.x,rotVec.y,rotVec.y);

          //vertex(points[i-1].x + cos(angle) * topRadius, points[i-1].y, points[i-1].z + sin(angle) * topRadius);
          //vertex(points[i].x + cos(angle) * bottomRadius, points[i].y, points[i].z + sin(angle) * bottomRadius);

          angle += angleIncrement;
          }
        endShape();
      }
      //begin draw segments between caps
    }else println("Not enough points: " + pointsNum);
  }

Ich habe den Code so jetzt die Klasse Refactoring, die CShape genannt wurde ist Extrude genannt, der Code weniger und hoffentlich simples ist, und ich verwende eine Reihe von PVector anstelle eines Vektors von PVector Objekte Objekte, die verwirrend sein könnte .

Hier ist mein noch ein weiterer Versuch mit einigen escher-artigen Ergebnissen:

upated Unentschieden

void draw() {
    if(pointsNum >= 2){  
      float angle = 0;
      float angleIncrement = TWO_PI / sides;

      //begin draw segments between caps
      angle = 0;
      for(int i = 1; i < pointsNum ; ++i){
        beginShape(QUAD_STRIP);
        float angleBetweenNextAndPrevious = 0.0;
        if(i < pointsNum - 1) angleBetweenNextAndPrevious = PVector.angleBetween(points[i],points[i+1]);

        for(int j = 0; j < sides + 1; j++){

          PVector s = new PVector(0,0,1);
          PVector s2 = new PVector(0,0,1);
          PVector cn = new PVector();
          PVector cn2 = new PVector();
          points[i-1].normalize(cn);
          points[i].normalize(cn);
          PVector r = s.cross(cn);
          PVector r2 = s.cross(cn2);
          PMatrix3D rot = new PMatrix3D(1,0,0,0,
                                        0,1,0,0,
                                        0,0,1,0,
                                        0,0,0,1);
          PMatrix3D rot2 = new PMatrix3D(1,0,0,0,
                                        0,1,0,0,
                                        0,0,1,0,
                                        0,0,0,1);

          rot.rotate(angleBetweenNextAndPrevious,r.x,r.y,r.z);
          rot2.rotate(angleBetweenNextAndPrevious,r2.x,r2.y,r2.z);

          PVector rotVec = new PVector();
          rot.mult(points[i-1],rotVec);
          rotVec.add(new PVector(cos(angle) * topRadius,0,sin(angle) * topRadius));
          PVector rotVec2 = new PVector();
          rot2.mult(points[i],rotVec2);
          rotVec2.add(new PVector(cos(angle) * topRadius,0,sin(angle) * topRadius));

          vertex(rotVec.x,rotVec.y,rotVec.z);
          vertex(rotVec2.x,rotVec2.y,rotVec2.z);
          //vertex(points[i-1].x + cos(angle) * topRadius, points[i-1].y, points[i-1].z + sin(angle) * topRadius);
          //vertex(points[i].x + cos(angle) * bottomRadius, points[i].y, points[i].z + sin(angle) * bottomRadius);

          angle += angleIncrement;
          }
        endShape();
      }
      //begin draw segments between caps
    }else println("Not enough points: " + pointsNum);
  }
}

fix_test http://doc.gold.ac.uk/~ma802gp/extrude2.gif

Bearbeiten von drhirsch Dies sollte funktionieren:

void draw() {
    if(pointsNum >= 2){  
      float angle = 0;
      float angleIncrement = TWO_PI / sides;

      //begin draw segments between caps
      angle = 0;
      for(int i = 1; i < pointsNum ; ++i){
        beginShape(QUAD_STRIP);
        float angleBetweenNextAndPrevious = 0.0;
        if(i < pointsNum - 1) angleBetweenNextAndPrevious = PVector.angleBetween(points[i],points[i+1]);
        PVector s = new PVector(0,0,1);
        PVector s2 = new PVector(0,0,1);
        PVector cn = new PVector();
        PVector cn2 = new PVector();
        points[i-1].normalize(cn);
        points[i].normalize(cn2);
        PVector r = s.cross(cn);
        PVector r2 = s.cross(cn2);
        PMatrix3D rot = new PMatrix3D(1,0,0,0,
                                      0,1,0,0,
                                      0,0,1,0,
                                      0,0,0,1);
        PMatrix3D rot2 = new PMatrix3D(1,0,0,0,
                                       0,1,0,0,
                                       0,0,1,0,
                                       0,0,0,1);

        rot.rotate(angleBetweenNextAndPrevious,r.x,r.y,r.z);
        rot2.rotate(angleBetweenNextAndPrevious,r2.x,r2.y,r2.z);
        PVector rotVec = new PVector();
        PVector rotVec2 = new PVector();

        for(int j = 0; j < sides + 1; j++){
          // I am still not sure about this. Should the shape be in the xy plane 
          // if the extrusion is mainly along the z axis? If the shape is now in
          // the xz plane, you need to use (0,1,0) as normal vector of the shape
          // (this would be s and s2 above, don't use the short names I have
          // used, sorry)
          PVector shape = new PVector(cos(angle) * topRadius,0,sin(angle) * topRadius);

          rot.mult(shape, rotVec);
          rot2.mult(shape,rotVec2);

          rotVec.add(points[i-1]);
          rotVec2.add(points[i]);

          vertex(rotVec.x,rotVec.y,rotVec.z);
          vertex(rotVec2.x,rotVec2.y,rotVec2.z);
          //vertex(points[i-1].x + cos(angle) * topRadius, points[i-1].y, points[i-1].z + sin(angle) * topRadius);
          //vertex(points[i].x + cos(angle) * bottomRadius, points[i].y, points[i].z + sin(angle) * bottomRadius);

          angle += angleIncrement;
          }
        endShape();
      }
      //begin draw segments between caps
    }else println("Not enough points: " + pointsNum);
  }
}

UPDATE

Hier ist eine einfache Darstellung meines Problems:

Beschreibung http://doc.gold.ac.uk/~ma802gp/description.gif

Der blaue Pfad entspricht den Punkt [] PVector Array in meinem Code, wenn pointsNum = 6. Der rote Weg ist, was ich bin zu kämpfen der grüne Weg zu lösen, ist das, was ich erreichen will.

UPDATE

Einige kleinere Probleme mit der Reihenfolge der Eckpunkte, denke ich. Hier sind einige der Druck-Taste mit 6 Punkten und keine (if / else% 2) Stern Zustand.

Punkte1 http://doc.gold.ac.uk/~ma802gp/points1.gif

alt text http://doc.gold.ac.uk/~ma802gp/points2.gif

War es hilfreich?

Lösung

Ihre Form Unter der Annahme hat einen Normalvektor S. In Ihrem Beispiel S würde (0,0,1), weil Ihre Form flach in xy ist. Sie können das Kreuzprodukt zwischen dem aktuellen Pfadvektor V (normalisiert) und S verwenden, um den Drehachsenvektor R. Sie müssen erhalten Ihre Form um R. Den Drehwinkel drehen, kann aus dem Skalarprodukt zwischen S und V erhalten werden, Also:

R = S x V
a = arc cos(S . V)

Jetzt können Sie Setup ein Rotationsmatrix mit R und ein und drehen Sie die Form durch .

Sie können mit glRotate (...) der aktuellen Matrix auf dem Stapel drehen, aber das kann nicht zwischen glBegin () und glEnd () erfolgen. So haben Sie selbst die Matrixmultiplikation zu tun oder mit einer Bibliothek.

Edit: Nach einem kurzen Blick auf die Bibliothek, die Sie verwenden, sollten Sie die Rotationsmatrix mit

Setup der Lage sein,
PVector s = new PVector(0,0,1);  // is already normalized (meaning is has length 1)
PVector cn;
current.normalize(cn);
PVector r = s.cross(cn);
float a = acos(s.dot(cn));
PMatrix rot = new PMatrix(1, 0, 0, 0,
                          0, 1, 0, 0,
                          0, 0, 1, 0,
                          0, 0, 0, 1);
rot.rotate(a, r.x, r.y, r.z);

und nun jedes Element Ihrer Form mit rot vermehren und sie von Ihrem aktuellen Pfadvektor übersetzen:

PVector rotVec;
rot.mult((PVector)shape[i], rotVec);
rotVec.add(current);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top