void reset(){
for (int i=0; i<numa; i++){
for (int j=0; j<numb; j++){
X[i][j] = new PVector(elementWidth * (i)+width/8,
elementWidth * (j)+height/8,
random(-0.1,0.1));
V[i][j] = new PVector();
}
}
}
void physics(){
for (int i=0; i<numa; i++){
for (int j=0; j<numb; j++){
F[i][j] = new PVector(0.0,gravity,0.0);
}
}
for (int i=0; i<numa; i++){
for (int j=0; j<numb; j++){
normalForce(i,j);
windForce(i,j);
}
}
collide();
for (int i=0; i<numa; i++){
for (int j=0; j<numb; j++){
V[i][j].add(F[i][j]);
X[i][j].add(V[i][j]);
}
}
useConstraint();
}
void drawSheet(){
noStroke();
for (int j=0; j<numb-1; j++){
beginShape(TRIANGLE_STRIP);
texture(flag);
float xtweek = 1.02;
float ytweek = 1.05;
for (int i=0; i<numa; i++){
vertex(X[i][j].x, X[i][j].y, X[i][j].z,
elementWidth*i*xtweek, elementWidth*j*ytweek);
vertex(X[i][j+1].x, X[i][j+1].y, X[i][j+1].z,
elementWidth*i*xtweek, elementWidth*(j+1)*ytweek);
}
endShape();
}
}
void setupConstraint(){
for (int j=0; j<numb; j++){
constraint[j] = new PVector(X[0][j].x,
X[0][j].y,
X[0][j].z);
}
}
void useConstraint(){
for (int j=0; j<numb; j++){
X[0][j] = new PVector(constraint[j].x,
constraint[j].y,
constraint[j].z);
V[0][j] = new PVector();
}
}
void normalForce(int i, int j){
int a = i+1;
int b = j;
force2(i,j,a,b,1);
a = i-1;
b = j;
force2(i,j,a,b,1);
a = i;
b = j+1;
force2(i,j,a,b,1);
a = i;
b = j-1;
force2(i,j,a,b,1);
a = i+1;
b = j+1;
force2(i,j,a,b,pow(2,0.5));
a = i-1;
b = j+1;
force2(i,j,a,b,pow(2,0.5));
a = i+1;
b = j-1;
force2(i,j,a,b,pow(2,0.5));
a = i-1;
b = j-1;
force2(i,j,a,b,pow(2,0.5));
boolean jump = true;
if (jump == true){
int jumper = 2;
a = i+jumper;
b = j;
force2(i,j,a,b,jumper);
a = i-jumper;
b = j;
force2(i,j,a,b,jumper);
a = i;
b = j+jumper;
force2(i,j,a,b,jumper);
a = i;
b = j-jumper;
force2(i,j,a,b,jumper);
a = i+jumper;
b = j+jumper;
force2(i,j,a,b,jumper*pow(2,0.5));
a = i-jumper;
b = j+jumper;
force2(i,j,a,b,jumper*pow(2,0.5));
a = i+jumper;
b = j-jumper;
force2(i,j,a,b,jumper*pow(2,0.5));
a = i-jumper;
b = j-jumper;
force2(i,j,a,b,jumper*pow(2,0.5));
}
}
void force2(int i,int j,int a,int b,float distMult){
float eW2 = elementWidth * distMult;
if ((a>=0)&&(b>=0)&&(a<numa)&&(b<numb)){
PVector dx = PVector.sub(X[a][b], X[i][j]);
float bufferWidth = 0.01 * elementWidth;
float delta = 0;
if ((dx.mag() < eW2 - bufferWidth/2)||
(dx.mag() > eW2 + bufferWidth/2)){
delta = abs(dx.mag() - eW2)
- bufferWidth/2;
}
int sighn = 0;
if (dx.mag() < eW2 - bufferWidth/2){
sighn = -1;
}else if (dx.mag() > eW2 + bufferWidth/2){
sighn = +1;
}
dx.normalize();
float v1 = dx.dot(V[i][j]);
float v2 = dx.dot(V[a][b]);
float dv = v2 - v1;
float fmag = k * delta * sighn + c * dv;
PVector df = PVector.mult(dx,fmag);
F[i][j].add(df);
F[a][b].sub(df);
}
}
void windForce(int i,int j){
// NOTE: vector selected based on right hand rule
int a = i+1;
int b = j;
int c = i;
int d = j+1;
wind2(i,j,a,b,c,d);
a = i;
b = j+1;
c = i-1;
d = j;
wind2(i,j,a,b,c,d);
a = i-1;
b = j;
c = i;
d = j-1;
wind2(i,j,a,b,c,d);
a = i;
b = j-1;
c = i+1;
d = j;
wind2(i,j,a,b,c,d);
}
void wind2(int i,int j,int a,int b,int c,int d){
PVector windV = new PVector(wind,0.0,0.0);
if ((a>=0)&&(b>=0)&&(a<numa)&&(b<numb)){
if ((c>=0)&&(d>=0)&&(c<numa)&&(d<numb)){
PVector ab = PVector.sub(X[a][b], X[i][j]);
PVector cd = PVector.sub(X[c][d], X[i][j]);
PVector un = ab.cross(cd);
un.normalize();
float fmag = un.dot(windV);
F[i][j].add(PVector.mult(un,fmag));
}
}
}