作者 主题: p0629a_2013_worms  (阅读 8036 次)

RavenKwok

  • Sr. Member
  • ****
  • 帖子: 277
  • Artist/ Animator/ Coder/ Cynical Asshole
p0629a_2013_worms
« 于: 七月 03, 2013, 12:46:31 上午 »
度完一个月假期后的暖手小作。



via openprocessing

http://openprocessing.org/sketch/102905

程序代码

//Raven Kwok (aka Guo Ruiwen)
//p0629a_2013_worms
/*
 
raystain@gmail.com
ravenkwok.com
flickr.com/ravenkwok
vimeo.com/ravenkwok
weibo.com/ravenkwok
 
*/
 
 
StageManager sm;
boolean onPressed;
boolean newVertexSpawn;
int currentDrawingWormIndex;
 
void setup() {
  size(500, 500);
  colorMode(HSB);
  smooth();
  frameRate(30);
  sm = new StageManager();
  sm.spawnItf(width/2,height/2,0.001);
}
 
void draw() {
  background(255);
  if (onPressed) {
    Worm currentW = (Worm) sm.worms.get(currentDrawingWormIndex);
    currentW.spawnV(mouseX, mouseY);
    if(newVertexSpawn){
      sm.checkIntersect();
    }
  }else{
    sm.checkVanish();
  }
  sm.update();
  sm.display();
}
 
void mousePressed() {
  sm.spawnW();
  currentDrawingWormIndex = sm.worms.size()-1;
  onPressed = true;
}
 
void mouseReleased() {
  onPressed = false;
}
 
class Interference{
   
  PVector loc;
  float force;
   
  Interference(float initX,float initY,float force){
    this.force = force;
    loc = new PVector(initX,initY);
  }
}
class StageManager {
 
  ArrayList worms;
  ArrayList itfs;
  int maxPAmt;
 
  StageManager() {
    worms = new ArrayList();
    itfs = new ArrayList();
  }
 
  void update() {
    for (int i=0;i<worms.size();i++) {
      Worm eachW = (Worm) worms.get(i);
 
      eachW.repelWithin();
      eachW.tensedWithin();
 
      for (int j=i+1;j<worms.size();j++) {
        Worm repWorm = (Worm) worms.get(j);
        eachW.repelWithOther(repWorm);
      }
 
      for (int k=0;k<itfs.size();k++) {
        Interference eachItf = (Interference) itfs.get(k);
        eachW.interferedBy(eachItf, eachItf.force);
      }
 
      eachW.update();
    }
  }
 
  void display() {
    for (int i=0;i<worms.size();i++) {
      Worm eachW = (Worm) worms.get(i);
      eachW.display();
    }
  }
   
  void checkVanish(){
    for (int i = worms.size()-1;i>=0;i--){
      Worm eachW = (Worm) worms.get(i);
      if(eachW.vertices.size()<=3){
        worms.remove(i);
      }
    }
  }
 
  void checkIntersect() {
 
    Worm currentW = (Worm) worms.get(currentDrawingWormIndex);
    int lastVertexIndex = currentW.vertices.size()-2;
 
    if (lastVertexIndex>=0) {
      Vertex currentVertex = (Vertex)currentW.vertices.get(lastVertexIndex+1);
      Vertex lastVertex = (Vertex)currentW.vertices.get(lastVertexIndex);
      PVector cSeg1v1 = new PVector(currentVertex.loc.x, currentVertex.loc.y);
      PVector cSeg1v2 = new PVector(lastVertex.loc.x, lastVertex.loc.y);
 
      for (int i=0;i<worms.size();i++) {
        if (i==currentDrawingWormIndex) {
          continue;
        }
        else {
          Worm eachW = (Worm) worms.get(i);
          for (int j=1;j<eachW.vertices.size()-2;j++) {
            Vertex v1 = (Vertex)eachW.vertices.get(j);
            Vertex v2 = (Vertex)eachW.vertices.get(j+1);
            PVector cSeg2v1 = new PVector(v1.loc.x, v1.loc.y);
            PVector cSeg2v2 = new PVector(v2.loc.x, v2.loc.y);
            if (intersect(cSeg1v1, cSeg1v2, cSeg2v1, cSeg2v2)) {
 
              Worm cutOffSeg = new Worm();
              worms.add(cutOffSeg);
 
              for (int k=j;k<eachW.vertices.size();k++) {
                Vertex ogV = (Vertex)eachW.vertices.get(k);
                Vertex addedV;
                if (k==j) {
                  addedV = new Vertex((v1.loc.x+v2.loc.x)*0.5, (v1.loc.y+v2.loc.y)*0.5);
                }else {
                  addedV = new Vertex(ogV.loc.x, ogV.loc.y);
                }
                cutOffSeg.vertices.add(addedV);
              }
 
              v1.loc.x = (v1.loc.x+v2.loc.x)*0.5;
              v1.loc.y = (v1.loc.y+v2.loc.y)*0.5;
              for (int k=eachW.vertices.size()-1;k>j+1;k--) {
                eachW.vertices.remove(k);
              }
            }
          }
        }
      }
    }
  }
 
