Whats the best way to make a simplex like in this Pic

edited February 2018 in How To...

simplex

As you can see, its one polyhedron with five vertices.

Would you use triangle strip to construct it ? Or use single lines and group them in classes to tetrahedrons? In the end I like to highlight each of the single tetrahedrons eg via key commands.

Additionally I would like to experiment with shading to create depth effect. how would you do that? coloring the triangle planes black and white. Or can I place light sources?

Big thanks in advance for any help

I´m sure there are thousand ways. Please choose the simple one for me, doenst matter if its more code :)

Tagged:

Answers

  • I´m sure there are thousand ways.

    Yep, exactly.

    Please choose the simple one for me

    That's not really how it works. Which one is simple depends on you more than anything. We can tell you how we would do that, but that doesn't mean it's how you should do it.

    The best thing you can do is break your problem down into smaller steps and take those steps on one at a time. For example, can you create a simple version of one of these shapes? Start with a basic triangle.

    Then if you get stuck, you can post a MCVE along with a more specific technical question. Good luck.

  • is this 3D?

    because somehow the gray lines seem to be crossing the color lines. or the gray lines define a pyramid which intersects with the colored main part which is strange

    https://www.processing.org/reference/vertex_.html

  • the picture is a screenshot from that video (5:43min)

    how this 4D to 3D abstractions shall work - i´have no idea. 4th dimension to me is time - like the tetrahedron in movement.

    but it seems to me that I could make five vertices in 3D space, connect them and the result is a polyhedron which contains 5 tetrahedron and consequently multiple depth perspectives.

    Beeing able to choose between depth perspectives - this is what I´m interesting in. Choosing the combination of planes to open up a space. Would it work with this approach?

  • Answer ✓

    when i've done this i've defined my own class to hold 4d values, like a pvector but one louder. you also have to write 4d rotation code (think of a 3d rotation matrix, only 4d, and instead of 3 axes you can rotate around you have 6 planes you can rotate around) and finally a 4d perspective transform (again, quite a simple extension of the 3d equiv).

    (i'd post some examples but mine are actually 5d, and quite old)

    as for creating the shape, you'd have an array of 5 of your 4d points and an array of 10(?) pairs of vertices, which define which lines connect which vertices (and maybe a 4d-equivalent of an array of faces, which define the individual tetrahedra)

  • edited February 2018 Answer ✓

    @TillFly: The 4th dimension is time in the sense of Albert Einstein (https://en.wikipedia.org/wiki/Spacetime) but in your context, it's not time.

    It's just an additional space dimension, like when we go from point to line, to plane, to cube and then to a 4th dimension. You could go on to 5th, 6th and so forth.

  • koogs has described the best way to do it.

    But here is a simple triangle in 3D, that you can rotate with the mouse (PeasyCam)

    import peasy.*;
    import peasy.org.apache.commons.math.*;
    import peasy.org.apache.commons.math.geometry.*;
    
    
    PeasyCam cam ;
    
    ArrayList<TriangleClass> triangles;
    //
    // -----------------------------------------------------
    //
    void setup() {
      // init
      size(800, 600, P3D);
    
      cam =  new PeasyCam(this, 500);
    
      int widthX= 50;
      int widthY= 50;
      int widthXhalf= widthX/2;
      int widthYhalf= widthY/2;
    
      triangles = new ArrayList<TriangleClass>();  // Create an empty ArrayList
    
      // for the Color : 
      color MyC1 = color( 22, 255, 22 );
      // A new TriangleClass object is added to the ArrayList (by default to the end)
      triangles.add(new TriangleClass(
        400-widthXhalf, 200, 300, 
        400+widthXhalf, 250, -100, 
        400, 600, -100, 
        MyC1 ));
      //  noStroke();
    } // func 
    
    void draw() 
    { 
      // runs again and again 
      background(255);
      lights();
    
      translate(-440, -300);
      //
      for (int i=0; i < triangles.size(); i++) {
        // get object from ArrayList 
        TriangleClass myCurrentTriangle = triangles.get(i);
        myCurrentTriangle.display();
      } // for
    } // func 
    
    // =================================
    // Simple class
    
    class TriangleClass {
      // 
      PVector pv1, pv2, pv3;    // points 
      color myColor;            // fill color 
    
      // constructor
      TriangleClass(
        float tempX1, float tempY1, float tempZ1, 
        float tempX2, float tempY2, float tempZ2, 
        float tempX3, float tempY3, float tempZ3, 
        color tempmyColor1 ) {
        pv1 = new PVector (tempX1, tempY1, tempZ1); 
        pv2 = new PVector (tempX2, tempY2, tempZ2);
        pv3 = new PVector (tempX3, tempY3, tempZ3);
    
        myColor=tempmyColor1;
      }  // constructor
    
      void display() {
        // show 
        fill(myColor); 
        beginShape(TRIANGLES); 
        vertex(pv1.x, pv1.y, pv1.z);
        vertex(pv2.x, pv2.y, pv2.z);
        vertex(pv3.x, pv3.y, pv3.z);
        endShape();
      } // func
      //
    } // class
    // ============================
    
  • so then i have to go after this thank you very much!

  • I would like to experiment with shading to create depth effect. how would you do that? coloring the triangle planes black and white. Or can I place light sources?

    as for creating the shape, you'd have an array of 5 of your 4d points and an array of 10(?) pairs of vertices, which define which lines connect which vertices (and maybe a 4d-equivalent of an array of faces, which define the individual tetrahedra)

    If for any given rotation you are creating a set of 3D tetrahedra as a projection into 3D space then you can shade them, texture them, or light them just like any other 3D object in Processing. By the time you know where they go, they aren't special -- they are just up to five 3D objects (each consisting of four 2D faces) -- these objects just that happen to share sides.

    If you are rendering a 5-cell, that means that for any given rotation of your 4d points list, you are then you are always going to render a Tetrahedron 5 times, and always with fixed 3D projections of points from your 4D point array. Whatever output you get, you can shade and light. Since there are always only 5 Tetrahedrons objects in your FiveCell object, that should make shading [1] or [3] fairly simple.

    Related:

  • thanks a lot for that great input!

    I tried it this way, but three coordinates with vertex() dont work with P3D of the size() object.

    import damkjer.ocd.*;
    import peasy.*;
    import peasy.org.apache.commons.math.*;
    import peasy.org.apache.commons.math.geometry.*;
    
    PeasyCam cam ;
    
    int[] strokeWeight = new int[3];  // datatype, name, new object with amount of instances
    
    
    void setup() {
    
    size(500, 500, P3D);
    //cam = new Camera(this, 0, 0, 50);
    
    cam =  new PeasyCam(this, 500);
    
    strokeWeight[0] = 1; 
    strokeWeight[1] = 2; 
    strokeWeight[2] = 8;
    }
    
    void draw() {
    
    background(255);
    
    int a = strokeWeight[0]; 
    int b = strokeWeight[1];
    int c = strokeWeight[2]; 
    
    
    // Tetrahedron 1
    beginShape(LINES);
    
    strokeWeight(b);
    
    vertex(200, 0, 0, 0); // V1
    vertex(0, 200, 0, 0); // V2
    
    vertex(200, 0, 0, 0); // V1
    vertex(0, 0, 200, 0); // V3
    
    vertex(200, 0, 0, 0); // V1
    vertex(0, 0, 0, 200); // V4
    
    vertex(200, 0, 0, 0); // V1
    vertex(162, 162, 162, 162); // V5
    
    vertex(0, 200, 0, 0); // V2
    vertex(0, 0, 200, 0); // V3
    
    vertex(0, 200, 0, 0); // V2
    vertex(0, 0, 0, 200); // V4
    
    vertex(0, 200, 0, 0); // V2
    vertex(162, 162, 162, 162); // V5
    
    endShape();
    }
    

    @koogs How does it work to assign number with lists like this to a 4D grid? (dont pay attention to the number pls)

    // 5 Points in a 4D Grid
    int[][][][] my4DArray = new int[5][5][5][5];
    
    
    // how to assign values with this list for x,y,z,w ??
    float[][][][] my4DArray = {{236, 189, 189,   0, 5}, 
                               {236,  80, 189, 189, 5}, 
                               {236,   0, 189,  80, 5},
                               {236,   0, 189,  80, 5},
                               {236,   0, 189,  80, 5}};
    
  • Answer ✓
    vertex(200, 0, 0, 0);
    

    this is a 2d vertex with a texture applied, not a 4d vertex

  • // how to assign values with this list for x,y,z,w ??
    float[][][][] my4DArray = {{236, 189, 189,   0, 5}, 
                               {236,  80, 189, 189, 5}, 
                               {236,   0, 189,  80, 5},
                               {236,   0, 189,  80, 5},
                               {236,   0, 189,  80, 5}};
    

    and that is a [][4] array, not a 4d array. but that's all you need - ditch two of the []s in the definition.

  • and that is a [][4] array, not a 4d array. but that's all you need - ditch two of the []s in the definition.

    hm.. sorry, I dont understand how this shall work with a 2D array. how can I iterate of the lists of myArray?

    this is where I am right now:

        int[][]myArray = {{200, 0, 0,   0}, 
                          {0, 200, 0, 0}, 
                          {0,   0, 200, 0},
                          {0,   0, 0,  200},
                          {162, 162, 162, 162}};
    
        int cols = 10;
        int rows = 10;
        //int[][] myArray = new int[cols][rows];
    
        void setup(){
        size(200,200);
        }
    
        void draw (){
    
    
        for (int i = 0; i < cols; i++) {
          for (int j = 0; j < rows; j++) {
            myArray[i][j] = 0;
          }
        }
    
    }
    
  • Answer ✓

    maybe call it something other than myArray and things would be clearer. an array of what? looks like a vertex array. so call it that. now you have an array of vertices and each element has 4 values, one for each dimension.

    this is where I am right now

    so you create an array of vertices with values and then set them all to 0? why?

    (and you do this 60 times a second until you stop the code. nothing is drawn.)

  • Answer ✓

    i would have written in class PVector4D with x,y,z,z2 but never mind

    your array is ok as well

    in draw start by saying ellipse( myArray[......

    you need a way to project the 4 coordinates of one point to the 3D realm then and display the array using pushMatrix(); translate (x,y,z); sphere (4); popMatrix();

  • edited February 2018

    so you create an array of vertices with values and then set them all to 0? why?

    because I dont know how to continue -.-

    in draw start by saying ellipse( myArray[......

    why an ellipse? shall there be an ellipse instead of a Point?

    how can I have an ellipse with four coordinates?

    just to make sure that I understood the next tasks:

    • next I have to get the coordinates attached to the points
    • then I have to project this into the 3D realm
    • then I guess, after displaying a point I have to make pushMatrix() and keep going with this point for point..
  • edited February 2018
    // Set coordinates in VertexArray
    int[][]VertexArray = {{200, 0, 0,       0}, 
                          {0, 200, 0,       0}, 
                          {0,   0, 200,     0},
                          {0,   0, 0,     200},
                          {162, 162, 162, 162}};
    
    // Set variables
    int cols = 4;
    int rows = 5;
    
    int test = 0;
    //int[][] myArray = new int[cols][rows];
    
    void setup(){
    size(200,200);
    
    // Initialize  and print array values
    for (int i = 0; i < cols; i++) {
      for (int j = 0; j < rows; j++) {
      println(VertexArray[i][j]); // what to 
      } 
     }
    }
    

    I just would like to print the VertexArray[i][j] values and the monitor says: "ArrayIndexOutOfBoundsException:4"

    I guess the i++ is counting further then the size of the array, but it should stop when the "i < cols-condition" is not fullfilled anymore..? Why is that happening?

  • your array is [5][4], 5 rows of 4 values each. rows should be the outer loop.

  • edited February 2018

    it's easier with classes, you'll just confuse yourself with a 2d array

    // global
    ArrayList<Point4> points = new ArrayList<Point4>();
    
    // setup
    points.add(new Point4(200, 0, 0, 0));
    points.add(new Point4(0, 200, 0, 0));
    points.add(new Point4(0, 0, 200, 0));
    points.add(new Point4(0, 0, 0, 200));
    points.add(new Point4(162, 162, 162, 162));
    
    // 4d point class
    class Point4 {
        float w, x, y, z;
        ....
    }
    
  • your array is [5][4], 5 rows of 4 values each. rows should be the outer loop.

    sorry just to understand this: how to put "row" out of the loop?.. I need that number to iterate?..

    thanks for the code with the classes. I will continue with that.

  • Answer ✓

    For 4D rotation and projection see

    https://www.uni-koblenz.de/~cg/Studienarbeiten/4d_mosig.pdf

    Projection: either just ignore w or follow the matrix formula for distance s

    see page 15

  • Answer ✓
    for (int i = 0; i < cols; i++) {
      for (int j = 0; j < rows; j++) {
        println(VertexArray[i][j]); // what to 
      } 
    }
    

    moving rows to the OUTER loop

    for (int i = 0; i < rows; i++) { // OUTER LOOP
      for (int j = 0; j < cols; j++) { // INNER LOOP
        println(VertexArray[i][j]);
      } 
    }
    
  • aah sorry koogs, I´m a noob here...

    trouble again: when I want to compile it like the code below debug log says: "unexpected token: (" - in the constructor line.

    when hovering over the constructors it says "=" missing. But the syntax of the constructors in comparison with the reference is correct where is the mistake?

    // global, declare the array
    ArrayList<Point4> points = new ArrayList<Point4>();
    //ArrayList<Particle> particles = new ArrayList<Particle>();
    
    // setup, adding objects to the Point4 class
    // constructor enables to give an object a value when you add it
    points.add(new Point4(200, 0, 0, 0));
    points.add(new Point4(0, 200, 0, 0));
    points.add(new Point4(0, 0, 200, 0));
    points.add(new Point4(0, 0, 0, 200));
    points.add(new Point4(162, 162, 162, 162));
    
    void setup() 
    {
      size(400,400);
    
    }
    
    void draw() {
      background (0);
    }
    
    
    // 4d point class
    class Point4 {
        float w, x, y, z;
        //Point4 (float
      }
    
    /*
    // Particles can be pulled out of an ArrayList with get()
    Point4 part = points.get(0);
    part.display();
    */
    
  • edited February 2018
    /**
     * 4D Points (v1.2)
     * GoToLoop (2018/Feb/06)
     *
     * Forum.Processing.org/two/discussion/26213/
     * whats-the-best-way-to-make-a-simplex-like-in-this-pic#Item_24
     */
    
    final Point4[] dots = {
      new Point4(200, 0, 0, 0), 
      new Point4(0, 200, 0, 0), 
      new Point4(0, 0, 200, 0), 
      new Point4(0, 0, 0, 200), 
      new Point4(162, 162, 162, 162)
    };
    
    void setup() {
      size(800, 600);
      noLoop();
    }
    
    void draw() {
      background((color) random(#000000));
      printArray(dots);
    }
    
    class Point4 {
      float w, x, y, z;
    
      Point4() {
      }
    
      Point4(float w, float x, float y, float z) {
        set(w, x, y, z);
      }
    
      Point4 set(float ww, float xx, float yy, float zz) {
        w = ww;
        x = xx;
        y = yy;
        z = zz;
    
        return this;
      }
    
      @ SafeVarargs final float[] get(final float... pts) {
        if (pts == null || pts.length < 4)  return new float[] { w, x, y, z };
    
        pts[0] = w;
        pts[1] = x;
        pts[2] = y;
        pts[3] = z;
    
        return pts;
      }
    
      @ Override String toString() {
        return "{ w: " + w + ", x: " + x + ", y: " + y + ", z: " + z + " }";
      }
    }
    
  • Hello Mr. GoToLoop,

    thanks a lot for your investigation! I´m having a hard time to understand this :/ I wrote some questions (marked with ??) inline the code. would be awwweseome if you could comment on those.

    /**
     * 4D Points (v1.2)
     * GoToLoop (2018/Feb/06)
     *
     * Forum.Processing.org/two/discussion/26213/
     * whats-the-best-way-to-make-a-simplex-like-in-this-pic#Item_24
     */
    
    //QUESTIONS QUESTIONS QUESTIONS --> ??
    
    
    // with final it´s not able to change the coordinates 
    // new: new object "Point4" is created, Point4[] is array (Datatype) 
    final Point4[] dots = {
      new Point4(200, 0, 0, 0), 
      new Point4(0, 200, 0, 0), 
      new Point4(0, 0, 200, 0), 
      new Point4(0, 0, 0, 200), 
      new Point4(162, 162, 162, 162)
    };
    
    void setup() {
      size(800, 600);
      // void draw() does not loop
      noLoop();
    }
    
    void draw() {
      background(0);
      printArray(dots);
    }
    
    
    class Point4 {
    
      // in the class Point for 4 float variables are declared;
      float w, x, y, z;
    
      // nothing.. 
      Point4() {
      }
    
      // ?? 4 float variables are set to someting? or prepared to be set to something?
      Point4(float w, float x, float y, float z) {
        set(w, x, y, z);
      }
    
      // Why ww, xx, yy, zz? 
      Point4 set(float ww, float xx, float yy, float zz) {
        w = ww;
        x = xx;
        y = yy;
        z = zz;
    
        // returns the new assignment, but why to assign to ww, xx, yy? 
        return this;
      }
    
     // @ SafeVarargs necessary?
     // is this part iterating over the array? (looking for anything incrementing here), 
     // how does it acces the "final Point4[]-Lists" from the beginning? 
     // for what to the three points after the float stand for ? --> "get(final float... pts)"
     // "final float[]" is a new array you open and you fill this one with the list... just how?
        final float[] get(final float... pts) {
        if (pts == null || pts.length < 4)  return new float[] { w, x, y, z };
    
        pts[0] = w;
        pts[1] = x;
        pts[2] = y;
        pts[3] = z;
    
        return pts;
      }
    
     // this is for printing 
      @ Override String toString() {
        return "{ w: " + w + ", x: " + x + ", y: " + y + ", z: " + z + " }";
      }
    }
    
  • i'm guessing the get() just allows you access to the values within the point. i'd skip it and just use point.x etc instead. ditto the set().

    line 44 is the constructor. that's what's being run when you call new Point4() and it just stores the values passed in as parameters into the variables belonging to the instance.

Sign In or Register to comment.