My project library #5! Gallery megathread

Here are some of my projects! I hope you get some ideas/inspiration from it : P

There are 4 previous megathreads with 60 projects in total!

If you have any questions regarding the projects, use the #[project number] while referencing them!
Any suggestions/ideas are very welcome! Enjoy!

3 Likes

#62 4 point Bézier curve

Code
p po[] = new p[10]; //4 primary, 3 V% across, 2 V$ across secondary, 1 V% across terciary
ln l[] = new ln[6];
float V = 0.5;
boolean pediting = false;

void setup() {
  size(600, 600);
  stroke(255);
  float offX = 0, offY = 0;
  po[0] = new p(100 + offX, 100 + offY, true);
  po[1] = new p(500 + offX, 100 + offY, true);
  po[2] = new p(500 + offX, 500 + offY, true);
  po[3] = new p(100 + offX, 500 + offY, true);

  for (int i = 4; i < po.length; i++) po[i] = new p(0, 0, false);

  l[0] = new ln(0, 1);
  l[1] = new ln(1, 2);
  l[2] = new ln(2, 3);

  l[3] = new ln(4, 5);
  l[4] = new ln(5, 6);

  l[5] = new ln(7, 8);
}
void draw() {
  background(0); 
  if (pediting == false && mousePressed) V = constrain(map(mouseX, 0, width, 0, 1),0,1);

  po[4].setValue( l[0].pos(V) );
  po[5].setValue( l[1].pos(V) );
  po[6].setValue( l[2].pos(V) );

  po[7].setValue( l[3].pos(V) );
  po[8].setValue( l[4].pos(V) );

  po[9].setValue( l[5].pos(V) );
  noStroke();
  for (int i = 0; i < po.length; i++) {
    po[i].display();
  }
  stroke(255);
  for (int i = 0; i < 6 && 0 != l.length; i++) {
    l[i].drawLN();
  }

  drawCurve(0.001, 0,V);
}

void drawCurve(float increment, float start, float stop) {
  noFill();
  stroke(0,0,255);
  beginShape();
  for (float vv = start; vv < stop; vv+=increment) {
    PVector cpoint = getPos(vv);
    vertex(cpoint.x, cpoint.y);
  }
  endShape();
}

void keyPressed() {
  if (key == ' ') pediting = !pediting;
}

void mouseDragged() {
  if (pediting) {
    int maxRadius = 50;
    int closest = -1;
    float closestDist = maxRadius;
    for (int i = 0; i < po.length; i++) if (po[i].canMove==true) {
      float dst = dist(mouseX, mouseY, po[i].pv.x, po[i].pv.y);
      if (dst < closestDist) {
        closestDist = dst;
        closest = i;
      }
    }
    if(closest>=0) {
      po[closest].pv = new PVector(mouseX,mouseY);
    }
  }
}

PVector getPos(float V) {
  po[4].setValue( l[0].pos(V) );
  po[5].setValue( l[1].pos(V) );
  po[6].setValue( l[2].pos(V) );

  po[7].setValue( l[3].pos(V) );
  po[8].setValue( l[4].pos(V) );

  po[9].setValue( l[5].pos(V) );

  return l[5].pos(V);
}


class ln {
  int p1, p2;
  ln(int p1, int p2) {
    this.p1 = p1;
    this.p2 = p2;
  }
  void drawLN() {
    stroke(255);
    line(po[p1].pv.x, po[p1].pv.y, po[p2].pv.x, po[p2].pv.y);
  }
  PVector pos (float v) {
    return new PVector( lerp(po[p1].pv.x, po[p2].pv.x, v), lerp(po[p1].pv.y, po[p2].pv.y, v) );
  }
}