  boolean intersect(PVector s1v1, PVector s1v2, PVector s2v1, PVector s2v2) {
    float denominator = (s1v1.x-s1v2.x)*(s2v1.y-s2v2.y)-(s1v1.y-s1v2.y)*(s2v1.x-s2v2.x);
    if (denominator==0) {
      return false;
    }
    else {
      float istX = ((s1v1.x*s1v2.y-s1v2.x*s1v1.y)*(s2v1.x-s2v2.x)-(s1v1.x-s1v2.x)*(s2v1.x*s2v2.y-s2v2.x*s2v1.y))/denominator;
      float istY = ((s1v1.x*s1v2.y-s1v2.x*s1v1.y)*(s2v1.y-s2v2.y)-(s1v1.y-s1v2.y)*(s2v1.x*s2v2.y-s2v2.x*s2v1.y))/denominator;
      if ( (istX-s1v1.x)*(istX-s1v2.x)<=0 && (istY-s1v1.y)*(istY-s1v2.y)<=0 && (istX-s2v1.x)*(istX-s2v2.x)<=0 && (istY-s2v1.y)*(istY-s2v2.y)<=0 ) {
        return true;
      }
      else {
        return false;
      }
    }
  }
 
  void spawnW() {
    Worm addedW = new Worm();
    worms.add(addedW);
  }
 
  void spawnItf(float initX, float initY, float force) {
    Interference addedItf = new Interference(initX, initY, force);
    itfs.add(addedItf);
  }
}
 
class Vertex{
   
  PVector loc,vel,acc;
  float thres,thresT,decay;
   
  Vertex(float initX,float initY){
     
    loc = new PVector(initX,initY);
    vel = new PVector(0,0);
    acc = new PVector(0,0);
     
    decay = 0.9;
    thres = 0;
    thresT = 20;
  }
   
  void update(){
    thres = lerp(thres,thresT,0.1);
    vel.add(acc);
    vel.limit(10);
    vel.mult(decay);
    loc.add(vel);
    acc.set(0,0,0);
  }
   
  void repel(Vertex repV){
    PVector dir = new PVector(0, 0);
    float repForce = 0;
    dir = PVector.sub(loc, repV.loc);
    if (dir.mag() < thres) {
        repForce = 1/(dir.mag()+1);
        dir.normalize();
        dir.mult(repForce);
        acc.add(dir);
        repV.acc.sub(dir);
      }
  }
   
  void interferedBy(Interference itf, float force){
    PVector dir = new PVector(0, 0);
    float distance = 0;
    dir = PVector.sub(itf.loc, loc);
    distance = dir.mag();
    dir.normalize();
    dir.mult(distance*force);
    acc.add(dir);
  }
   
  void tensedBy(Vertex v1,Vertex v2, float force){
    PVector mid = new PVector((v1.loc.x+v2.loc.x)*0.5,(v1.loc.y+v2.loc.y)*0.5);
    PVector dir = new PVector(0, 0);
    float distance = 0;
    dir = PVector.sub(mid, loc);
    distance = dir.mag();
    dir.normalize();
    dir.mult(distance*force);
    acc.add(dir);
  }
   
  void display(){
    ellipse(loc.x,loc.y,5,5);
  }
}
class Worm {
 
  ArrayList vertices;
 
  Worm() {
    vertices = new ArrayList();
  }
 
  void update() {
    for (int i=0;i<vertices.size();i++) {
      Vertex eachV = (Vertex) vertices.get(i);
      eachV.update();
    }
  }
 
  void repelWithin() {
    for (int i=1;i<vertices.size()-1;i++) {
      Vertex eachV = (Vertex) vertices.get(i);
      for (int j=i+1;j<vertices.size()-1;j++) {
        Vertex repV = (Vertex) vertices.get(j);
        eachV.repel(repV);
      }
    }
  }
 
  void repelWithOther(Worm repWorm) {
    for (int i=1;i<vertices.size()-1;i++) {
      Vertex eachV = (Vertex) vertices.get(i);
      for (int j=1;j<repWorm.vertices.size()-1;j++) {
        Vertex repV = (Vertex) repWorm.vertices.get(j);
        eachV.repel(repV);
      }
    }
  }
   
