We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Again: Spinning a Sphere
Page Index Toggle Pages: 1
Again: Spinning a Sphere (Read 1998 times)
Again: Spinning a Sphere
Mar 18th, 2010, 5:57am
 
Hallo Guys,

some couple of days ago I posted a question of how to rotate a 3d sphere, aiming to achieve something near the following effect:

http://www.flickr.com/photos/alexposada/sets/72157623578136140/

Cedric gave me some very helpfull tips how to build a real 3d Sphere, but unfortunately the sphere I end up with wasn^t that agile and flexible as I need it.

So now, I will go even further back to the beginnigs of my sketches, to bring up the level of hardness for you.

This is what I started with:
Code:
float x,y;
float cX, cY;
float rX, rY;
float speed;


void setup()
{
 size(400,400);
 noStroke();
 smooth();
 
 cX = width/2;
 cY = height/2;
 
 rX = 120;
 rY = 50;
 speed = 0.07;
}


void draw()
 {
   fill(0,20);
   rect(0, 0, width, height);
   float phase = frameCount*speed;
   float pointSize = abs(sin((phase+HALF_PI)/2))*10;
   x = cos(phase)*rX+cX;
   y = sin(phase)*rY+cY;
   

   stroke(255);
   strokeWeight(pointSize);
   point(x,y);

 }


A point that cyrcles around an ellipse orbit and leaves a motion trace behind

Than a friend helped me to come up with a formula for building a fake 3d sphere that had the ability to be splited in parts, which is what I wanted.
Code:
void setup()
{
 size(400,400);
 colorMode(RGB,1);
 background(0);
 //  translate(width/2, height/2);
 drawSphere();
 noLoop();
}


void draw()
{
}


void drawSphere()
{
 float posy = height*.25;
 float sizey = height/2;
 int nRings = 29;
 for(int i=1; i<nRings; i++)
 {
   float phase = i*1./nRings;
   float ringCenterPosX = width / 2;
   float ringCenterPosY = posy + (sin(phase*PI+HALF_PI)*.5+.5)*sizey;
   float ringSizeX = sin(phase*PI)*sizey/2;
   float ringSizeY = ringSizeX / 4;
   drawRing(ringCenterPosX, ringCenterPosY, ringSizeX, ringSizeY);
 }
}

void drawRing(float posx, float posy, float sizex, float sizey)
{
 noStroke();
 fill(1,.5);
 int n = 200;
 for(int i=0; i<n; i++)
 {
   float phase = i*1./n;
   float r = 2;
   ellipse(posx + sizex*cos(phase*TWO_PI), posy + sizey*sin(phase*TWO_PI), r,r);
 }
}



THE PROBLEM IS: how can I combine both - the spinning elipse and the form of the sphere, to stimulate this amazing particle motion ?

It^s not easy at all, at least for me, so I will be very greatfull if someone could give me the slightest hint! My time is ticking away......

Thank you in advance and sorry for the monstrous post!

Re: Again: Spinning a Sphere
Reply #1 - Mar 18th, 2010, 5:49pm
 
First of all, it is my opinion that you don't have to 'fake' the sphere: You can draw it in real 3D-space (using x,y,z coordinates) and then use matrix transformations to change the view. You don't even need to do the transformations yourself, you can just use a camera library, like peasycam for example.

Now, what you'r going to need:

1. A function that creates an arc using starting point, starting and ending angles and radius
2. A function that uses the previous one to draw the different slices of the sphere.
3. A function that uses the previous one to draw a sphere (in the case you want multiple spheres, like concentric ones etc.).

So, as a diagram, you code would be:

drawSphere {
 find initial slice y-position and diameter
 (obviously yposition=sphere radius
  and sliceradius=0)
 for number of slices {
   draw current slice (as an arc with starting and ending angles)
   find next slice position and diameter
 }
}

