import java.applet.*; 
import java.awt.*; 
import java.awt.image.*; 
import java.awt.event.*; 
import java.io.*; 
import java.net.*; 
import java.text.*; 
import java.util.*; 
import java.util.zip.*; 

public class udk_07_bend extends BApplet {
// UdK Computational design
// Marius Watz 2003
// http://www.evolutionzone.com/udk/
//
// udk_07_bend
// How to "bend" and "stack" a series of points.

Vec2D v[];
int num,cnt;

void setup() {
  size(400,400);
  num=50;
  v=new Vec2D[num];
  for(int i=0; i<num; i++) v[i]=new Vec2D(0,0);
  stack(200,-200);
  bend(45);
  ellipseMode(CENTER_DIAMETER);
}

void loop() {
  for(int i=0; i<num; i++) v[i].set(0,0);
  stack(50,-200);

  bend(10+sin(radians((cnt/2)%180))*60);
  stack(-sin(radians((cnt/4)%180))*100,sin(radians((cnt/7)%360))*150);
  cnt++;

  translate(width/2,height/2);
  for(int j=0; j<7; j++) {
    rotate(PI/3.5f);
    for(int i=0; i<num; i++) ellipse(v[i].x,v[i].y,6,6);
  }  
}

void bend(float deg) {
  deg=radians(deg/(float)(num-1));
  for(float i=0; i<num; i++) v[(int)(i)].rotate(deg*i);
}

void stack(float x,float y) {
  x=x/(float)(num-1);
  y=y/(float)(num-1);
  for(float i=0; i<num; i++) v[(int)(i)].add(x*i,y*i);
}

// General vector class for 2D vectors
class Vec2D {
  float x,y;

  Vec2D(float _x,float _y) {
    x=_x;
    y=_y;
  }

  Vec2D(Vec2D v) {
    x=v.x;
    y=v.y;
  }

  void set(float _x,float _y) {
    x=_x;
    y=_y;
  }

  void set(Vec2D v) {
    x=v.x;
    y=v.y;
  }

  void add(float _x,float _y) {
    x+=_x;
    y+=_y;
  }

  void add(Vec2D v) {
    x+=v.x;
    y+=v.y;
  }

  void sub(float _x,float _y) {
    x-=_x;
    y-=_y;
  }

  void sub(Vec2D v) {
    x-=v.x;
    y-=v.y;
  }

  void mult(float m) {
    x*=m;
    y*=m;
  }

  void div(float m) {
    x/=m;
    y/=m;
  }

  float length() {
    return sqrt(x*x+y*y);
  }

  float angle() {
    return atan2(y,x);
  }

  void rotate(float val) {
    float cosval=cos(val);
    float sinval=sin(val);

    x=x*cosval - y*sinval;
    y=x*sinval + y*cosval;
  }
}

}