  void tensedWithin(){
    for (int i=1;i<vertices.size()-1;i++) {
      Vertex eachV = (Vertex) vertices.get(i);
      Vertex pV1 = (Vertex) vertices.get(i-1);
      Vertex nV1 = (Vertex) vertices.get(i+1);
      eachV.tensedBy(pV1,nV1,0.01);
      if(i>1&&i<vertices.size()-2){
        Vertex pV2 = (Vertex) vertices.get(i-2);
        Vertex nV2 = (Vertex) vertices.get(i+2);
        eachV.tensedBy(pV1,nV2,0.005);
        eachV.tensedBy(pV2,nV1,0.005);
        eachV.tensedBy(pV2,nV2,0.005);
      }
    }
  }
 
  void interferedBy(Interference itf, float force) {
    for (int i=0;i<vertices.size();i++) {
      Vertex eachV = (Vertex) vertices.get(i);
      eachV.interferedBy(itf, force);
    }
  }
 
  void display() {
    noFill();
    stroke(0);
    strokeWeight(2);
    if (vertices.size()>3) {
      for (int i=1;i<vertices.size()-2;i++) {
        Vertex control1 = (Vertex) vertices.get(i-1);
        Vertex draw1 = (Vertex) vertices.get(i);
        Vertex draw2 = (Vertex) vertices.get(i+1);
        Vertex control2 = (Vertex) vertices.get(i+2);
        curve(control1.loc.x, control1.loc.y, draw1.loc.x, draw1.loc.y, draw2.loc.x, draw2.loc.y, control2.loc.x, control2.loc.y);
      }
    }
  }
 
  void spawnV(float initX, float initY) {
    if (vertices.size()==0) {
      Vertex addedV = new Vertex(initX, initY);
      vertices.add(addedV);
      newVertexSpawn = true;
    }
    else {
      Vertex lastV = (Vertex) vertices.get(vertices.size()-1);
      if (dist(initX, initY, lastV.loc.x, lastV.loc.y)>=5) {
        Vertex addedV = new Vertex(initX, initY);
        vertices.add(addedV);
        newVertexSpawn = true;
      }else{
        newVertexSpawn = false;
      }
    }
  }
}


RavenKwok

  • Sr. Member
  • ****
  • 帖子: 277
  • Artist/ Animator/ Coder/ Cynical Asshole
Automata sample added
« 回复 #1 于: 七月 03, 2013, 08:47:48 上午 »
Automata sample added


RavenKwok

  • Sr. Member
  • ****
  • 帖子: 277
  • Artist/ Animator/ Coder/ Cynical Asshole
Another automata sample added
« 回复 #2 于: 七月 05, 2013, 04:50:27 上午 »

Contra

  • SuperManager
  • Sr. Member
  • *****
  • 帖子: 347
  • AC, game dev, new media art&tech.
    • i'm Contra
Re: p0629a_2013_worms
« 回复 #3 于: 七月 05, 2013, 09:06:29 上午 »
密集死我了 =皿=
百爪挠心,猴子偷桃

RavenKwok

  • Sr. Member
  • ****
  • 帖子: 277
  • Artist/ Animator/ Coder/ Cynical Asshole
Re: p0629a_2013_worms
« 回复 #4 于: 七月 08, 2013, 12:03:22 上午 »
还有猴子偷桃这样的神效。。。

小雍子

  • Newbie
  • *
  • 帖子: 20
Re: p0629a_2013_worms
« 回复 #5 于: 七月 08, 2013, 02:35:53 上午 »
我操 半夜看瞬间痿了的感觉。。

RavenKwok

  • Sr. Member
  • ****
  • 帖子: 277
  • Artist/ Animator/ Coder/ Cynical Asshole
Re: p0629a_2013_worms
« 回复 #6 于: 七月 11, 2013, 01:17:42 下午 »
阿波罗男子医院助您重振雄风。

kyy921

  • Full Member
  • ***
  • 帖子: 101
Re: p0629a_2013_worms
« 回复 #7 于: 七月 14, 2013, 10:59:25 上午 »
这个是至今为止你做出来最喜欢的:D

RavenKwok

  • Sr. Member
  • ****
  • 帖子: 277
  • Artist/ Animator/ Coder/ Cynical Asshole
Re: p0629a_2013_worms
« 回复 #8 于: 七月 15, 2013, 12:20:05 下午 »
这。。。

kennyma1991

  • Newbie
  • *
  • 帖子: 9
Re: p0629a_2013_worms
« 回复 #9 于: 七月 22, 2013, 04:27:32 下午 »
so nice

Allen

  • Newbie
  • *
  • 帖子: 4
Re: p0629a_2013_worms
« 回复 #10 于: 七月 31, 2013, 11:51:04 上午 »
兔子那个好萌!