# P3D Vector Spherical Geometry Ball

**URL:** https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083
**Category:** Libraries
**Created:** [September 20, 2019, 8:05am UTC](https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083 "2019-09-20T08:05:46Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![ChristmasCC](https://avatars.discourse-cdn.com/v4/letter/c/898d66/32.png) [@ChristmasCC](https://discourse.processing.org/u/ChristmasCC)
#### Post date: [September 20, 2019, 8:05am UTC](https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083/1 "2019-09-20T08:05:46Z")

</div>

I want to create a Ball that could go bigger and smaller according to the Music Frequency. (I don’t want to use the sphere(), because it doesn’t create the dot points)  
I made it work. But, it is a little bit laggy. At the moment, I could reduce the rows and cols or decrease the player analysis rate to relieve the situation. But, it is still laggy.  
I think the main program is the three loops that I had. I tried to minimize them, but I have no idea what I can do.

Just a little bit more, instead of making the whole ball bigger and smaller. If there is anyway that I could make them like a “wave”? Something like perlin noise.

```auto
/ *****IMPORT LIBRARIES***** /
import peasy.*; // Import Peasy Cam Library. Peasy Cam is a camera library. 
import ddf.minim.analysis.*; // Import Minim Music Library
import ddf.minim.*; // Import Minim Music Library

/ *****Define Some variables**** /
PeasyCam cam;
Minim minim;
AudioPlayer player;
FFT fft;

PVector[][] globe; // Create a Vector array to save all
int total = 50; // Rows and Cols of the ball
float angle; // Auto Rotate Ball
float c; // HSB Dynamic Color

void setup()
{
  size(displayWidth, displayHeight, P3D); // Windows Size Not Correct
  cam = new PeasyCam(this, 600); // Cam Size 600. Initial
  minim = new Minim(this); // Initial Minim

  globe = new PVector[total+1][total+1]; 
  player = minim.loadFile("test.mp3", 128);
  player.loop();
  fft = new FFT( player.bufferSize(), player.sampleRate() );
}

void draw()
{
  / *****Basic Setups***** /
  background (0);
  fft.forward( player.mix ); // Play the music forward

  / *****START DRAWING THE BALL***** /
  angle += PI/18; // + 10 Degree 
  rotateX(PI/2); // Rotate the Ball along the X 
  rotateY(angle); // Rotate the Ball along the Y with 10 degree 
  colorMode(HSB); // Set Color Mode to HSB
  if (c >= 255) // Increase the c 
  {
    c = 0;
  } else
  {
    c++;
  }
  stroke(c, 255, 255); // Hue/Saturation/Brightness. Change the HUE and keep Saturation and Brighness 255
  float r = 200; // Radius of the ball
  for (int a = 0; a < fft.specSize(); a++)
  {
    / *****
    
     Complicated Spherical Geometry Calculation
     From YouTube The Coding Train: Spherical Geometry.
     
     ***** /
    for (int i = 0; i < total+1; i++)
    {
      float lon = map(i, 0, total, -PI, PI);
      for (int j = 0; j < total+1; j++)
      {

        float lat = map(j, 0, total, -HALF_PI, HALF_PI);
        float x = r * sin(lon) * cos(lat);
        float y = r * sin(lon) * sin(lat);
        float z = r * cos(lon);
        globe [i][j] = new PVector(x, y, z);

        / *****
         Returns the Perlin noise value at specified coordinates. 
         Perlin noise is a random sequence generator producing a more natural, 
         harmonic succession of numbers than that of the standard random() function. 
         ***** /
        point(x*noise(fft.getFreq(a)), y*noise(fft.getFreq(a)), z*noise(fft.getFreq(a)));
      }
    }
  }
}

```

---

<div class="post-metadata">

### Author: ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)
#### Post date: [September 20, 2019, 10:19am UTC](https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083/3 "2019-09-20T10:19:46Z")

</div>

65 \* 51 \* 51 loop might give you that LAG

try more easy first:

```auto
import peasy.*; // Import Peasy Cam Library camera library. 
import ddf.minim.*; // Import Minim Music Library
import ddf.minim.analysis.*;

PeasyCam cam;
Minim minim;
AudioPlayer player;
FFT fft;

void setup_sound() {
  minim = new Minim(this);
  player = minim.loadFile("groove.mp3", 1024);
  player.loop();
  fft = new FFT( player.bufferSize(), player.sampleRate() );
  println("fft.specSize: "+fft.specSize());
}

int total = 25;
float r0 =30, zoom = 0.5;

void setup() {
  size(500, 500, P3D);
  stroke(200, 0, 0); //noStroke();
  strokeWeight(5);
  noFill();
  setup_sound();
  cam = new PeasyCam(this, 100);
}

void draw() {
  background(200, 200, 0);
  fft.forward( player.mix );
  surface.setTitle(nf(frameRate, 0, 1)+"FPS");
  ball();
}

void ball() {
  float r=0;
  for (int i = 0; i < total; i++) {
    float lon = map(i, 0, total, -PI, PI);
    for (int j = 0; j < total; j++) {
      r = r0 + zoom * fft.getBand(j);//(i+i*j);
      float lat = map(j, 0, total, -HALF_PI, HALF_PI);
      float x = r * sin(lon) * cos(lat);
      float y = r * sin(lon) * sin(lat);
      float z = r * cos(lon);
      point(x, y, z);
    }
  }
}

```

works here ( Win10 / Processing 3.5.3 / medium hardware ) with 50 FPS  
i try stay as close as possible to your example, but actually not get why the  
sound analysis FFT must again mixed with noise, so i skipped that

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [September 20, 2019, 10:29am UTC](https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083/4 "2019-09-20T10:29:21Z")

</div>

A lot of stuff is constant and could be pre-calculated in setup ().

Eg lon  
lat  
and sin \* cos

Hence you can store them in a class (Arraylist of it) and derive from there. Especially map and sin and cos are slow. It’s called look up table. Can be faster.

Only r is really variable

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [September 20, 2019, 1:43pm UTC](https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083/5 "2019-09-20T13:43:02Z")

</div>

I made one version of this idea with a class and an ArrayList of it (not showing here).

Then I shortened this to an Array of PVector:

```auto

// https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083/3

import peasy.*; // Import Peasy Cam Library camera library. 
import ddf.minim.*; // Import Minim Music Library
import ddf.minim.analysis.*; // Import 

PeasyCam cam;
Minim minim;
AudioPlayer player;
FFT fft;

int total = 25;
float r0 =30, 
  zoom = 0.5;

// ArrayList<Data> data = new ArrayList();
PVector[] data = new PVector [total*total];

// ------------------------------------------------------------

void setup() {
  size(500, 500, P3D);
  stroke(200, 0, 0); //noStroke();
  strokeWeight(5);
  noFill();
  setup_sound();
  cam = new PeasyCam(this, 100);
}

void draw() {
  background(200, 200, 0);
  fft.forward( player.mix );
  surface.setTitle(nf(frameRate, 0, 1)+" FPS");
  // text (int(frameRate)+" FPS", 33, 33);
  ball();
}

// ------------------------------------------------------------

void ball() {
  // runs on and on 
  // uses data 
  int j=0;
  float r, x, y, z; 
  for (PVector myData : data) {
    r = r0 + zoom * fft.getBand(j);//(i+i*j);
    x = r * myData.x;
    y = r * myData.y;
    z = r * myData.z;
    //
    point(x, y, z);
    j++;
  }//for
}//func 

// ------------------------------------------------------------

void setup_sound() {
  // runs only ONCE 
  minim = new Minim(this);
  player = minim.loadFile("groove.mp3", 1024);
  if (player!=null) { 
    // success
    player.loop();
    fft = new FFT( player.bufferSize(), player.sampleRate() );
    println("fft.specSize: "+fft.specSize());
    ball_Init();
  } else {
    // error 
    println("Abort");
    exit();
  }//else
}//func

void ball_Init() {
  // runs only ONCE 
  // stripped down version of the old ball to fill the Array data 
  // float r=0;
  int k=0; 
  for (int i = 0; i < total; i++) {
    float lon = map(i, 0, total, -PI, PI);
    for (int j = 0; j < total; j++) {
      //r = r0 + zoom * fft.getBand(j);//(i+i*j);
      float lat = map(j, 0, total, -HALF_PI, HALF_PI);
      //float x = r * sin(lon) * cos(lat);
      //float y = r * sin(lon) * sin(lat);
      //float z = r * cos(lon);
      PVector preparation = new PVector(0, 0, 0);
      preparation.x = sin(lon) * cos(lat);
      preparation.y = sin(lon) * sin(lat);
      preparation.z = cos(lon);
      data[k] = preparation.copy();  
      // point(x, y, z);
      k++;
    }
  }
}
//

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [September 20, 2019, 2:01pm UTC](https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083/6 "2019-09-20T14:01:20Z")

</div>

I have to admit my version is crab.

It’s not faster but it also looks bad, much much worse than yours.

Which is strange, it must be because I store the results in PVector which maybe has not the precision Java works with internally (double?).

E.g. in this line: `float x = r * sin(lon) * cos(lat);`

I could try to store as double… see below.

still looks crab. The amplitude is much smaller than in your sketch

I am sorry I couldn’t be of help

Chrisir

(version where I unsuccessfully store as double (in a class))

```auto

// https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083/3

import peasy.*; // Import Peasy Cam Library camera library. 
import ddf.minim.*; // Import Minim Music Library
import ddf.minim.analysis.*; // Import 

PeasyCam cam;
Minim minim;
AudioPlayer player;
FFT fft;

int total = 25;
float r0 = 30, 
  zoom = 0.5;

ArrayList<Data> data = new ArrayList();

// ------------------------------------------------------------

void setup() {
  size(500, 500, P3D);
  stroke(200, 0, 0); //noStroke();
  strokeWeight(5);
  noFill();
  setup_sound();
  cam = new PeasyCam(this, 100);
}

void draw() {
  background(200, 200, 0);
  fft.forward( player.mix );
  surface.setTitle(nf(frameRate, 0, 1)+" FPS");
  // text (int(frameRate)+" FPS", 33, 33);
  ball();
}

// ------------------------------------------------------------

void ball() {
  // runs on and on 
  // uses ArrayList<Data> data 
  int j=0;
  double r, x, y, z; 
  for (Data myData : data) {
    r = r0 + zoom * fft.getBand(j);//(i+i*j);
    x = r * myData.preparationX;
    y = r * myData.preparationY;
    z = r * myData.preparationZ;
    //
    point((float)x, (float) y, (float) z);
    j++;
  }//for
}//func 

// ------------------------------------------------------------

void setup_sound() {
  // runs only ONCE 
  minim = new Minim(this);
  player = minim.loadFile("groove.mp3", 1024);
  if (player!=null) { 
    // success
    player.loop();
    fft = new FFT( player.bufferSize(), player.sampleRate() );
    println("fft.specSize: "+fft.specSize());
    ball_Init();
  } else {
    // error 
    println("Abort");
    exit();
  }//else
}//func

void ball_Init() {
  // runs only ONCE 
  // stripped down version of the old ball to fill the ArrayList<Data> data 
  // float r=0;
  for (int i = 0; i < total; i++) {
    float lon = map(i, 0, total, -PI, PI);
    for (int j = 0; j < total; j++) {
      //r = r0 + zoom * fft.getBand(j);//(i+i*j);
      float lat = map(j, 0, total, -HALF_PI, HALF_PI);
      //float x = r * sin(lon) * cos(lat);
      //float y = r * sin(lon) * sin(lat);
      //float z = r * cos(lon);
      Data newData = new Data(); 
      newData.preparationX = sin(lon) * cos(lat);
      newData.preparationY = sin(lon) * sin(lat);
      newData.preparationZ = cos(lon);
      data.add(newData); 
      // point(x, y, z);
    }
  }
}

// ================================================================
// classes 

class Data {
  double preparationX = 0;
  double preparationY = 0;
  double preparationZ = 0;
}//class 
//

```

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [September 20, 2019, 6:08pm UTC](https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083/7 "2019-09-20T18:08:31Z")

</div>

Have you thought about creating a single sphere of fixed size and then use [scale](https://processing.org/reference/scale_.html) when rendering it.

---

<div class="post-metadata">

### Author: ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)
#### Post date: [September 20, 2019, 8:33pm UTC](https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083/8 "2019-09-20T20:33:02Z")

</div>

no, my idea was to map the FFT on the sphere:

 ![FFTonSphere](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/e/eafdbe4230bf85e8ee060f4e381302bc6be2d716.png)

just to change its size / scale, BUT  
fft.specSize() \* frameRate /sec  
is too heavy and ?invisible? and anyhow much like the BEAT example

> **@Chrisir test switchable**
>
> ```auto
> import peasy.*; // Import Peasy Cam Library camera library. 
> import ddf.minim.*; // Import Minim Music Library
> import ddf.minim.analysis.*;
> 
> PeasyCam cam;
> Minim minim;
> AudioPlayer player;
> FFT fft;
> 
> void setup_sound() {
> minim = new Minim(this);
> player = minim.loadFile("groove.mp3", 1024);
> player.loop();
> fft = new FFT( player.bufferSize(), player.sampleRate() );
> println("fft.specSize: "+fft.specSize());
> }
> 
> int total = 50;
> float r0 =30, zoom = 0.2;
> float[][][] ksphere = new float[total][total][3];
> boolean atChrisir = false; //true;
> 
> void setup_ksphere() { // @Chrisir
> for (int i = 0; i < total; i++) {
> float lon = map(i, 0, total, -PI, PI);
> for (int j = 0; j < total; j++) {
> float lat = map(j, 0, total, -HALF_PI, HALF_PI);
> ksphere[i][j][0] = sin(lon) * cos(lat);
> ksphere[i][j][1] = sin(lon) * sin(lat);
> ksphere[i][j][2] = cos(lon);
> }
> }
> }
> 
> void setup() {
> size(500, 500, P3D);
> stroke(200, 0, 0); //noStroke();
> strokeWeight(5);
> noFill();
> setup_sound();
> if ( atChrisir ) setup_ksphere();
> cam = new PeasyCam(this, 100);
> }
> 
> void draw() {
> background(200, 200, 0);
> fft.forward( player.mix );
> surface.setTitle(nf(frameRate, 0, 1)+"FPS");
> ball();
> }
> 
> void ball() {
> float x=0, y=0, z=0, lon=0, lat=0, r=0;
> for (int i = 0; i < total; i++) {
> if ( !atChrisir ) lon = map(i, 0, total, -PI, PI);
> for (int j = 0; j < total; j++) {
> r = r0 + zoom * fft.getBand(j);//(i+i*j);
> if ( !atChrisir ) { 
> lat = map(j, 0, total, -HALF_PI, HALF_PI);
> x = r * sin(lon) * cos(lat);
> y = r * sin(lon) * sin(lat);
> z = r * cos(lon);
> } else {
> x = r * ksphere[i][j][0];
> y = r * ksphere[i][j][1];
> z = r * ksphere[i][j][2];
> }
> point(x, y, z);
> }
> }
> }
> 
> ```

---

<div class="post-metadata">

### Author: ![ChristmasCC](https://avatars.discourse-cdn.com/v4/letter/c/898d66/32.png) [@ChristmasCC](https://discourse.processing.org/u/ChristmasCC)
#### Post date: [September 21, 2019, 12:46am UTC](https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083/9 "2019-09-21T00:46:46Z")

</div>

You are super awesome!!! That’s really useful! It works on my laptop as well. Also, if I want to create the ball surface like wave/mountain shape. Do you have any ideas about it? Is it even possible? A surface like this: [https://www.youtube.com/watch?v=IKB1hWWedMk](https://www.youtube.com/watch?v=IKB1hWWedMk). Maybe. (Don’t worry about the Triangle strips)

The complicated part is how to match the FFT with the vertex. So, instead of defining the r in your example. I might need to define the point directly. What do you think? \>\_\<

I think it is going to be a little bit complicated. You don’t really need to give me the whole code. Just some thought should be enough.

---

<div class="post-metadata">

### Author: ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)
#### Post date: [September 21, 2019, 4:25am UTC](https://discourse.processing.org/t/p3d-vector-spherical-geometry-ball/14083/10 "2019-09-21T04:25:19Z")

</div>

> [@ChristmasCC](#):
>
> Also, if I want to create the ball surface like wave/mountain shape. Do you have any ideas about it?

no, but he has:  
[https://www.youtube.com/watch?v=RkuBWEkBrZA](https://www.youtube.com/watch?v=RkuBWEkBrZA) ,  
watch spec. 13 … 24 minutes
