4d Sphere

Hi, I'm trying to make a 4d sphere and I'm running into some problems. Right now I'm using a 4d polar coordinate system and I think these points are accurate. I think the problem is when I try to convert the 4d Cartesian coordinates to 3d ones that I can use in P3D. I'm currently doing this by storing each point as a 3d vector then using the 4th dimension to scale that. It doesn't look like any kind of sphere (its not round). Anyone know why or how I could do this?

float scale = TAU/20;
float r = 500; 
float a = 0;
PVector[][][] vertexes = new PVector[10][10][20];
void setup(){
  size(1080,720,P3D);
}
void draw(){
  translate(width/2,height/2,-200);
  a+= .01;
  background(0);
  //rotation
  float beta = map(a,0,2,0,TAU);
  float psi = map(a,0,3,0,TAU);
  float gamma = map(a,0,4,0,TAU);
  for(float theta = 0; theta < PI ; theta += scale){
    for(float phi = 0; phi < PI ; phi += scale){
      for(float alpha = 0; alpha < TAU ; alpha += scale){        
        float w = r * sin(theta+beta) * sin(phi+psi) * cos(alpha+gamma) + (r*1.5);
        float x = r * sin(theta+beta) * sin(alpha+gamma) * sin(phi+psi);
        float y = r * sin(theta+beta) * cos(phi+psi);
        float z = r * cos(theta+beta); 
        w  =  1/( abs(w)/100 + 1);        
        x *= w;
        y *= w;
        z *= w;        
        PVector v = new PVector(x,y,z);   
        //this just goes through every point in a way that is easy to change and draws lines along these points       
        vertexes[int(map(theta ,0,PI,0,10))][int(map(phi ,0,PI,0,10))][int(map(alpha ,0,TAU,0,20))] = v   ;    
        if(int(map(theta,0,PI,0,10)) < 9 && int(map(phi,0,PI,0,10)) < 9 && int(map(alpha,0,TAU,0,20)) < 19 && frameCount > 1){                   
          stroke(255,0,0);
          line(x,y,z,vertexes[int(map(theta+scale,0,PI,0,10))][int(map(phi,0,PI,0,10))][int(map(alpha,0,TAU,0,20))].x,vertexes[int(map(theta+scale,0,PI,0,10))][int(map(phi,0,PI,0,10))][int(map(alpha,0,TAU,0,20))].y,vertexes[int(map(theta+scale,0,PI,0,10))][int(map(phi,0,PI,0,10))][int(map(alpha,0,TAU,0,20))].z); 
          stroke(0,255,0);
          line(x,y,z,vertexes[int(map(theta,0,PI,0,10))][int(map(phi,0,PI,0,10))][int(map(alpha+scale,0,TAU,0,20))].x,vertexes[int(map(theta ,0,PI,0,10))][int(map(phi,0,PI,0,10))][int(map(alpha+scale,0,TAU,0,20))].y,vertexes[int(map(theta ,0,PI,0,10))][int(map(phi,0,PI,0,10))][int(map(alpha+scale,0,TAU,0,20))].z); 
          stroke(0,0,255);
          line(x,y,z,vertexes[int(map(theta,0,PI,0,10))][int(map(phi+scale,0,PI,0,10))][int(map(alpha,0,TAU,0,20))].x,vertexes[int(map(theta ,0,PI,0,10))][int(map(phi+scale,0,PI,0,10))][int(map(alpha,0,TAU,0,20))].y,vertexes[int(map(theta ,0,PI,0,10))][int(map(phi+scale,0,PI,0,10))][int(map(alpha,0,TAU,0,20))].z); 
        }        
      }
    }
  }
}
Tagged:

Answers

  • line(x,y,z,vertexes[int(map(theta+scale,0,PI,0,10))][int(map(phi,0,PI,0,10))][int(map(alpha,0,TAU,0,20))].x,vertexes[int(map(theta+scale,0,PI,0,10))][int(map(phi,0,PI,0,10))][int(map(alpha,0,TAU,0,20))].y,vertexes[int(map(theta+scale,0,PI,0,10))][int(map(phi,0,PI,0,10))][int(map(alpha,0,TAU,0,20))].z);

    Use local variables rather than calling the same map 10 times

  • Ok I did that but it still does the same thing

    float scale = TAU/20;
    float r = 2000; 
    float a = 0;
    PVector[][][] vertexes = new PVector[10][10][20];
    void setup(){
      size(1080,720,P3D);
    }
    void draw(){
      translate(width/2,height/2,-200);
      a+= .01;
      background(0);
      //rotation
      float beta = map(a,0,2,0,TAU);
      float psi = map(a,0,3,0,TAU);
      float gamma = map(a,0,4,0,TAU);
      for(float theta = 0; theta < PI ; theta += scale){
        for(float phi = 0; phi < PI ; phi += scale){
          for(float alpha = 0; alpha < TAU ; alpha += scale){        
            float w = r * sin(theta+beta) * sin(phi+psi) * cos(alpha+gamma) + (r*1.5);
            float x = r * sin(theta+beta) * sin(alpha+gamma) * sin(phi+psi);
            float y = r * sin(theta+beta) * cos(phi+psi);
            float z = r * cos(theta+beta); 
            w  =  1/( abs(w)/100 + 1);        
            x *= w;
            y *= w;
            z *= w;        
            PVector v = new PVector(x,y,z);   
            //this just goes through every point in a way that is easy to change and draws lines along these points 
            int t = int(map(theta,0,PI,0,10));
            int p = int(map(phi,0,PI,0,10));
            int a = int(map(alpha,0,TAU,0,20));        
            int t1 = int(map(theta + scale ,0,PI,0,10));
            int p1 = int(map(phi + scale,0,PI,0,10));
            int a1 = int(map(alpha + scale,0,TAU,0,20));       
            vertexes[t][p][a] = v   ;    
            if(t < 9 && p < 9 && a < 19 && frameCount > 1){                   
              stroke(255,0,0);
              line(x,y,z,vertexes[t1][p][a].x,vertexes[t1][p][a].y,vertexes[t1][p][a].z); 
              stroke(0,255,0);
              line(x,y,z,vertexes[t][p1][a].x,vertexes[t][p1][a].y,vertexes[t][p1][a].z); 
              stroke(0,0,255);
              line(x,y,z,vertexes[t][p][a1].x,vertexes[t][p][a1].y,vertexes[t][p][a1].z); 
            }        
          }
        }
      }
    }
    
  • How exactly is projection from 4D to 3D coordinates even done (in mathematical terms maybe)? If you were to explain that, I'm sure a lot of us will be able to help you out more easily. After all, not all of us know how that even works (though there may be someone who can help you).

    In a simpler question, what's the, um, formula you use to convert from a 4D Vector to a 3D Vector when projecting?

  • The 4d perspective looks fine. It's just one more than a 3d perspective transform.

    It's all the maps that I suspect. Don't forget that a value outside of your input domain will get you a value outside of the output range.

    An easy check would be to calculate all the magnitudes of the points of your sphere (before perspective) using 4d pythagorus. They should all be equal.

  • Add peasycam to add some flexibility exploring your sketch. Partial code below based on your last provided code.

    Kf

    import peasy.PeasyCam;
    
    PeasyCam cam;
    
    float scale = TAU/20;
    float r = 2000; 
    float a = 0;
    PVector[][][] vertexes = new PVector[10][10][20];
    void setup() {
      size(1080, 720, P3D);
      cam = new PeasyCam(this, width/2, height/2, -200,400);
    }
    
  • I've already checked the 4d polar coordinates and they are all on a 4d sphere. Also, I've tried just using points instead of lines and it creates a similar sort of image. And lord of the galaxy, it is similar to transforming from 3d to 2d. You can just use the 3d coordinate to scale it and make it look further away.

  • Can you post a screen grab?

    (Sorry, can't run code, am on my phone)

  • edited February 2018

    c1 Am I wrong in assuming it should look spherical? circles and spheres are so I just assumed hyper spheres should be too.

  • Answer ✓

    That suggests to me that one of your ranges is wrong. Think of a 3d sphere. Longitude goes from -180 to 180 (-pi to pi), latitude goes from -90 to 90 (-pi/2 to pi/2). Yours goes from 0 to two pi and from 0 to pi.

    I'd be tempted to pick a bunch of random 4d dots, normalise them so they are all on the surface of a 4d sphere and see how that looks.

  • (don't get me started on tau...)

  • Ok I think that worked thanks.

  • Can you share the final code?

  • edited February 2018

    Regarding how it ought to look: I believe that, just as every planar (2D) cross-section of a sphere is a circle, every volumetric (3D) cross-section of a hypersphere is a sphere.

    However, those circles or spheres can get smaller if you aren't bisecting the shape. So the cross-sectional series over a sphere should be a circle growing then shrinking; for a hypersphere it should be a sphere growing and shrinking.

Sign In or Register to comment.