Then you can just change the starting and ending angles and even get a 'rotating' effect!
Or you could wrap all functions in a 'sphere' class with it's own variables so that you get multiple self-updating spheres!
Remember to draw these in real 3D-space, so that you don't have to do any conversions. This way you get any viewing angle by using cameras.
Re: Again: Spinning a Sphere
Reply #2 - Mar 18th, 2010, 11:33pm
 
thats actually what i told him the last time...
i am not sure what wasnt right with it...
what was the problem ?
Re: Again: Spinning a Sphere
Reply #3 - Mar 19th, 2010, 4:50am
 
Hallo yconst and thank you for the detailed answer!

It`s sound a bit too complex to me. I`m still a novice and I`m not aware of the variates of standard functions processing offers and therefor I still cant get the best out of it.... I would therefor ask if there is a pre-defined function that draws arcs and so on, but I dont want to bother you with the small stuff, I guess I can find it in the references....
I have to work my way up to the thing with the cameras, unfortunately I have no clue how to deal with them Sad

----------------------

I start grubbing now, and hopefully dont bother you much...

Thank you once more, appreciate it very much!
Re: Again: Spinning a Sphere
Reply #4 - Mar 19th, 2010, 4:53am
 
Quote:
Cedric wrote on Yesterday at 09:33:
i am not sure what wasnt right with it...
what was the problem ?


Hi Cedric,

well the problem was that I couldn't slice the sphere into peaces (see flickr photos) and implement a trace left of the rotating dots... So yes,
now I`m starting all over again ...

greetings
Re: Again: Spinning a Sphere
Reply #5 - Mar 19th, 2010, 3:42pm
 
Well, i'd suggest again to check out peasycam. It's a great library that lets you just get done with all the camera-related fuss. Check out the examples in the site to get an idea how it works.
Lnk:http://mrfeinberg.com/peasycam/

After you've done that, just try to imagine things in normal 3d-space: Just as if you'd build this sculpture in reality.

So, your basic ingredient would be a flexible function to draw horizontal arcs in various positions/angles.

You can check the processing reference, there are functions to create almost any shape, including a specific one for an arc.

Then you can store the drawing function along with all related variables into an object, so that you can represent each sphere you want to draw with an object.

good luck!

Then you'd repeat that as many times as you want to create a sphere.
Re: Again: Spinning a Sphere
Reply #6 - Mar 20th, 2010, 1:50am
 
fankof wrote on Mar 19th, 2010, 4:53am:
Hi Cedric,

well the problem was that I couldn't slice the sphere into peaces (see flickr photos) and implement a trace left of the rotating dots... So yes,
now I`m starting all over again ...



why not

Code:
void setup() {
 size(600,400,P3D);
 smooth();
 background(255);

}

int radius = 100;
void draw() {
fill(200);
stroke(150);

 translate(width/2,height/2);
 rotateY(radians(mouseX));
 rotateZ(radians(mouseY));
 background(255);

 for (int i = 1; i < 36; i++){
   for (int j = 0; j < 36; j++){
pushMatrix();
strokeWeight(1);
stroke(1);
if(i==20){
 strokeWeight(4);
 stroke(255,0,0);
};
if(j==20){
 strokeWeight(4);
 stroke(255,0,255);
};

float cx = cos(i) * sin(j)*radius ;
float cy = cos(j)*radius;
float cz = sin(i) * sin(j)*radius;

   point(cx,cy,cz);
popMatrix();
   }
 }

}



Re: Again: Spinning a Sphere
Reply #7 - Mar 20th, 2010, 2:36am
 
ok, i see where the problem is, give me some sec
Re: Again: Spinning a Sphere
Reply #8 - Mar 20th, 2010, 3:01am
 
here we go


Code:
void setup() {
size(600,400,P3D);
smooth();
background(255);

}

int radius = 100;
void draw() {
fill(200);
stroke(150);
strokeWeight(3);
int radius = 150;
translate(width/2,height/2);
rotateY(radians(mouseX));
rotateZ(radians(mouseY));
background(255);

for (int k = 0; k < 6; k++){
for (int i = 0; i < 36; i++){
rotateX(TWO_PI/36);
for (int j = 0; j < 36; j++){
rotateY(TWO_PI/36);


stroke(0,20);
strokeWeight(2);
if(i==(frameCount/2)%36){
strokeWeight(5);
stroke(255,0,0);
};

if(j==(frameCount/2)%36){
strokeWeight(5);
stroke(0,0,255);
};

if( k==(frameCount/4)%5){
strokeWeight(2);
stroke(255,0,255);
};


point(radius-(k*30),0,0);

}
}
}

}




Re: Again: Spinning a Sphere
Reply #9 - Mar 20th, 2010, 5:40am
 
yconst,

I`ve built an ellipse with the arc() function:

