orientate cubes to face / target a common point

I have a sphere covered with a number of small cubes and I want the cubes to be orientated so their z axis points to the center of the sphere... how do I go about doing this ? I'm not having much luck with forum search, but somebody must have asked this before. Can anyone point to an example here or elsewhere ?

Thanks in advance, mala

Answers

  • It will be great if you can post what you have. The key words for your task are:

    rotate()
    pushMatrix()
    popMatrix()

    Using rectMode(CENTER) should make things a bit easier.

    The last part is figuring out the rotation angles to be used for each cube (I assume you know where the center of each cube is on the sphere). You need spherical coordinate system: https://forum.processing.org/two/search?Search=spherical

    Kf

  • edited March 2017

    sorry for the misleading description, there is no actual sphere, the cubes are arranged _as if _they are on the surface of a sphere, the XYZ positions are set from a CSV file read into a Table, so I do know their positions. The cubes themselves are a custom PShape. The relevant section of code I have so far... it's figuring the angles that I'm lost with:

        pushMatrix();
        translate(this.pos.x, this.pos.y, this.pos.z);
        rotateX(angleX);
        rotateY(angleY);  
        rotateZ(angleZ);   
        shape(cubeNode);
        popMatrix();
    

    I know nothing about the Spherical coordinate system yet, so looks like i have a bit of reading and learning to do!

  • edited March 2017

    this is as close as I've got so far, something still a bit funky going on with some of the cubes for some reason

              pushMatrix();
                float angleX = atan2(this.pos.y,this.pos.z);
                float angleY = atan2(this.pos.x , this.pos.z);
    
                translate(this.pos.x, this.pos.y, this.pos.z); 
    
                rotateY(angleY);
                rotateX(angleX); 
    
                shape(cubeNode);
                popMatrix();
    
  • This is a start: http://mathworld.wolfram.com/SphericalCoordinates.html

    Would this solve your problem?

    Kf

  • thank Kf, tbh I'm getting pretty lost with that ,I do have a lot to learn. This is what I've managed to muddle through with so far:

    pushMatrix();
        float posZstate;
    
        if (this.pos.z > 0) {
        posZstate = -this.pos.z;
      }else {
        posZstate = this.pos.z;
      }
    
        float angleX = atan2(this.pos.y, posZstate);
        float angleY = atan2(-this.pos.z, this.pos.x);
    
        translate(this.pos.x, this.pos.y, this.pos.z); 
        rotateY(angleY+radians(90));
        rotateX(angleX);
        shape(nodeCube);
        popMatrix();
    

    the 'funky' cubes were the ones in a -Z position, kinda fixed that, but still have some that are pretty much bang on the XY plane that are not behaving. kinda feel like I need to remap either the this.pos.Z or the angleX itself...but not sure what to.

  • Check the following post: https://forum.processing.org/two/discussion/20688/plotting-points-on-a-sphere#latest

    If you run either jeremydouglass or Chrisir's code at the beginning of the chain, you will see how to do the x-y-z to theta-phi-r transformation. You can click and drag the mouse on the x or y direction and you will see changes in the number of points being plotted along theta or phi angles projections.

    Kf

  • Hi Kf, I'm obviously missing something there, as I can only see that the code in that thread is positioning the spheres not rotating them to align an axis to look at center of sphere.

    Here is a simplified cut down version of my code which I hope shows the problem, needs peasycam and the csv file:

    import peasy.*; 
    PeasyCam cam;
    
    Table csvTable;
    
    
    void setup() 
    {
      csvTable = loadTable("cubePositions.csv"); // load csv file of positions to table 
      // ------------------------------------- CAM SETTINGS ----------------------------------------------------
      size(800, 600, P3D);
      cam = new PeasyCam(this, 0, 0, 0, 280);  
      cam.setMinimumDistance(100);
      cam.setMaximumDistance(280);
      cam.setYawRotationMode();  // cam will only rotate around the rigs(lookAt point) Y axis UNLESS shift is held
    }
    
    
    void draw() 
    {
      background(0);
      lights(); 
    
      for (int i = 0; i <156; i++) {
        float X= csvTable.getFloat(i, 0)-128;
        float Y = (csvTable.getFloat(i, 1)-128)* -1;
        float Z = (csvTable.getFloat(i, 2)-128)* -1;
        float posZstate;
        if (Z > 0) {
          posZstate = -Z;
        } else {
          posZstate = Z;
        }
        float angleX = atan2(Y, posZstate);
        float angleY = atan2(-Z, X);
        pushMatrix();
        translate(X, Y, Z);
        rotateY(angleY+radians(90));
        rotateX(angleX);
        stroke(3);
        fill(255);
        box(4,4,60);
    
        popMatrix();
    
      }
      noStroke();
      fill(255,0,0);
      sphere(50);
    }
    

    To make it easier to see the problem cubes, the cubes are elongated and there is a large sphere at the center, cubes should all point to center of sphere.

    cubePositions.csv : (can't see how I would upload file here so copy to a new file)

    128,19,59
    159,19,82
    191,19,106
    179,19,143
    167,19,181
    128,19,181
    88,19,181
    76,19,143
    64,19,106
    96,19,82
    128,45,36
    159,40,49
    191,40,72
    214,45,98
    211,40,133
    199,40,170
    181,44,200
    147,39,208
    108,39,208
    74,44,200
    56,39,170
    44,40,133
    41,45,98
    64,40,72
    96,40,49
    128,71,13
    159,66,26
    191,61,39
    214,66,65
    236,71,91
    233,65,126
    231,60,160
    213,65,189
    195,70,219
    161,65,227
    128,60,235
    94,65,227
    60,70,219
    42,65,189
    24,60,160
    22,65,126
    19,71,91
    41,66,65
    64,61,39
    96,66,26
    147,100,9
    179,94,22
    211,94,45
    233,99,72
    246,99,109
    243,94,143
    231,94,181
    222,99,210
    181,98,234
    147,93,242
    108,93,242
    74,98,234
    42,99,210
    24,94,181
    12,94,143
    9,99,109
    22,99,72
    44,94,45
    76,94,22
    108,100,9
    128,128,6
    167,128,6
    199,128,29
    231,128,52
    243,128,89
    255,128,127
    243,127,164
    231,127,202
    199,127,225
    167,127,248
    128,127,248
    88,127,248
    56,127,225
    24,127,202
    12,127,164
    0,128,127
    12,128,89
    24,128,52
    56,128,29
    88,128,6
    147,162,12
    181,157,20
    213,156,43
    231,161,73
    243,161,110
    246,156,145
    233,156,182
    211,161,208
    179,161,232
    147,155,245
    108,155,245
    76,161,232
    44,161,208
    22,156,182
    9,156,145
    12,161,110
    24,161,73
    42,156,43
    74,157,20
    108,162,12
    128,195,19
    161,190,27
    195,185,35
    213,190,64
    231,195,94
    233,190,128
    236,184,162
    214,189,189
    191,194,215
    159,189,228
    128,184,241
    96,189,228
    64,194,215
    41,189,189
    19,184,162
    22,190,128
    24,195,94
    42,190,64
    60,185,35
    94,190,27
    147,216,46
    181,211,54
    199,215,83
    211,215,121
    214,210,155
    191,215,182
    159,215,205
    128,210,218
    96,215,205
    64,215,182
    41,210,155
    44,215,121
    56,215,83
    74,211,54
    108,216,46
    128,236,73
    167,236,73
    179,236,111
    191,236,148
    159,236,171
    128,236,194
    96,236,171
    64,236,148
    76,236,111
    88,236,73
    147,246,100
    159,245,138
    128,245,161
    96,245,138
    108,246,100
    128,255,128
    

    That was fun ;)

    Cheers, mala

  • edited August 2017 Answer ✓

    Replace lines 38 and 39 with:

        float theta=atan2(Y,X);  //Restricte -180,180
        float phi=acos(Z/sqrt(X*X+Y*Y+Z*Z)); //Restricte 0,180
        rotateZ(theta);
        rotateY(phi);
    

    So the trick is this. You know the center position of each box on top of the surface. Based on the previous website explaining conversion of Cartesian to spherical coordinates, you need to get theta and phi angles. I apply angle theta first on the Z axis and angle phi on the Y axis and in that specific order (very important).

    Why those angles? Well, if you trace an imaginary line from the center of any cube to the center of the arrangement, you'll get a line of length L = sqrt(x^2+Y^2+Z^) and defined by two angles theta and phi.

    Kf

    P.S. Note to myself: An alternative to peasyCam, use this: camera(map(mouseX,0,width,-width,width),map(mouseY,0,height,-height,height),zc,width>>1,height>>1,0,0,1,0); Notice sketch needs to be translated to its center position.

  • Answer ✓

    ha... just solved it myself by trial and error, this was it:

    for (int i = 0; i <156; i++) {
        float X = map(csvTable.getFloat(i,0),0,255,-128,128); // centering
        float Y = map(csvTable.getFloat(i,1),0,255,128,-128);
        float Z = map(csvTable.getFloat(i,2),0,255,128,-128);
        float angleX = acos(Y / dist(0,0,0,X,Y,Z));
        float angleY = atan2(-Z, X);
    
        pushMatrix();
        translate(X, Y, Z);
        rotateY(angleY+radians(90));
        rotateX(angleX+radians(90));
        stroke(3);
        fill(255);
        box(4,4,12);
    
        popMatrix();
    

    yours is a much neater solution Thanks for sticking with me on this ;)

    Cheers, mala

Sign In or Register to comment.