/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.dENaDUSP$Yg/rev.3370
*
* authors:
*
* frederic.vernier
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
float ANG = PI/3;
int R = 16;
int RAD ;
int abu[] = new int[6];
int def[] = new int[6];
int pri[] = new int[6];
int par[] = new int[6];
int sab[] = new int[6];
String title[] = {"E", "SE", "SW", "W", "NW", "NE"};
int mind = 0;
int maxd = 1;
int dec = 1;
float bestAbundant = 0;
boolean propSize = false;
PFont font8, font16;
// determines the number of factors
int numFactors(int number) {
if (number==1)
return 1;
int factorCount = 0;
float sqrtNum = sqrt(number);
for (int i=1; i<=sqrtNum; i++)
if (number%i == 0)
factorCount++;
return factorCount;
}
//determines the sum of factors (perfect numbers have a sum equal to itself)
int sumFactors(int number) {
if (number==1)
return 1;
int factorSum = 0;
float sqrtNum = sqrt(number);
for (int i=2; i< number; i++)
if (number%i == 0)
factorSum += i;
return factorSum+1;
}
void setup() {
bestAbundant = 0;
//for (int i=0; i<20; i++)
// println(""+i+" => "+ sumFactors(i*496)/(i*496));
RAD = 240/R;
mind = 0;
maxd = 1;
dec = 5000/R;
size(900, 800);
// initialize array for densities
for (int i=0; i<6; i++) {
def[i]=0;
abu[i]=0;
pri[i]=0;
par[i]=0;
sab[i]=0;
}
frameRate(5);
strokeWeight(2);
background(255);
loop();
colorMode(HSB);
font8 = createFont("Arial", 8);
font16 = createFont("Arial", 16);
textAlign(CENTER, CENTER);
}
void drawHexa(int x, int y, int R, int v, float a, int j, int ii, int k, int maxi) {
pushMatrix();
int sf = sumFactors(v);
boolean sa = false;
if (v!=0 && sf/v> bestAbundant){
bestAbundant = sf/v;
sa=true;
}
if (k==maxi-1) {
noStroke();
fill(216, 255);
beginShape();
for (int i=0; i<=6; i++) {
float x0 = x+R*cos(i*ANG);
float y0 = y+R*sin(i*ANG);
vertex(x0, y0);
}
endShape();
}
if (v==0){
} else if (sf==1)
pri[ii]++;
else if (sf<v)
def[ii]++;
else if (sa)
sab[ii]++;
else if (sf>v)
abu[ii]++;
else
par[ii]++;
stroke(0);
if (sf==1) {
if (propSize) scale(0.98*sf/v);
fill (0, 255, 255);
} else if (sf<v) {
if (propSize) scale(0.98*sf/v);
fill (0, 128, 255);
} else if (sa) {
if (propSize) scale(0.98*v/sf);
fill (150, 255, 255);
} else if (sf>v) {
if (propSize) scale(0.98*v/sf);
fill (128, 128, 255);
} else {
scale(0.98);
fill (192, 128, 255);
}
if (R<3) noStroke();
strokeWeight(1);
beginShape();
for (int i=0; i<=6; i++) {
float x0 = x+R*cos(i*ANG);
float y0 = y+R*sin(i*ANG);
vertex(x0, y0);
}
endShape();
stroke(1);
popMatrix();
rotate(-a);
fill(0,0,0);
if (R>6)
text(v, -1, 0);
rotate(a);
}
void draw() {
int c = RAD+1;
int v = 0;
float a = -1*PI/3;
pushMatrix();
translate(width/2, height/2);
textFont(font8);
if (0>=mind && 0<=maxd) {
drawHexa(0, 0, R, v, 0, 0, 0, 0, 0);
fill(0);
textFont(font16);
text("Press + or - to zoom in or out",width/2-120, -height/2+20);
text("Press p to relate size and distance to perfection",width/2-180, -height/2+40);
}
textFont(font8);
translate(R*1.5, R*(sqrt(3)/2));
//rotate(PI/3);
for (int j=1; j<RAD; j++) {
for (int i=0; i<6; i++) {
int maxl = j;
//if (i==5) maxl++;
//if (i==0) maxl--;
if (i!=0)rotate(PI/3);
a = (a+PI/3)%TWO_PI;
for (int k=0; k<maxl; k++) {
v++;
stroke(196);
if(k!=0||i!=0) translate(0, R*sqrt(3));
if (v>mind && v<=maxd) {
dec = max(dec, j/2);
drawHexa(0, 0, R, v, a, j, i, k, maxl);
stroke(255, 128);
if(k!=0||i!=0) line(0,0, 0, -R*sqrt(3));
else line(0,0, -R*1.5, -R*(sqrt(3)/2));
rotate(-a);
fill(0,0,0);
if (R>6)
text(v, -1, 0);
rotate(a);
}
}
}
translate(0, R*sqrt(3));
rotate(PI/3);
}
popMatrix();
float prop = R*R/60;
strokeWeight(1);
stroke(0);
for (int i=0; i<6; i++) {
fill (0, 255, 255);
rect(i*30, height-pri[i]*prop, 30, pri[i]*prop);
fill (0, 128, 255);
rect(i*30, height-(pri[i]+def[i])*prop, 30, def[i]*prop);
fill (192, 128, 255);
rect(i*30, height-(pri[i]+def[i]+par[i])*prop, 30, par[i]*prop);
fill (128, 128, 255);
rect(i*30, height-(pri[i]+def[i]+par[i]+abu[i])*prop, 30, abu[i]*prop);
fill (150, 255, 255);
rect(i*30, height-(pri[i]+def[i]+par[i]+abu[i]+sab[i])*prop, 30, sab[i]*prop);
fill(0, 255);
textFont(font8);
if (abu[i]+def[i]+pri[i]+par[i]!=0){
text( (100*abu[i])/(abu[i]+def[i]+pri[i]+par[i]), i*30+15, height-(pri[i]+def[i]+par[i])*prop-abu[i]*prop/2);
text( (100*def[i])/(abu[i]+def[i]+pri[i]+par[i]), i*30+15, height-pri[i]*prop-def[i]*prop/2);
text( (100*pri[i])/(abu[i]+def[i]+pri[i]+par[i]), i*30+15, height-pri[i]*prop/2);
text(title[i], i*30+15, height-def[i]*prop-abu[i]*prop-pri[i]*prop-par[i]*prop-sab[i]*prop+8);
}
}
mind = maxd;
maxd += dec;
}
void keyTyped(){
if (key==43 && R<65){
R++;
setup();
} else if (key==45 && R>1){
R--;
setup();
} else if (key==112){
propSize = ! propSize;
setup();
}else {
println("key "+key+" not recognized");
}
}