Hi again everyone, I’m trying to code a program to generate voronoi diagrams,
however I’m having issues generating the function that draws arcs in between each line.
Voronoi generation is supposed to produce this type of effect
at the moment I’m establishing the intersection of the points as the radius grows by looping through the global array and just checking the point distance and radius. This works so far and I can find the angle of intersection by taking the normal, thats fine too.
However when I try to draw an arc either from point b to point a, or point a to point b using calculated angles I get errors such as the arcs will draw seemingly randomly, and therefore provides nothing consistent.
I have checked my angles by passing them through a line function and I can draw lines from the center of the arc out to point a and point b consistently but the arcs are a mystery.
Apologies but openprocessing produces an override error when I copied the code.
ArrayList<Point> grid = new ArrayList<Point>();
ArrayList<Pair> Collisions = new ArrayList<Pair>();
Button reset;
int W = 1200, H = 660, total = 4, toggle = 0,toggle2 = 0, limit = 5, counter = 0;
float inc = 5;
void gen(){
for(int i=0;i<total;i++){
float x = random(W);
float y = random(H);
grid.add(new Point(x,y,i));
}
}
class Button{
float x,y,w,h;
int toggle = 0;
String label;
boolean pressed = false;
Button(float xx, float yy, float ww, float hh, String Label){
x = xx;
y = yy;
w = ww;
h = hh;
label = Label;
}
void draw(){
noStroke();
fill(255);
rect(x,y,w,h);
fill(0);
text(label,x+5,y+h-5);
}
boolean pos(){
return x < mouseX && mouseY < x + w && y< mouseY && mouseY < y + h;
}
void click(){
if(pos()){
toggle ++;
}
if(toggle==2){
toggle = 0;
}
}
};
void Reset(){
if (reset.toggle==1){
grid = new ArrayList<Point>();
gen();
}
}
void settings(){
//size(W,H,FX2D);
size(W,H);
}
void setup(){
reset = new Button(1140,10,50,20, "reset");
gen();
}
void draw(){
frameRate(60);
background(51);
if(inc<0){
fill(255);
text("revese" ,1160,90);
}
Reset();
reset.draw();
//reset.click();
text(reset.toggle,10,10);
for(int i=0;i<grid.size();i++){
grid.get(i).draw();
grid.get(i).p_angle();
if(toggle==1){
grid.get(i).update();
}
grid.get(i).voronoi();
}
trim();
for(int i=0;i<Collisions.size();i++){
//Collisions.get(i).p_angle();
}
};
void mousePressed(){
if(mouseButton == LEFT && ! reset.pos()){
toggle++;
if(toggle == 2){
toggle = 0;
}}
if(mouseButton == RIGHT && ! reset.pos()){
inc = -inc;
}
if(mouseButton == LEFT && reset.pos()){
reset.click();
}
};
void mouseClicked(){
//mouse();
counter ++;
};
void mouseReleased(){
reset.toggle = 0;
}
class Point{
float x,y,theta,D = 0, r , _r =0;
boolean update = true,draw = true;
int id,ID;
ArrayList<Float> Arc_height = new ArrayList<Float>();
ArrayList<Point> collisions = new ArrayList<Point>();
ArrayList<PVector> intersects = new ArrayList<PVector>();
ArrayList<Float> lines = new ArrayList<Float>();
//PVector [] lines = {};
ArrayList<Float> angles = new ArrayList<Float>();
ArrayList<Float> arcs = new ArrayList<Float>();
color col ;
Point(float xx, float yy,int Id){
x = xx;
y = yy;
id = Id;
r = D/2;
ID = -1;
col = color(random(0,255),random(0,255),random(0,255));
}
void init(){
}
void draw(){
//if(id<1){
strokeWeight(10);
stroke(col);
//noStroke();
point(x,y);
noFill();
//fill(col);
strokeWeight(2);
//arc(x,y,r,r,0,360);
//text(arcs.size(),x,y);
//}
for(int i=0;i<intersects.size();i++){
PVector b = intersects.get(i);
stroke(col);
strokeWeight(4);
//float xx = collisions.get(ID).intersects.get(ID).x;
//float yy = collisions.get(ID).intersects.get(ID).y;
//float xa = (xx + x)/2;
//float ya = (yy + y)/2;
point(b.x,b.y);
//point(xa,ya);
}
//if(arcs.size()%2==0){
//for(int i=arcs.size()-1;i>0;i-=2){
// //for(int i = arcs.size() - (ID+1)*2;i<arcs.size();i+=2){
// //for(int i=0;i<arcs.size();i+=2){
// float theta1 = arcs.get(i);
// float theta2 = arcs.get(i+1);
// strokeWeight(5);
// //stroke(51);
// stroke(col);
// noFill();
//fill(51);
//arc(x,y,r,r,theta1,theta2);
//}
//}
};
void update(){
if(update){
D += inc ;
}
r = D/2;
};
void voronoi(){
fill(0);
text(intersects.size(),x,y);
text(ID,x,y+10);
//text(lines.size(),x,y+20);
text(Arc_height.size(),x,y+20);
if(arcs.size()>=limit*2){
//text("hello",10,10);
//arcs.remove(1);
//arcs.remove(0);
}
for(int i=0;i<grid.size();i++){
Point a = grid.get(i);
float d = dist(x,y,a.x,a.y);
boolean b = collisions.contains(a);
boolean c = a.collisions.contains(this);
if(a.update&&d<=a.r/2+r/2&&a!=this){
if(!b){
ID++;
collisions.add(a);
Arc_height.add(r/2);
intersects.add(new PVector(intersect(a,ID).x,intersect(a,ID).y));
}}
if(!a.update&&d<=r/2+a.r/2&&a!=this){
if(!b){
ID++;
collisions.add(a);
Arc_height.add(r/2);
intersects.add(new PVector(intersect(a,ID).x,intersect(a,ID).y));
}}}
if(collisions.size()>limit){
update = false;
}
};
PVector intersect(Point a,int id){
float c = Arc_height.get(id);
PVector b = new PVector();
float theta = atan2(a.y - y,a.x - x);
b.x = x + (c) * cos(theta);
b.y = y + (c) * sin(theta);
return b;
}
void perimeter(){
};
void p_angle(){
int t = collisions.size();
if(ID>1){
//t = collisions.size() - 1;
}
for(int i=0;i<t;i++){
PVector k = new PVector(intersects.get(i).x,intersects.get(i).y);
PVector a = intersects.get(i);
float c = Arc_height.get(i);
float theta1 = - atan2((a.x-x),a.y-y);
float b = r/2-c;
float l1 = sqrt(2*(b)*r/2 - (b)*(b));
PVector p1 = new PVector(k.x + l1 * cos(theta1), k.y + l1 * sin(theta1));
PVector p2 = new PVector(k.x - l1 * cos(theta1),k.y - l1 * sin(theta1));
float theta_a = atan2(p1.y - y,p1.x - x);
float theta_b = atan2(p2.y - y,p2.x - x);
float ta = 100;
float tb = 340;
float aa = theta_a*PI/180;
float ba = theta_b*PI/180;
stroke(col);
strokeWeight(2);
line(p1.x,p1.y,p2.x,p2.y);
stroke(0);
//strokeWeight(5);
point(p1.x,p1.y);
text("p1",p1.x+10,p1.y);
stroke(255);
point(p2.x,p2.y);
//if(ID==0){
noFill();
strokeWeight(2);
//arc(x,y,r,r,-theta_b,-theta_a);
stroke(col);
//arc(x,y,r,r,theta_a,theta_b);
line(x,y,x+r/2 * cos(theta_a),y+r/2 * sin(theta_a));
line(x,y,x+r/2 * cos(theta_b),y+r/2 * sin(theta_b));
arc(x,y,r/2,r/2,theta_b,theta_a);
//}
if(ID>0){
if(i<collisions.size()-1){
Point n = collisions.get(i + 1);
PVector kn = new PVector(intersects.get(i+1).x,intersects.get(i+1).y);
float theta2 = - atan2((kn.x-x),kn.y-y);
float c2 = Arc_height.get(i+1);
float b2 = r/2-c2;
float l2 = sqrt(2*(b2)*r/2 - (b2)*(b2));
PVector p3 = new PVector(kn.x + l2 * cos(theta2), kn.y + l2 * sin(theta2));
PVector p4 = new PVector(kn.x - l2 * cos(theta2),kn.y - l2 * sin(theta2));
float theta_c = atan2(p3.y - y,p3.x - x);
float theta_d = atan2(p4.y - y,p4.x - x);
noFill();
stroke(col);
//if(
//arc(x,y,r,r,theta_d,theta_c);
}
else if(i>= collisions.size()-1){
Point n = collisions.get(0);
PVector kn = new PVector(intersects.get(0).x,intersects.get(0).y);
float theta2 = - atan2((kn.x-x),kn.y-y);
float c2 = Arc_height.get(0);
float b2 = r/2-c2;
float l2 = sqrt(2*(b2)*r/2 - (b2)*(b2));
PVector p3 = new PVector(kn.x + l2 * cos(theta2), kn.y + l2 * sin(theta2));
PVector p4 = new PVector(kn.x - l2 * cos(theta2),kn.y - l2 * sin(theta2));
float theta_c = atan2(p3.y - y,p3.x - x);
float theta_d = atan2(p4.y - y,p4.x - x);
noFill();
stroke(col);
//arc(x,y,r,r,theta_d,theta_c);
}
}
}
};
};