Code:
arc(height/2,width/2,100,50,0,TWO_PI)  



and combined it with the peasyCam to try out its functions. While rotating, I`ve noticed that the arc is flat Sad
and one other thing that struck me. As I tried to draw not a complete ellipse, but a slice of it with the following:

Code:
arc(height/2,width/2,100,50,[b]30,TWO_PI[/b])  


absolutely nothing was drawn ??!?  Maybe it`s just my maths, that`s bugging it ?


-------------------

Cedric,

your 3D sphere is perfect, but is there a way to also draw just a slice of it and not only full 360?


I have to basic approaches now:

FIRST ONE is my skatch + camera:
Code:



class Sphere {

float ringCenterX,ringCenterY;
float ringSizeX, ringSizeY;
float radius,angle, speed, slice;
float rotation;
int nRings, dRings;
color c;

float x,y;


Sphere(float xpos, float ypos, float radius, int nRings, int dRings, float slice)
{
this.ringCenterX = xpos;
this.ringCenterY = ypos;
this.radius = radius;
this.slice = slice;

this.nRings = nRings;
this.dRings = dRings;
}

void drawSphere()
{

for(int i=1; i<nRings; i++)
{

float phase = i*1./nRings;
ringCenterY = (sin(phase*PI+HALF_PI)*.5+.5)*radius;
ringSizeX = sin(phase*PI)*radius/2;
ringSizeY = ringSizeX/4;
drawRing();
}
}

void drawRing()
{
noStroke();
for(int i=0; i<dRings; i++)
{

float phase = i*slice/dRings-rotation;
x = ringCenterX + ringSizeX*cos(phase*TWO_PI);
y = ringCenterY + ringSizeY*sin(phase*TWO_PI);
fill(100*2, 100*2,100);
ellipse(x,y, 2,2);


}
//rotation += 0.01;
}

void rotateSphere(float speed)
{

rotation +=speed;

}

void moveSphere(float moveX, float moveY)
{
ringCenterX += moveX;
ringCenterY += moveY;

}

}



import peasy.*;

PeasyCam cam;
Sphere sp, sp1,sp2,sp3;
float rotation;

void setup()
{
size(700,500,P3D);
background(0);

cam = new PeasyCam(this, 600);
cam.setMinimumDistance(50);
cam.setMaximumDistance(500);


sp = new Sphere(400,100,180.0, 30, 70,.3);
sp1 = new Sphere(100,100,100.0, 20, 50, .7);
sp2 = new Sphere(200,100,100.0, 10, 100, .7);
sp3 = new Sphere(300,400,100.0, 100, 30, .7);
}

void draw()
{
background(0);
fill(0,100);
rect(0,0,height,width);
rotation = mouseX*1./width;
sp.drawSphere();
sp1.drawSphere();
sp2.drawSphere();
sp3.drawSphere();

sp.rotateSphere(0.02);
sp1.rotateSphere(-0.03);
sp2.rotateSphere(0.2);
sp3.rotateSphere(-0.07);

}



PROBLEM: FLAT, but sphere controll is agile --> sphere slice, angle, speed;


SECOND ONE : Cedric`s 3D Sphere + Camera:
Code:
import peasy.*;

PeasyCam cam;

void setup() {
size(600,400,P3D);
smooth();
background(255);

cam = new PeasyCam(this, 600);
cam.setMinimumDistance(50);
cam.setMaximumDistance(500);

}