class p {
  PVector pv;
  boolean canMove = false;
  p(float x, float y, boolean canMove) {
    pv = new PVector(x, y);
    this.canMove = canMove;
  }
  void setValue(PVector pv) {
    this.pv = pv;
  }
  void display() {
    fill( (pediting? #00FF00 : #FFFFFF) );
    circle(pv.x, pv.y, (pediting && canMove? 15 : 5));
  }
}

Press space to edit point location. Hold mouse to change the completion of the curve.

#62 B | N - point Bézier

Code
int n = 4; //N-point brazier curve
int prevN = n;
p po[] = new p[0];
l ln[] = new l[0];
float v = 0.5;
boolean pediting = false;
boolean displayLines = true;
boolean displayDots = true;
void setup() {
  updateStructure(true);
  size(600, 600);
}
void draw() {
  if (mousePressed && pediting == false) v = map(mouseX, 0, width, 0, 1);
  background(0);
  updatePoints(v);
  if(displayDots) for (int i = 0; i < po.length; i++) po[i].display();
  if(displayLines) for (int i = 0; i < ln.length; i++) ln[i].display();
  drawCurve(0.01, 0, 1);
}

void keyPressed() {
  if (key == ' ') {
    n++;
    updateStructure(false,new p(mouseX,mouseY,true));
  }
  if (key == 'c') {
    n++;
    updateStructure(true);
  }
  if (key == 'e') {
    pediting = !pediting;
  }
  if(key == 'h') displayLines = !displayLines;
  if(key == 'd') displayDots = !displayDots;
}

void mouseDragged() {
  if (pediting) {
    int maxRadius = 50;
    int closest = -1;
    float closestDist = maxRadius;
    for (int i = 0; i < po.length; i++) if (po[i].canMove==true) {
      float dst = dist(mouseX, mouseY, po[i].pv.x, po[i].pv.y);
      if (dst < closestDist) {
        closestDist = dst;
        closest = i;
      }
    }
    if (closest>=0) {
      po[closest].pv = new PVector(mouseX, mouseY);
    }
  }
}

void drawCurve(float increment, float start, float stop) {
  noFill();
  stroke(0, 0, 255);
  beginShape();
  for (float vv = start; vv < stop; vv+=increment) {
    PVector cpoint = getPos(vv);
    vertex(cpoint.x, cpoint.y);
  }
  endShape();
}

PVector getPos(float V) {
  updatePoints(V);
  return po[n*(n+1)/2-1].pv;
}

void updatePoints(float V) {
  for (int i = n; i < po.length; i++) {
    po[i].setValue( ln[i-n].pos(V));
  }
}

void updateStructure(boolean createPoints, p... addPoint) {
  if (n < 3) n = 3;

  if (addPoint.length>0) n+=addPoint.length-1;

  p newPO[] = new p[n*(n+1)/2];
  ln = new l[n*(n-1)/2];
  for(int i = 0; i < newPO.length; i++) newPO[i] = new p(150,150,true);
  for (int i = 0; i < prevN && i < po.length; i++) newPO[i] = po[i];
  if (addPoint.length>0) for (int i = 0; i < addPoint.length; i++) newPO[i+prevN] = addPoint[i];
  po = newPO;

  if (createPoints) { //creating PRIMARY POINTS
    float cx = width*0.5, cy = height*0.5, r = 250, a = TWO_PI/n;
    for (int i = 0; i < n; i++) {
      po[i] = new p( cx + cos(a*i)*r, cy + sin(a*i)*r, true);
    }
  }
  for (int i = n; i < po.length; i++) po[i] = new p(-1, -1, false); //creating all NON-PRIMARY points

  int counter = 0, counter2 = 0;
  for (int i = 1; i < n; i++) {
    for (int j = i; j < n; j++) {
      ln[counter2] = new l(counter, counter+1);
      counter++;
      counter2++;
    }
    counter++;
  }
  println(prevN,n,addPoint.length);
  prevN = n;
}

class p { //point
  PVector pv;
  boolean canMove;
  p (float x, float y, boolean canMove) {
    pv = new PVector(x, y);
    this.canMove = canMove;
  }
  void setValue(PVector pv) {
    this.pv = pv;
  }
  void display() {
    fill( (pediting? #00FF00 : #FFFFFF) ); 
    noStroke();
    circle(pv.x, pv.y, (pediting && canMove? 15 : 5 ));
  }
}
class l { //line
  int p1, p2;
  l (int p1, int p2) {
    this.p1 = p1;
    this.p2 = p2;
  }
  PVector pos(float v) {
    if(p1>=po.length-1 || p2>=po.length-1) println(p1,p2);
    return new PVector( lerp(po[p1].pv.x,po[p2].pv.x, v),lerp(po[p1].pv.y,po[p2].pv.y, v) );
  }
  void display() {
    stroke(255);
    line(po[p1].pv.x, po[p1].pv.y, po[p2].pv.x, po[p2].pv.y);
  }
}

Instructions:

  • when dots are white, drag the mouse across the screen to change V. Only mouseX is counted.
  • press ‘e’ to enter editing mode - all dots will turn green and the closest Large dot (primary), if in range of 50px, will be moved to mouse position.
  • press ‘c’ to add 1 point and arrange all points into a circle ish shape.
  • press ’ ’ to add a point where the cursor is without affecting the others
  • press ‘h’ to toggle lines
  • press ‘d’ to toggle dots.
1 Like

#63 Snowflake generator
Creates a random snowflake-ish shape. Press ‘space’ to reset and use mouse to (un)pause. Scroll mouse wheel to adjust complexity (speed of changes). Press ‘c’ to clear stage and reset.


How to adjust things inside of the program?

  • Change the number of sides? - N, default = 6
  • Change step length? - L, default 5
  • Circle size? - cd, default L*0.5;
  • Update rate? - frameRate( speed );
    Everything else is explained inside of the code.

Just felt like this was a project worth sharing. It is simple and has a fun result. I first saw the idea about a year ago. I don’t remember the whole story, but I saw this and it surprised me. I couldn’t understand the code at all. I remember staring at it for minutes, yet coming up with nothing. Anyway, have fun.

Code
int N = 6; //sides
int a = 0, modulo = 3; //editing has no use, besides changing initial value
float l = 5, cd = l*0.5; //step length, circle diameter
final float A = TWO_PI/N; //just felt like using constants
mover m[] = new mover[2*N];
boolean active = true; //state? Looping / not looping
color bgColor = color(0), circleColor = color(255);
void setup() {
  size(600, 600);
  background(bgColor);
  fill(255); 
  noStroke();
  //frameRate(10); //update rate
  for (int i = 0; i < N; i++) {
    m[2*i]   = new mover(300, 300,  1, i); //adding pairs of points. 
    m[2*i+1] = new mover(300, 300, -1, i);
  }
}
void draw() {
  if (active) {
    fill(bgColor, 3); //fading speed. Set 2nd value to something between 0 and 255. 0 means no clearing trail, while anything >0 means that it is slowly erased. 255 means instant erasure. 
    rect(0, 0, width, height);
    fill(circleColor);
    if (frameCount%modulo==0) a+=round(random(-1, 1)); //changing direction 
    a%=N; //a is always between 0 and N
    a%=-N;

    for (int i = 0; i < 2*N; i++) m[i].move();
    for (int i = 0; i < 2*N; i++) m[i].display();
  }
}
void reset() {
  for (int i = 0; i < N; i++) {
    m[2*i]   = new mover(300, 300, 1, i);
    m[2*i+1] = new mover(300, 300, -1, i);
  }
}
void keyPressed() {
  if (key == ' ') reset();
  if (key == 'c') {
    background(bgColor);
    reset();
  }
}
void mousePressed() {
  active=!active;
}
void mouseWheel(MouseEvent e) {
  int n = round(e.getCount());
  modulo-=n;
  if(modulo<1) modulo=1; //if modulo = 0, program crashes
  println(modulo); 
}

class mover {
  float x, y;
  int am, ao;
  mover(float x, float y, int am, int ao) {
    this.x=x;
    this.y=y;
    this.am=am;
    this.ao=ao;
  }
  void move() {
    int la = (a+ao)*am;
    x+= cos(la*A)*l;
    y+= sin(la*A)*l;
  }
  void display() {
    circle(x, y, cd);
  }
}


1 Like

#64 Pythagoras tree


image
image
image

image

Controls:

  • Press any key to generate the next branch
  • Left click to change the triangle shape
  • Drag right click - change base square

This is a proof of concept, so it has some issues.

Code
float rot = -QUARTER_PI, move = sqrt(2)/2, baseLen=100;
squ base = getSqu(new PVector[]{new PVector(300-baseLen*0.5, 500), new PVector(300+baseLen*0.5, 500)});
ArrayList<squ> ss = new ArrayList<squ>();
float sx=0,sy=0;

void setup() {
  size(600, 600);
  stroke(255);
  ss.add(base);
}
void draw() {
  background(0);
  //base = getSqu(new PVector[]{new PVector(300,300), new PVector(mouseX,mouseY)});
  for (int i = 0; i < ss.size(); i++) ss.get(i).display();
  ss.get(0).displayPoint();
}
void keyPressed() { 
  step();
}
void mousePressed() {
  if (mouseButton==LEFT) {
    float dir = atan2(base.points[3].y-mouseY, base.points[3].x-mouseX);
    float dst = -dist (base.points[3].x, base.points[3].y, mouseX, mouseY)/baseLen;
    rot = dir;
    move=dst;
    base.updatePrefs();
    ss.clear();
    ss.add(base);
  } else if(mouseButton==RIGHT) {
    sx=mouseX;
    sy=mouseY;
  }
}
void mouseReleased() {
  if(mouseButton==RIGHT) {
    base = getSqu(new PVector[]{new PVector(sx,sy),new PVector(mouseX,mouseY)});
    baseLen=dist(sx,sy,mouseX,mouseY);
    base.updatePrefs();
    ss.clear();
    ss.add(base);
  }
}
void step() {
  for (int i = 0, m = ss.size(); i < m; i++) ss.get(i).dupe();
}

class squ {
  PVector points[], third;
  boolean canDupe = true;
  squ(PVector[] points) {
    this.points = points;
    third = getThirdPoint(new PVector[]{points[3], points[2]});
  }
  void updatePrefs() {
    canDupe=true;
    third = getThirdPoint(new PVector[]{points[3], points[2]});
  }
  void display() {
    for (int i = 0; i < 4; i++) line(points[i].x, points[i].y, points[(i+1)%4].x, points[(i+1)%4].y);
  }
  void displayPoint() {
    circle(third.x, third.y, 5);
  }
  void dupe() {
    if (canDupe) {
      ss.add(getSqu(new PVector[]{points[3], third}));
      ss.add(getSqu(new PVector[]{third, points[2]}));
      canDupe=false;
    }
  }
}

PVector getThirdPoint(PVector[] points) {
  float dir = atan2(points[1].y-points[0].y, points[1].x-points[0].x);
  float len = dist(points[0].x, points[0].y, points[1].x, points[1].y);

  return new PVector(points[0].x+ cos(dir+rot)*len*move, points[0].y + sin(dir+rot)*len*move);
}

squ getSqu(PVector[] points) {
  PVector output[] = {points[0], points[1], new PVector(), new PVector()};
  float dir = atan2(points[1].y-points[0].y, points[1].x-points[0].x);
  float dir2 = dir - HALF_PI;
  float len = dist(points[0].x, points[0].y, points[1].x, points[1].y);
  float kx = cos(dir2), ky = sin(dir2);

  output[3] = new PVector(points[0].x+kx*len, points[0].y+ky*len);
  output[2] = new PVector(points[1].x+kx*len, points[1].y+ky*len);

  return new squ(output);
}