• Virtual
  • Digital
  • Physical
  • About
  • Contact
Joe Kane
  • Virtual
  • Digital
  • Physical
  • About
  • Contact
Forlola_PurpleCircles.png

Prototyping

Forlola started as a napkin sketch. I prototyped the code for the physics using Processing before beginning the final development in Xcode.

ForlolaSketch.jpeg
float gravity = 6.0;
int numsprings = 4;
 
ArrayList springs;

Spring2D feet, body, head, eye;
 
void setup()
{
  size(640, 960);
  smooth();
  fill(0);
  noStroke();
   
  springs = new ArrayList();
  
  feet = new Spring2D(width/2, 20, 2, gravity, 40, 0.2);
  body = new Spring2D(width/2, 300, 10, gravity, 100, 0.8);
  head = new Spring2D(width/2, 500, 6, gravity, 60, 0.5);
  eye = new Spring2D(width/2, 600, 2, gravity, 20, 0.2);
  
  springs.add(feet);
  springs.add(body);
  springs.add(head);
  springs.add(eye);
  
  
}
 
void draw()
{
  background(204);
  Spring2D firstspring = (Spring2D) springs.get(0);
  firstspring.update(width/2, 50, 50);
  firstspring.display();
 
  for (int i=1; i<springs.size(); i++) {
    Spring2D spring = (Spring2D) springs.get(i);
    Spring2D backspring = (Spring2D) springs.get(i-1);
    spring.update(backspring.x, backspring.y, backspring.ty);
    spring.display();
  }
  
  
}

void mousePressed() {
  for(int i=1; i<springs.size(); i++) {
    Spring2D spring = (Spring2D) springs.get(i);
    if(abs(spring.x-mouseX) < spring.radius && abs(spring.y-mouseY) < spring.radius) {
      spring.drag = true;
    } else {
      spring.drag = false;
    }
  }
}

void mouseReleased() {
  for(int i=1; i<springs.size(); i++) {
    Spring2D spring = (Spring2D) springs.get(i);
    spring.drag = false;
  }
}
 


class Spring2D {
  float vx, vy; // The x- and y-axis velocities
  float x, y; // The x- and y-coordinates
  float gravity;
  float mass;
  float radius;
  float stiffness;
  float damping = 0.9;
  boolean drag = false;
  
  float tx, ty;
   
  Spring2D(float xpos, float ypos, float m, float g, float r, float k) {
    tx = xpos;
    ty = ypos;
    x = xpos;
    y = ypos;
    mass = m;
    gravity = g;
    radius = r;
    stiffness = k;
  }
   
  void update(float targetX, float targetY, float ty0) {
    if(drag) {
      x = mouseX;
      y = mouseY;
      return;
    }
    float forceX = (targetX - x) * stiffness;
    float ax = forceX / mass;
    vx = damping * (vx + ax);
    x += vx;
    float forceY = ((targetY - y)-(ty0 - ty)) * stiffness;
    forceY += gravity;
    float ay = forceY / mass;
    vy = damping * (vy + ay);
    y += vy;
  }
   
  void display() {
    ellipse(x, y, radius*2, radius*2);
  }
}

Final Product

I scanned construction paper to give the final app a tactile appearance.

PurpleCircles.png
OrangeTriangles.png
RedSquares.png

Copyright Joe Kane Design 2023