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 › 3d arc - static/physics suggestions please
Pages: 1 2 
3d arc - static/physics? suggestions please (Read 7523 times)
Re: 3d arc - static/physics? suggestions please
Reply #15 - Jun 14th, 2010, 9:23am
 
Nice!! Thank you! Processing is great by itself, but indeed the greatest thing is the community around it.

So... I think I found an expression that can generate control points for a visually acceptable bezier edge between any two points on a sphere. The code is below.

But I still can't draw an arc between the two points that's on the sphere itself; like representing the shortest path between them. I'm trying to use the "arc()" function but I still didn't manage to position both points at the XY plane at the same time to draw the arc (since the function only accepts 2d coordinates). I'm still trying so, if anyone have ideas, I'm open. Smiley

Thank you very much!!

Note: changing "debug" to "true" shows some details.

Code:

/* bezier edges on a sphere */
/* author: rafael.messias   */

import processing.opengl.*;
import javax.media.opengl.*;

// main parameters
color sphereColor = color(10, 10, 10);
int sphereAlpha = 200;
int sphereRadius = 200;
boolean debug = false;
int vsize = 10;
int esize = 5;

// global variables
float cx, cy, cz;
float mx, my;
float dx, dy;
float anglex = 0, angley = 0;
float values[][] = new float[vsize][6];
float edges[][] = new float[esize][8];

void setup() {
 size(600, 600, P3D);

 cx = width/2;
 cy = height/2;
 cz = 0.0f;

 float fi, theta;
 for (int i = 0; i < vsize; i++) {
   // nodes' random positions
   fi = random(0, 360);
   theta = random(0, 360);
   values[i][0] = sphereRadius * sin(radians(fi)) * cos(radians(theta));
   values[i][1] = sphereRadius * sin(radians(fi)) * sin(radians(theta));
   values[i][2] = sphereRadius * cos(radians(fi));
 }

 for (int i = 0; i < esize; i++) {
   // edges' random nodes
   int v1 = int(random(0, vsize));
   int v2 = int(random(0, vsize));

   edges[i][0] = v1;
   edges[i][1] = v2;

   // calculating control points
   float x1 = values[v1][0];
   float y1 = values[v1][1];
   float z1 = values[v1][2];
   float x2 = values[v2][0];
   float y2 = values[v2][1];
   float z2 = values[v2][2];
   float dist1 = dist(x1, y1, z1, x2, y2, z2);

   float u = x2 - x1;
   float v = y2 - y1;
   float w = z2 - z1;  

   float t = 0.5;
   float ax = (x1 + (t * u));
   float ay = (y1 + (t * v));
   float az = (z1 + (t * w));
   float dist2 = dist(0, 0, 0, ax, ay, az);

   t = (dist1 / dist2) / 1.5f; // play with this constant

   float cx1 = (x1 + (t * ax));
   float cy1 = (y1 + (t * ay));
   float cz1 = (z1 + (t * az));    
   edges[i][2] = cx1;
   edges[i][3] = cy1;
   edges[i][4] = cz1;

   float cx2 = (x2 + (t * ax));
   float cy2 = (y2 + (t * ay));
   float cz2 = (z2 + (t * az));    
   edges[i][5] = cx2;
   edges[i][6] = cy2;
   edges[i][7] = cz2;
 }
 
}

void draw() {
 background(0);

 translate(cx, cy, cz);
 rotateX(-mouseY*0.02);
 rotateY(mouseX*0.02);  
 pushMatrix();  

 noStroke();
 for (int i = 0; i < vsize; i++) {    
   pushMatrix();    
   fill(255, 0, 0, 255);
   translate(values[i][0], values[i][1], values[i][2]);
   sphere(5);
   popMatrix();
 }

 int v1, v2;
 float x1, y1, z1, x2, y2, z2;
 float cx1, cy1, cz1, cx2, cy2, cz2;
 for (int i = 0; i < esize; i++) {    
   pushMatrix();
   
   v1 = (int) edges[i][0];
   v2 = (int) edges[i][1];
   
   x1 = values[v1][0];
   y1 = values[v1][1];
   z1 = values[v1][2];
   
   x2 = values[v2][0];
   y2 = values[v2][1];
   z2 = values[v2][2];

   cx1 = edges[i][2];
   cy1 = edges[i][3];
   cz1 = edges[i][4];

   cx2 = edges[i][5];
   cy2 = edges[i][6];
   cz2 = edges[i][7];

   noFill();
   stroke(255, 255, 255);
   bezier(x1, y1, z1, cx1, cy1, cz1, cx2, cy2, cz2, x2, y2, z2);

   if (debug) {
     stroke(0, 0, 255);
     line(x1, y1, z1, x2, y2, z2);      
     float t = 0.5;
     float u = x2 - x1;
     float v = y2 - y1;
     float w = z2 - z1;
     float ax = (x1 + (t * u));
     float ay = (y1 + (t * v));
     float az = (z1 + (t * w));
     stroke(255, 255, 0);
     line(0, 0, 0, ax, ay, az);
     stroke(0, 255, 0);
     line(x1, y1, z1, cx1, cy1, cz1);
     line(x2, y2, z2, cx2, cy2, cz2);
   }
   popMatrix();
 }    

 noStroke();
 fill(sphereColor, sphereAlpha);
 popMatrix();  
 sphere(sphereRadius);

}
Re: 3d arc - static/physics? suggestions please
Reply #16 - Jun 14th, 2010, 9:45am
 
As for the arc between 2 points on the sphere surface, just take the modified method below and replace in my other demo (Arc3DSphere):

Code:
/**
* Computes arc points between the given points on the sphere surface (or just above it).
* Points A & B need to be in spherical coords: X=radius, Y=lon, Z=lat
*/
List createNewArc(Vec3D a, Vec3D b) {
 Vec3D ac=a.copy().toCartesian();
 Vec3D bc=b.copy().toCartesian();
 // sample line from A -> B in cartesian space at fixed interval (e.g. 60 steps)
 List points=new Line3D(ac,bc).splitIntoSegments(null,ac.distanceTo(bc)/60,true);
 // transform each point into spherical domain,
 // set radius and then back into cartesian space
 for(int i=points.size()-1; i>=0; i--) {
   Vec3D p=((Vec3D)points.get(i)).toSpherical();
   // set radius slightly larger than sphere
   // to avoid rendering issues/artifacts
   p.x=GLOBE_RAD*1.01;
   p.toCartesian();
 }
 return points;
}


This basically samples the AB line in cartesian space and projects the tweened points back onto the sphere surface...
Re: 3d arc - static/physics? suggestions please
Reply #17 - Jun 14th, 2010, 10:38am
 
Wow... thanks Toxi! I'm learning more CG in a couple of days here than I've learned with the whole semester course...  Grin
Pages: 1 2