つよくなりたいなあ

地に足をつけず世界を生きぬくブログです

サトクリフ五角形

ジェネラティヴ・アートの本を買って、一通りのレッスンを試し終わりました。最後はサトクリフ五角形です。いじっているので五角形の形が壊れてますが。

FractalRoot pentagon;
int _maxlevels = 4;
int _numSides = 8;
float _strutFactor = 0.2;
float _strutNoise;


void setup() {
  size(800, 600);
  background(255);
  smooth();
  _strutNoise = random(25);
}
void draw() {
  background(255);
  _strutNoise += 0.03;
  _strutFactor = noise(_strutNoise * 3) - 1;

  pentagon = new FractalRoot(frameCount);
  pentagon.drawShape();

}
//============================ Point object
class PointObj {
  float x, y;
  PointObj(float ex, float why) {
    x = ex; 
    y = why;
  }
}

class FractalRoot {
  PointObj[] pointArr = {};
  Branch rootBranch;

  FractalRoot(float startAngle) {
    float centX = width/2;
    float centY = height/2;
    float angleStep = 360.0f/_numSides;
    for (int i = 0; i < 360; i += angleStep) {
      float x = centX + (200 * cos(radians(startAngle + i)));
      float y = centY + (200 * sin(radians(startAngle + i)));
      pointArr = (PointObj[])append(pointArr, new PointObj(x, y));
    }
    rootBranch = new Branch(0, 0, pointArr);
  }
  void drawShape() {
    rootBranch.drawMe();
  }
}

class Branch {
  int level, num;
  PointObj[] outerPoints = {};
  PointObj[] midPoints = {};
  PointObj[] proPoints = {};
  Branch[] myBranches = {};

  Branch(int lev, int n, PointObj[] points) {
    level = lev;
    num = n;
    outerPoints = points;
    midPoints = calcMidPoints();
    proPoints = calcStrutPoints();

    if ((level+1) < _maxlevels) {
      Branch childBranch = new Branch(level+1, 0, proPoints);
      myBranches = (Branch[])append(myBranches, childBranch);

      for (int k = 0; k < outerPoints.length; k++) {
        int nextk = k-1;
        if (nextk < 0) {
          nextk += outerPoints.length;
        }
        PointObj[] newPoints = {proPoints[k], midPoints[k], 
          outerPoints[k], midPoints[nextk], 
          proPoints[nextk]};
        childBranch = new Branch(level+1, k+1, newPoints);
        myBranches = (Branch[])append(myBranches, childBranch);
      }
    }
  }

  PointObj[] calcMidPoints() {
    PointObj[] mpArray = new PointObj[outerPoints.length];
    for (int i = 0; i < outerPoints.length; i++) {
      int nexti = i+1;
      if (nexti == outerPoints.length) {
        nexti = 0;
      }
      PointObj thisMP = calcMidPoint(outerPoints[i], outerPoints[nexti]);
      mpArray[i] = thisMP;
    }
    return mpArray;
  }

  PointObj calcMidPoint(PointObj end1, PointObj end2) {
    float mx, my;
    if (end1.x > end2.x) {
      mx = end2.x + ((end1.x - end2.x)/2);
    } else {
      mx = end1.x + ((end2.x - end1.x)/2);
    }
    if (end1.y > end2.y) {
      my = end2.y + ((end1.y - end2.y)/2);
    } else {
      my = end1.y + ((end2.y - end1.y)/2);
    }
    return new PointObj(mx, my);
  }

  PointObj[] calcStrutPoints() {
    PointObj[] strutArray = new PointObj[midPoints.length];
    for (int i = 0; i < midPoints.length; i++) {
      int nexti = i+3;
      if (nexti >= midPoints.length) {
        nexti -= midPoints.length;
      }
      PointObj thisSP = calcProPoint(midPoints[i], 
        outerPoints[nexti]);
      strutArray[i] = thisSP;
    }
    return strutArray;
  }

  PointObj calcProPoint(PointObj mp, PointObj op) {
    float px, py;
    float adj, opp;
    if (op.x > mp.x) {
      opp = op.x - mp.x;
    } else {
      opp = mp.x - op.x;
    }
    if (op.y > mp.y) {
      adj = op.y - mp.y;
    } else {
      adj = mp.y - op.y;
    }
    if (op.x > mp.x) {
      px = mp.x + (opp * _strutFactor);
    } else {
      px = mp.x - (opp * _strutFactor);
    }
    if (op.y > mp.y) {
      py = mp.y + (adj * _strutFactor);
    } else {
      py = mp.y - (adj * _strutFactor);
    }
    return new PointObj(px, py);
  }

  void drawMe() {
    strokeWeight(1);
    noFill();
    for (int i = 0; i < outerPoints.length; i++) {
      int nexti = i+1;
      if (nexti == outerPoints.length) {
        nexti = 0;
      }
      line(outerPoints[i].x, outerPoints[i].y, 
        outerPoints[nexti].x, outerPoints[nexti].y);
    }
    strokeWeight(0.2);
    fill(250);
    for (int j = 0; j < midPoints.length; j++) {
      ellipse(midPoints[j].x, midPoints[j].y, 5, 5);
      line(midPoints[j].x, midPoints[j].y, 
        proPoints[j].x, proPoints[j].y);
      ellipse(proPoints[j].x, proPoints[j].y, 5, 5);
    }
    for (int k =0; k < myBranches.length; k++) {
      myBranches[k].drawMe();
    }
  }
}

f:id:heyassy:20180303133715j:plain f:id:heyassy:20180303133728j:plain f:id:heyassy:20180303133824j:plain

ENTERキーで画像を保存するとき。

void keyPressed() {
  if ( key == ENTER) {
    saveFrame("Pentagon-####.jpg");
  }
}