press left mouse to start, play around with the gw and gh sizes and see what effect the number of horizontal and vertical divisions has on framerate. Please note this uses fx2d currently which might not be ideal in all situations.
xxxxxxxxxx
void settings(){
//size(W,H,FX2D);
};
void setup(){
size(1200,660);
pop();
};
void mouse(){
int k = floor(mouseX/gW) + floor(mouseY/gH) * gw;
text(floor(mouseX/gW) + floor(mouseY/gH) * gw,mouseX,mouseY);
qgrid.get(k).fillc();
}
void draw(){
//frameRate(10);
background(42);
for (int i=0;i<grid.size();i++){
if(toggle==1){
grid.get(i).move();
}
grid.get(i).draw();
grid.get(i).updates();
grid.get(i).get_neighbours();
grid.get(i).update_qgrid();
//grid.get(i).reg_collisions();
grid.get(i).quad_collisions();
}
mouse();
fill(0);
text(frameRate,100,100);
text(qgrid.size(),60,10);
};
void mousePressed(){
toggle ++;
if(toggle==2){
toggle = 0;
}
if(toggle==1){
toggle2++;
}
};
//-----------------------------------------------------------------------------------
class object{
PVector a,v,p;
float xpos,ypos,id,x,y;
color col= color(0);
boolean collide = false, update = false, ext = false;
ArrayList<Integer> iid = new ArrayList<Integer>();
ArrayList<Integer> iid2 = new ArrayList<Integer>();
ArrayList<Quad> neighbours = new ArrayList<Quad>();
int t,c;
int t2 = 0;
float r = 30;
object(PVector P,int ID){
p = P;
a = new PVector();
v = new PVector();
id = ID;
};
void move(){
float k = 0.1;
a.x = random(-k,k);
a.y = random(-k,k);
v.add(a);
v.limit(2);
p.add(v);
x = p.x;
y = p.y;
};
void updates(){
if(p.x>W){
p.x = 1;
}
if(p.x<0){
p.x = W-1;
}
if(p.y>H){
p.y = 1;
}
if(p.y<0){
p.y = H-1;
}
x = p.x;
y = p.y;
xpos = floor(p.x/gW);
ypos = floor(p.y/gH);
int pos = int(xpos + ypos * (gw));
if(iid.size()==2&&iid.get(0)!=iid.get(1)){
update = true;
}
else{
update = false;
}
boolean k = iid.contains(pos);
if(iid.size()==0){
iid.add(pos);
}
else{
if(iid.get(iid.size()-1)!=pos){
iid.add(pos);
}}
if(iid.size()>2){
iid.remove(0);
}
//fill(255);
// text(pos,x,y);
};
void draw(){
if(toggle2==0){
collide = false;
}
stroke(0);
if(collide){
//noStroke();
fill(255);
ellipse(p.x,p.y,r,r);
//fill(0);
//text(iid.get(iid.size()-1),x,y);
//strokeWeight(3);
//stroke(0);
//point(x,y);
}
if(!collide){
//noStroke();
fill(0);
ellipse(p.x,p.y,r,r);
//fill(255);
//text(iid.get(iid.size()-1),x,y);
//strokeWeight(3);
//stroke(255);
//point(x,y);
}
};
void update_qgrid(){
//updates the corresponding qgrid array's children with the last id in the iid arraylist
// iid is either of length 1 at the start or of length 2 any time after. If iid is size 2 then you need to check if the perticle crosses a border at anytime by comparing iid(0)
// and iid(1), if they are different then the particle has crossed a border. Therefore update the corresponding previous grid space by removing this id, and update the new grid
// space by adding the id.
if(iid.size()==2){
boolean a = qgrid.get(iid.get(1)).children.contains(this);
boolean b = qgrid.get(iid.get(0)).children.contains(this);
if(!a){
qgrid.get(iid.get(1)).children.add(this);
//qgrid.get(iid.get(1)).fillc();
}
if (b){
int k = qgrid.get(iid.get(0)).children.indexOf(this);
qgrid.get(iid.get(0)).children.remove(k);
}}
if(iid.size()==1){
boolean a = qgrid.get(iid.get(0)).children.contains(this);
if(!a){
//qgrid.get(iid.get(0)).fillc();
qgrid.get(iid.get(0)).children.add(this);
}}
};
void get_neighbours(){
ArrayList<Quad> n = new ArrayList<Quad>();
int cell = iid.get(iid.size() -1);
Quad a = qgrid.get(cell);
Quad topl = index2(int(xpos) - 1, int(ypos) - 1);
Quad top = index2(int(xpos) , int(ypos) - 1);
Quad topr = index2(int(xpos) + 1, int(ypos) - 1);
Quad right = index2(int(xpos) + 1, int(ypos));
Quad btmr = index2(int(xpos) + 1, int(ypos) + 1);
Quad btm = index2(int(xpos) , int(ypos) + 1);
Quad btml = index2(int(xpos) - 1, int(ypos) + 1);
Quad left = index2(int(xpos) - 1, int(ypos) );
// left and top
if(x > a.x && x < a.x + r && y > a.y && y < a.y + r){
if(topl!=null){
boolean k3 = n.contains(topl);
if(!k3){
n.add(topl);
}}
if(top!=null){
boolean k2 = n.contains(top);
if(!k2){
n.add(top);
}}
if(left!=null){
boolean k1 = n.contains(left);
if(!k1){
n.add(left);
}}
}
// top only
if(x - r > a.x && x + r < a.x + gW && y > a.y && y < a.y + r && top!=null){
boolean k2 = n.contains(top);
if(!k2){
n.add(top);
}
}
// top and right
if(x < a.x + gW && x > a.x +gW - r && y > a.y && y < a.y + r && top!= null && right!=null && topr!=null){
boolean k1 = n.contains(right);
boolean k2 = n.contains(top);
boolean k3 = n.contains(topr);
if(!k1){
n.add(right);
}
if(!k2){
n.add(top);
}
if(!k3){
n.add(topr);
}
}
// right only
if(x > a.x + gW - r && x < a.x + gW && y > a.y - r && y < a.y + gH - r && right != null){
boolean k1 = n.contains(right);
if(!k1){
n.add(right);
}
}
// right and bottom
if(x > a.x + gW - r && x < a.x + gW && y > a.y + gH - r && y < a.y + gH && right!= null && btm !=null && btmr !=null ){
boolean k1 = n.contains(right);
boolean k2 = n.contains(btm);
boolean k3 = n.contains(btmr);
if(!k1){
n.add(right);
}
if(!k2){
n.add(btm);
}
if(!k3){
n.add(btmr);
}
}
// bottom only
if(x > a.x + r && x < a.x + gW - r && y > a.y + gH - r && y < a.y + gH && btm != null){
boolean k1 = n.contains(btm);
if(!k1){
n.add(btm);
}
}
// bottom and left
if(x > a.x && x < a.x + r && y > a.y + gH - r && y < a.y + gH && btm!= null && left !=null && btml !=null){
boolean k1 = n.contains(left);
boolean k2 = n.contains(btm);
boolean k3 = n.contains(btml);
if(!k1){
n.add(left);
}
if(!k2){
n.add(btm);
}
if(!k3){
n.add(btm);
}
}
// left only
if(x > a.x && x < a.x + r && y > a.y + r && y < a.y + gH - r&& left != null){
boolean k1 = n.contains(left);
if(!k1){
n.add(left);
}
}
for(int i=0;i<neighbours.size();i++){
Quad k = neighbours.get(i);
//k.fillc();
}
if(x > a.x && x < a.x + gW && y > a.y && y < a.y + gH){
n.add(qgrid.get(iid.get(iid.size()-1)));
}
if(iid.size()==2){
boolean b = qgrid.get(iid.get(1)).children.contains(this);
boolean c = qgrid.get(iid.get(0)).children.contains(this);
if(!b){
qgrid.get(iid.get(1)).children.add(this);
//qgrid.get(iid.get(1)).fillc();
}
if (c){
int k = qgrid.get(iid.get(0)).children.indexOf(this);
qgrid.get(iid.get(0)).children.remove(k);
}}
if(iid.size()==1){
boolean b = qgrid.get(iid.get(0)).children.contains(this);
if(!b){
//qgrid.get(iid.get(0)).fillc();
qgrid.get(iid.get(0)).children.add(this);
}}
neighbours = n;
//neighbours.add(qgrid.get(iid.get(iid.size()-1)));
};
void quad_collisions(){
t = 0;
for(int i=0;i<neighbours.size();i++){
Quad a = neighbours.get(i);
for(int j=0;j<a.children.size();j++){
object b = a.children.get(j);
float d = dist(x,y,b.x,b.y);
if (d<r&&b!=this){
t++;
}
}}
//t = 1;
if(t==0){
collide = false;
}
else if(t>0){
collide = true;
}
};
void reg_collisions(){
t = 0;
for(int i=0;i<grid.size();i++){
object a = grid.get(i);
float d = dist(x,y,a.x,a.y);
if(d<r&&a!=this){
t++;
a.collide = true;
}}
if(ext = true){
//t = 1;
}
if(t==0){
collide = false;
}
else if(t>0){
collide = true;
}
};
};
//---------------------------------------------------------------------------
Quad index2(int xpos,int ypos){
if(wrap){
if(xpos<=0){
xpos = gw -1;
}
if(xpos>= gw -1){
xpos = 0;
}
if(ypos <= 0){
ypos = gh - 1;
}
if(ypos >= gh - 1){
ypos = 0;
}
return qgrid.get(ypos + (xpos * int(gw)));
}
else{
if(xpos<0||xpos>gw-1||ypos<0||ypos>gh-1){
return null;
}
return qgrid.get(xpos + (ypos * int(gw)));
}
};
//-------------------------------------------------------------------------------
void pop(){
for (int i=0;i<total;i++){
PVector a = new PVector(random(W),random(H));
grid.add(new object(a,i));
}
for (int j=0;j<gh;j++){
for (int i=0;i<gw;i++){
int id = i+j*gw;
PVector p = new PVector(i*gW,j*gH);
//float x = i*gW;
//float y = j*gH;
qgrid.add(new Quad(p,id));
}}
};
//--------------------------------------------------------------------------------
class Quad{
int id,iid;
float x,y;
PVector p;
ArrayList<object> children = new ArrayList<object>();
Quad(PVector P,int ID){
p = P;
id = ID;
x = p.x;
y = p.y;
};
void draw(){
strokeWeight(1);
stroke(255);
noFill();
rect(p.x,p.y,gW,gH);
//textSize(24);
//text(id,x + gW/2, y + gH/2);
//textSize(12);
};
void fillc(){
fill(255);
rect(p.x,p.y,gW,gH);
}
void update(){
fill(255);
text(children.size(),x,y);
for(int i=0;i<children.size();i++){
object a = children.get(i);
int t = 0;
for(int j=0;j<children.size();j++){
object b = children.get(j);
float d = dist(a.x,a.y,b.x,b.y);
if(d<a.r&&a!=b){
t++;
}}
if(t>0){
a.collide = true;
}
else{
a.collide = false;
}
}
};
};
//-----------------------------------------------------------------------------------
float k = 1000, ik = 1370/k, jk = floor(760/k);
int W = 1370,H = 760,total = 500,gw = 20 ,gh = 15,toggle = 0,toggle2 = 0;
float gW = (W)/float(gw), gH = H/float(gh);
ArrayList<Quad> qgrid = new ArrayList<Quad>();
ArrayList<object> grid = new ArrayList<object>();
boolean wrap = false;