int radius = 100;
float rotation = 10;
float speed = 5;

void draw() {
//pushMatrix();
//noStroke();
//fill(200,50); --> I wanted to simulate the leaving trace through transparency, but I couldn't use translate?
//rect(0,0,width,height);
//translate(0.0,0.0,600.0,400.0); --> why cant I use translate here?
//popMatrix();
background(20);
stroke(150);

rotateY(radians(rotation));

for (int i = 1; i < 22; i++){
for (int j = 0; j < 22; j++){
pushMatrix();
strokeWeight(2);
stroke(100*j,100*i,100);
if(i==20){
strokeWeight(4);
stroke(255,0,0);
};
if(j==20){
strokeWeight(4);
stroke(255,0,255);
};

float cx = cos(i) * sin(j)*radius ;
float cy = cos(j)*radius;
float cz = sin(i) * sin(j)*radius;

point(cx,cy,cz);

popMatrix();
}
}
rotation+=speed;

}




Thank you gyus for your further help!
Re: Again: Spinning a Sphere
Reply #10 - Mar 20th, 2010, 6:27am
 
yconst,

is there a formula like the one building a 3d Sphere, but for a 3D ellipse/ring instead ? I would then use it to stack the 3D rings in a 2D sphere form ....

a kind of a crazy mix really, but thats the only thing I`m thinking of now  ?!
Re: Again: Spinning a Sphere
Reply #11 - Mar 20th, 2010, 8:49am
 
sure instead of coloring red you can only draw it...
Re: Again: Spinning a Sphere
Reply #12 - Mar 20th, 2010, 9:39am
 
you can also fade the following points to get a fading like effekt,


Code:
void setup() {
size(600,400,P3D);
smooth();
background(255);

}

int radius = 100;
void draw() {
fill(200);
stroke(150);
strokeWeight(3);
int radius = 150;
translate(width/2,height/2);
rotateY(radians(mouseX));
rotateZ(radians(mouseY));
background(255);

for (int k = 0; k < 6; k++){
for (int i = 0; i < 36; i++){
rotateX(TWO_PI/36);
for (int j = 0; j < 36; j++){
rotateY(TWO_PI/36);
noStroke();
for(int f = 0; f<15; f++){
if(i==(frameCount+f)%36){
strokeWeight(3);
stroke(255,0,f*15,(f*15));
}
}
point(radius-(k*30),0,0);
}
}
}

}





Re: Again: Spinning a Sphere
Reply #13 - Mar 20th, 2010, 5:45pm
 
I combined Cedric's code with a peasycam interface as an alternative:

Code:


import peasy.org.apache.commons.math.*;
import peasy.*;
import peasy.org.apache.commons.math.geometry.*;

PeasyCam cam;
int radius = 100;

void setup() {
size(300,300,P3D);
cam = new PeasyCam(this, 0,0,0,150);

}

void draw() {
fill(200);
stroke(150);
strokeWeight(3);
int radius = 150;
//translate(width/2,height/2);
background(255);

for (int k = 0; k < 6; k++){
for (int i = 0; i < 36; i++){
rotateX(TWO_PI/36);
for (int j = 0; j < 36; j++){
rotateY(TWO_PI/36);
noStroke();
for(int f = 0; f<15; f++){
if(i==(frameCount+f)%36){
strokeWeight(3);
stroke(255,0,f*15,(f*15));
}
}
point(radius-(k*30),0,0);
}
}
}

}


Please note that any transformations in Cedric's drawing loop are in addition to any transformations imposed by the camera. So, essentially by changing the camera angle you are not affecting transformations inside the draw loop; in other words, relations between different shapes etc. will be the same, only viewing angle changes.

Hope it is helpful.
Re: Again: Spinning a Sphere
Reply #14 - Mar 22nd, 2010, 10:55am
 
Thank you guys.
I have achieved something now. It`s still not completely ready but hopefully soon.

I could post the code if you`re interested in the result.


Page Index Toggle Pages: 1