We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hey everybody! I am quite new to processing and I'm desperatly trying to connect the two systems in my code with
each other: one is a swarming system and the other is an arraylist containing spheres;
what i am trying to do is to draw the lines between te spheres, can anybody help me, please!
i am greatful for any advise!
thanks!
import toxi.geom.*;
import controlP5.*;
import peasy.*;
PeasyCam cam;
ArrayList manyPams;
//ControlP5 MControl;
int bColor = 100;
float envSize = 300;
void setup(){
size (800,800,P3D);
cam = new PeasyCam(this,800);
//INITIALIZE
manyPams = new ArrayList();
//MControl = new ControlP5(this);
//Slider s = MControl.addSlider("bColor", 0, 255, 100, 10,10, 120,20);
for(int i = 0; i < 800; i++){
Vec3D o = new Vec3D(random(-envSize,envSize),random(-envSize,envSize),random(-envSize,envSize));
//Vec3D v = new Vec3D(random(-5,5),random(-5,5),random(-5,5));
Pam myPam = new Pam(o); //--> calls myBall(instance) from class ball
manyPams.add(myPam);
}
}
void draw(){
background(255);
for(int i = 0; i < manyPams.size() ; i++){
Pam mP = (Pam) manyPams.get(i);
mP.run();
}
}
//_______________________________________________________________________________________________________________
class Pam {
// GLOBAL VARIABLES
float velX = random(-3,3);
float velY = random(-3,3);
Vec3D pos = new Vec3D (random(-3,3),random(-4,4),random(-10,10));
Vec3D vel = new Vec3D (random(-3,3),random(-4,4),random(-10,10));
Vec3D acc = new Vec3D ();
Vec3D grav = new Vec3D (0,0.2,0);
//CONTRUCTOR
Pam (Vec3D _pos){
pos = _pos;
}
//FUNCTIONS
void run(){
display();
move();
bounce ();
//gravity ();
lineBetween();
flock();
}
void flock(){
separate(4);
cohesion(0.005);
alignment(0.5);
}
void alignment(float magnitude){
Vec3D steer = new Vec3D();
int count = 0;
for(int i =0; i < manyPams.size(); i++){
Pam o = (Pam) manyPams.get(i); //--> call other = one element from the whole collection
float distance = pos.distanceTo(o.pos); //--> distance from ball to all the other elements
if(distance > 0 && distance < 40) {
steer.addSelf(o.vel); //-->ad vel = ad direction to function
count++;
}
}
if(count < 0){
steer.scaleSelf(1.0/count);
}
steer.scaleSelf(magnitude);
acc.addSelf(steer);
}
void cohesion(float magnitude){
Vec3D sum = new Vec3D();
int count = 0;
for(int i =0; i < manyPams.size(); i++){
Pam mP = (Pam) manyPams.get(i); //--> call other = one element from the whole collection
float distance = pos.distanceTo(mP.pos); //--> distance from ball to all the other elements
if(distance > 0 && distance < 30) {
sum.addSelf(mP.pos);
count++;
}
}
if(count > 0){ //--> average
sum.scaleSelf(1.0/count);
}
Vec3D steer = sum.sub(pos); //--> line between our pos and the target.. towards
steer.scaleSelf(magnitude);
acc.addSelf(steer);
}
void separate(float magnitude){ //--> separation
Vec3D steer = new Vec3D();
int count = 0;
for(int i =0; i < manyPams.size(); i++){
Pam mP = (Pam) manyPams.get(i); //--> call other = one element from the whole collection
float distance = pos.distanceTo(mP.pos); //--> distance from ball to all the other elements
if(distance > 0 && distance < 30) {
Vec3D diff = pos.sub(mP.pos); //--> makes vector moving away
diff.normalizeTo(1.0/distance); //--> scale it to the distance... smooth
steer.addSelf(diff); //--> add the diff vector to the empty vector
count++;
}
}
if(count > 0){
steer.scaleSelf(1.0/count);
}
steer.scaleSelf(magnitude);
acc.addSelf(steer);
}
void lineBetween(){
// go through ballCollection
for(int i =0; i < manyPams.size(); i++){
Pam mP = (Pam) manyPams.get(i); //--> call other = one element from the whole collection
float distance = pos.distanceTo(mP.pos); //--> distance from ball to all the other elements
if(distance > 0 && distance < 100) {
stroke(0);
strokeWeight(0.2);
line(pos.x, pos.y, mP.pos.x, mP.pos.y);
}
}
}
void bounce(){
/**if(pos.x > width){
vel.x = vel.x *-1;
}
if(pos.x < 0){
vel.x = vel.x *-1;
}
if(pos.y > height){
vel.y = vel.y *-1;
}
if(pos.y < 0){
vel.y = vel.y *-1;
}
*/
if(pos.x > envSize) pos.x = pos.x - envSize*2;
if(pos.x < -envSize) pos.x = pos.x + envSize*2;
if(pos.y > envSize) pos.y = pos.y - envSize*2;
if(pos.y < -envSize) pos.y = pos.y + envSize*2;
if(pos.z > envSize) pos.z = pos.z -envSize*2;
if(pos.z < -envSize) pos.z = pos.z + envSize*2;
}
void move(){
vel.addSelf(acc);
vel.limit(2);
pos.addSelf(vel);
acc.clear();
}
void display(){
stroke(0);
pushMatrix();
translate(pos.x, pos.y,pos.z);
//noFill();
sphere(2);
popMatrix();
}
}
![image alt text](![image alt text](--))
Answers
you can use ctrl-t in the IDE of processing to auto-format your code
I am not sure if I understand your code (which is my fault, the code is very good).
you wrote
where can I see this in the code?
Pam / manyPams are the swarm.
Where is the ArrayList of spheres?
Also the image didn't get through, the way you formatted it it's part of the code
;-)
Hello
inside your function "lineBetween", try to replace this line
line(pos.x, pos.y, mP.pos.x, mP.pos.y);
by this line
line(pos.x, pos.y, pos.z, mP.pos.x, mP.pos.y, mP.pos.z);
because sphere and all the stuff in your code are in 3D, then the "line" function should be called with XYZ arguments and not only XY
in this version we have connections
it's rather slow now.........
see **** in draw()
By the way, I think that 800 sphere is a bit too much to do what you want. Because each sphere compute its distance relative to other sphere, then it represents 800 x 800 = 640 000 computations for each frame - it's a lot ! - , then it probably represents thousands of new lines for each frame. It could work if you want to render your movie frame by frame and then make a frame-sequence with it, but I'm almost sure it will run very slowly in real time.
Actually, you maybe can do it if you create a "quadtree" in 3D. It means that you have to represents the world-space as a "virtual-abstract-cube" composed of smaller "virtual-abstract-cube" that contain some spheres.
For example a cube of 10x10x10
Then you have to find all the cubes containing some spheres, and for each of them (cube), you can now apply the distance computation for the sphere contained in it.
It may be looks a bit complicated but the amount of computations fall down if you do that because you're only checking the sphere relative to other spheres that are close to the first one. From 640 000 computation, it could fall down to 5-6000 I think (it depends on the size of your world-space but I count 7-8 spheres close to each sphere )
The amount of computation the QuadTree3D need is not so huge, it represents a few lines using the modulo operator to divide the space/position XYZ into small parts and know in what cube is located each sphere
Good luck !
I did an example because it's not so obvious, and it runs perfectly with 800 3D objects that move in the same time ! :D
In my example, I use spheres with the lowest level of quality (then it draw something like a tetrahedron instead of a sphere) because I'm working on laptop and sphere was too complex with its CPU. You need just to change the sphereDetail to adjust the "resolution" of the sphere.
Here the code :
You need to adjust the amount of space-division and the maximum number of sphere by cube to get the result you need
I just see that I obtain a better result if I use bigger cube (because there is a larger probabilité that it contains some sphere ; but if you use bigger cube, you need to accept a larger amount of sphere per cube)
quadtree = new Quadtree3D(3,3,3,width,height,1000,800,100,spheres);
The first "3,3,3" means "divide the space in 3 parts on the X-axis ; in 3 parts on Y-axis and 3 parts on the Z-axis.
"width, height, 1000" represents respectivly the width, height and depth of the space-world
"800" is the amount of spheres
"100" is the amount maximum of sphere contained by one cube
In my previous message, my quadtree was instanciate like that
quadtree = new Quadtree3D(10,10,10,width,height,1000,800,30,spheres);
so the space was divided in 10x10x10 cubes and each one could store 30 spheres. Bu because sphere are moving and cube are small enough, there is not so much collision detected inside of them. That's why I tryed to reduce the amount of space-division and increase the amount of sphere by cube.
The results are good enough I think :)
EDIT : hmmmmm, actually it works really good without a quadtree.... :D Processing is definitly a powerfull tool.
But the quad tree in that case allow you to choose how much lines you want to draw and still keeping a good repartition of them, then you can keep some ressources for other stuff.
@fanthomas your code uses a 3D array of cubes for space partitioning. So this code is not using a quadtree or an octree (3D equivalent cube has 8 children). This could cause confusion if carla_kunterbunt wants to take your suggestion further and does some searching.
In your code you can replace line 118 with
map3D = new AbstractCube[divisionX][divisionY][divisionZ];
and delete lines 147 and 149.
In the collision detection double loop in lines 202 to 209 inclusive you are doing twice as many tests as necessary and you should replace these lines with
You might want to add some comments. :)
Hello Quark,
"In your code you can replace line 118"
Thank you ! I didn't know I could to that :)
" So this code is not using a quadtree or an octree" You're right, I didn't know that
"you are doing twice as many tests as necessary " You're right again :)
Waow ! I'm impressed ! I didn't know that way to process. I used to do more complex stuff to solve this problem. Actually, at the beginning, I was going to tell you "I think your code is incorrect" but when I tryed to explain why it was incorrect, I understood why it was correct :)
Thanks a lot !
If you are interested and if you enable applets in your browser here are a couple of examples I created
City Patrol - simple 2D array cell partitioning (this comes with the AI for Games library)
Quadtree demonstrator - dynamic quadtree demonstrator. (I have also created a dynamic Octree demonstrator).
If anyone wants the Octree implementation I am willing to make it available, after I have documented the source code :)
I can't see your demo Don't know why but it doen't work (java looks to be enabled....)
I also made a quadtree before (in AS3) http://beginfill.com/collisionMap/
it's first time I try to do it in 3D :)
guys thank you so much!!! this is really awsome work!! i hope with a litte more nightshifts somehow i can get the coding stuff =) thank you also for the quadtree, i have never used this one before, i will look into it...
i didn't write the code on my own, it's picked together from different codes and tutorials i found tough;
one more big THANK YOU!!