boolean twoSteps = false;
boolean arePointsHalfway = false;
int[][] countGrid = new int[arraySize][arraySize];
int[][] countDoubledGrid = new int[arraySize*2][arraySize*2];
float dimensionEstimate = 2;
current = new PVector(random(width), random(height));
hs1 = new HScrollbar(1000, 330, 400, 20, 3);
hs2 = new HScrollbar(1000, 190, 400, 20, 3);
b1 = new Button(1100, 730, 200, 75);
c1 = new Checkbox(1000, 430, 40, 40);
c2 = new Checkbox(1000, 510, 40, 40);
c3 = new Checkbox(1000, 590, 40, 40);
for (int i = 0; i < arraySize; i++) {
for (int j = 0; j < arraySize; j++) {
for (int i = 0; i < arraySize/2; i++) {
for (int j = 0; j < arraySize/2; j++) {
countDoubledGrid[i][j] = 0;
void polygon(float x, float y, float radius, int npoints, boolean halfway) {
points = new PVector[numSides * 2];
points = new PVector[numSides];
for (int i = 0; i < npoints; i++) {
float angle = i * TWO_PI / npoints;
PVector v = PVector.fromAngle(angle);
points[i * 2 + 1] = new PVector((v.x + (x + cos(angle + TWO_PI / npoints) * radius))/2f,
(v.y + (y + sin(angle + TWO_PI / npoints) * radius))/2f);
void calculateCarpetFraction(int sides) {
for (float i = 1; i <= floor(float(sides) / 4f); i++) {
sum += cos((2*PI*i)/float(sides));
fraction = 1 / (2 * (1 + sum));
text("Length Fraction", 1000, 270);
text("0", 1000, 175+130);
text("1", 1385, 175+130);
text(hs1.normalPos, 1000, 240+130);
text("Number of Sides", 1000, 130);
text((int) (3.5 + hs2.normalPos * 7), 1000, 230);
text("Update", 1145, 777);
text("Other Options", 1000, 410);
text("Use Sierpinski Carpet Fraction", 1060, 460);
text("Allow the same point of the polygon to", 1060, 525);
text("be picked multiple times in a row", 1060, 555);
text("Add points to the midpoints of the edges", 1060, 605);
text("of the polygon", 1060, 635);
text("Estimated Dimension:", 1000, 690);
text(str(dimensionEstimate), 1320, 690);
background(200, 200, 200);
numSides = (int) (3.5 + hs2.normalPos * 7);
polygon(500, height/2, 400, numSides, arePointsHalfway);
for (int i = 0; i < points.length; i++) {
point(points[i].x, points[i].y, 8);
calculateCarpetFraction(numSides * 2);
calculateCarpetFraction(numSides);
float lerpPercent = hs1.normalPos;
lerpPercent = 1 - fraction;
hs1.setNormalPos(lerpPercent);
for (int i = 0; i < 100000; i++) {
PVector next = points[floor(random(points.length))];
if (twoSteps || next != previous) {
current.x = lerp(current.x, next.x, lerpPercent);
current.y = lerp(current.y, next.y, lerpPercent);
point(current.x, current.y);
int arrayX = (int)(current.x * (float)arraySize / (float)1000);
int arrayY = (int)(current.y * (float)arraySize / (float)1000);
if (arrayX < arraySize && arrayY < arraySize) {
countGrid[arrayX][arrayY] = 1;
int arrayX2 = (int)(current.x * 2 * (float)arraySize / (float)1000);
int arrayY2 = (int)(current.y * 2 * (float)arraySize / (float)1000);
if (arrayX2 < arraySize * 2 && arrayY2 < arraySize * 2) {
countDoubledGrid[arrayX2][arrayY2] = 1;
for (int i = 0; i < arraySize; i++) {
for (int j = 0; j < arraySize; j++) {
sumGrid += countGrid[i][j];
for (int i = 0; i < arraySize * 2; i++) {
for (int j = 0; j < arraySize * 2; j++) {
sumDoubledGrid += countDoubledGrid[i][j];
countDoubledGrid[i][j] = 0;
dimensionEstimate = log((float)sumDoubledGrid / (float)sumGrid) / log(2);
arePointsHalfway = c3.pressed;