Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

ForceFields 2

28. November 2012

Bei dieser Aufgabe hatten wir einen weiterführenden Code zu der letzten Aufgabe mit den Force Fields. Der Unterschied zum "alten" Code war, dass die Anfangspunkte nun nicht mehr immer am selben Ort waren, sondern immer neu berechnet wurden bei Mausklick (oder MouseDrag). Dies wurde mit einer Array-List gelöst, bei der die Punkte immer neu berechnet werden und jeweils das älteste Element in der Liste gelöscht wird. Wenn die Maus losgelassen wird, kehren die Punkte (oder Linien, in Form eines Polygons) jedoch wieder zum Ursprunkspunkt zurück. Aufgabe war es nun, diesen Code anzupassen und das Aussehen zu verändern. Bei der ersten Version hatte ich folgende Parameter verändert: Linienstärke, Anzahl Punkte, Farben Video: ForceFields3 Ber der Enversion habe ich noch mehr Punkte gesetzt und die ganze Fläche grösser gemacht. Zudem sind bei den Farben random-Werte drin, die das ganze spannender machen. Den Radius, bei dem die Punkte reagieren sollen habe ich zudem vergrössert und die "MouseDist" nach dem normalisieren mit 5 multipliziert. Das hatte die Auswirkung, dass das ganze lebendiger wirkte. Video: ForceFields4 Code:  

ArrayList<ForcePoint>  forcePointList = new ArrayList<ForcePoint>();
int                     borderDist = 30;
int                     gridX = 35;
int                     gridY = 35;

void setup()
{
  size(900,900);

  // setup the grid
  float stepX = (float)(width - borderDist * 2) / (gridX - 1);
  float stepY = (float)(height - borderDist * 2) / (gridY - 1);

  for(int x=0;x < gridX;x++)
  {
    for(int y=0;y < gridY;y++)
    {
      forcePointList.add(new ForcePointTrail((int)(stepX * x + borderDist),(int)(stepY * y + borderDist),500,0.8));
    }
  }
}

void draw()
{
  background(0);

  updateForceField();

  ForcePoint forcePoint;
  for(int i=0;i < forcePointList.size();i++)
  {
    forcePoint = forcePointList.get(i);

    forcePoint.update();
    forcePoint.draw();
  }
}

void updateForceField()
{
  ForcePoint forcePoint;

  for(int i=0;i < forcePointList.size();i++)
  {
    forcePoint = forcePointList.get(i);

    if(mousePressed &&  mouseButton == LEFT)
      forcePoint.setInput(mouseX,mouseY,0);
    else if(mousePressed &&  mouseButton == RIGHT)
      forcePoint.setInput(mouseX,mouseY,1);
  }
}
 

class ForcePoint
{
  int posX;
  int posY;
  float radius;
  PVector dir;
  float damperValue;
  float maxDist = 30;

  ForcePoint(int x,int y,float radius,float damperValue)
  {
    posX = x;
    posY = y;

    dir = new PVector(0,0);
    this.radius = radius;
    this.damperValue = damperValue;
  }

  void setInput(int mouseX,int mouseY,int extraFlag)
  {
    PVector mouseDist = new PVector(mouseX - posX,mouseY - posY);
    if(mouseDist.mag() < radius)
    {
      mouseDist.normalize();
      dir.add(PVector.mult(mouseDist,2));

      // check for max length
      if(dir.mag() > maxDist)
      {
        dir.normalize();
        dir = PVector.mult(dir,maxDist);
      }
    }
  }

  void update()
  {
    dir.mult(damperValue);
  }

  void draw()
  {
    stroke(255);

    point(posX,posY);
    line(posX,posY,
         dir.x + posX,dir.y + posY);
  }
}
 

class ForcePointTrail extends ForcePoint
{
  ArrayList<PVector>  _trail;
  int                 _trailMaxSize = 20;
  float               _dirMult = 2;
  float               _backDirMult = 0.01;
  color               _clr;

  ForcePointTrail(int x,int y,float radius,float damperValue)
  {
    super(x,y,radius,damperValue);

    _trail = new ArrayList<PVector>();
    _trail.add(new PVector(x,y));

    _clr = color(random(0,255),20,random(210,230),8);

  }

  void setInput(int mouseX,int mouseY,int extraFlag)
  {
    PVector endPos = lastPoint();
    PVector mouseDist = new PVector(mouseX - endPos.x,mouseY - endPos.y);

    if(mouseDist.mag() <= radius)
    {
      float strength = mouseDist.mag() / radius;
      float scaleVal = (1.0 - strength) * _dirMult;

      if(extraFlag == 1)
        scaleVal *= -1;

      mouseDist.normalize();
      mouseDist.mult(5);
      dir.add(PVector.mult(mouseDist,scaleVal));
    }
  }

  PVector lastPoint()
  {
    return _trail.get(_trail.size() - 1);
  }

  void update()
  {
    PVector endPos = lastPoint();
    PVector dirBack = PVector.sub(new PVector(posX,posY),endPos);

    dirBack.mult(_backDirMult);
    dir.add(dirBack);
    dir.mult(damperValue);

    PVector newEndPos = PVector.add(dir,endPos);
    _trail.add(newEndPos);

    // check if list reached the max. length
    if(_trail.size() > _trailMaxSize)
      _trail.remove(0);
  }

  void draw()
  {
    PVector pos;

    strokeWeight(20);
    stroke(_clr);
    noFill();

    beginShape();
    for(int i=0;i < _trail.size();i++)
    {
      pos = _trail.get(i);
      vertex(pos.x,pos.y);
    }
    endShape();
  }

}