Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Compatible with Processing 3.
- PImage map0;
- PGraphics offscreen;
- int countDistricts=3;//Must >= 2, obviously.
- District[] districts;
- Dot[] dots;
- Boolean done;
- int round=0,frameNum=0;
- int lastImageTime;
- void setup(){
- map0=loadImage("map.png");//Black shape on whatever background; data/map.png
- map0.loadPixels();
- offscreen=createGraphics(map0.width,map0.height);
- offscreen.noSmooth();
- offscreen.beginDraw();
- offscreen.colorMode(HSB,1);
- offscreen.ellipseMode(RADIUS);
- offscreen.endDraw();
- }
- void draw(){
- //Initialize districts
- districts=new District[countDistricts];
- for(int district=0;district<countDistricts;district++){
- districts[district]=new District();
- }
- //Initialize dots
- int countDotsImportant=0;
- for(int dot=0;dot<map0.pixels.length;dot++){
- if(map0.pixels[dot]==color(0,0,0)){
- countDotsImportant++;
- }
- }
- dots=new Dot[0];
- for(int dot=0;dot<map0.pixels.length;dot++){
- if(map0.pixels[dot]==color(0,0,0)){
- //dots=(Dot[])append(dots,new Dot(dot%map0.width,dot/map0.width,dots.length%countDistricts));
- if(dots.length<countDotsImportant/countDistricts*countDistricts){
- dots=(Dot[])append(dots,new Dot(dot%map0.width,dot/map0.width,dots.length/(countDotsImportant/countDistricts)));
- }else{
- dots=(Dot[])append(dots,new Dot(dot%map0.width,dot/map0.width,dots.length%countDistricts));
- }
- }
- }
- for(int district=0;district<districts.length;district++){
- println("District "+district+" contains "+districts[district].countDots+" dots.");
- }
- recalc();
- imageDraw();
- //Main loop
- int dot1,dot2;
- int fails=0;
- do{
- round++;
- do{
- dot1=int(random(dots.length));
- dot2=int(random(dots.length));
- }while(dots[dot1].district==dots[dot2].district);
- if(/*dots[dot1].r>districts[dots[dot1].district].r&&dots[dot2].r>districts[dots[dot2].district].r&&*/(dots[dot1].r+dots[dot2].r)/(dots[dot1].rMaybe(dots[dot2].district)+dots[dot2].rMaybe(dots[dot1].district))>1){
- dots[dot1].flipWith(dot2);
- recalc();
- fails=0;
- }else{
- fails++;
- }
- if(millis()-lastImageTime>10*1000||fails>pow(dots.length,1)*pow(districts.length,2)){
- imageDraw();
- }
- if(fails>pow(dots.length,1)*pow(districts.length,2)){
- break;
- }
- }while(true);
- exit();
- }
- class Dot{
- int x,y;//Coordinates
- int district;//To which this dot belongs
- float r;//From center of district
- Dot(int input0,int input1,int input2){
- x=input0;
- y=input1;
- district=input2;
- r=-1;
- districts[input2].countDots++;
- }
- float rMaybe(int input0){
- return dist(x,y,districts[input0].x,districts[input0].y);
- }
- void flipWith(int input0){
- int temp=dots[input0].district;
- dots[input0].district=district;
- district=temp;
- }
- }
- class District{
- float x,y;//Coordinates of center
- float r;//Average for all dots
- int countDots;//Number of dots belonging to this district
- District(){
- x=0;
- y=0;
- r=0;
- countDots=0;
- }
- }
- void recalc(){
- //Calculate district centers, then dot radii, and finally district radii
- for(int dot=0;dot<dots.length;dot++){
- districts[dots[dot].district].x+=dots[dot].x;
- districts[dots[dot].district].y+=dots[dot].y;
- }
- for(int district=0;district<districts.length;district++){
- districts[district].x/=(float)districts[district].countDots;
- districts[district].y/=(float)districts[district].countDots;
- }
- for(int dot=0;dot<dots.length;dot++){
- dots[dot].r=dist(dots[dot].x,dots[dot].y,districts[dots[dot].district].x,districts[dots[dot].district].y);
- districts[dots[dot].district].r+=dots[dot].r;
- }
- for(int district=0;district<districts.length;district++){
- districts[district].r/=(float)districts[district].countDots;
- }
- }
- void imageDraw(){
- offscreen.beginDraw();
- offscreen.noStroke();
- offscreen.fill(0,0,0);
- offscreen.rect(0,0,offscreen.width,offscreen.height);
- for(int dot=0;dot<dots.length;dot++){
- offscreen.fill((float)dots[dot].district/districts.length,1,1);
- offscreen.rect(dots[dot].x,dots[dot].y,1,1);
- }
- offscreen.stroke(0,0,1);
- offscreen.strokeWeight(1);
- offscreen.noFill();
- for(int district=0;district<districts.length;district++){
- offscreen.ellipse(districts[district].x,districts[district].y,districts[district].r,districts[district].r);
- offscreen.point(round(districts[district].x),round(districts[district].y));
- }
- offscreen.save("output/"+frameNum+".png");
- frameNum++;
- offscreen.endDraw();
- lastImageTime=millis();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement