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.

7. Im Uhrzeigersinn – Stunden, Minuten, Sekunden

10. November 2010

Bei dieser Übung galt es eine Uhr neu zu gestalten. Anfangs habe ich mit Gradienten experimentiert und bin dann über Zwischenschritte bei sich umkreisenden Zeiteinheiten gelandet. Die 24 Stunden des Tages bilden den Hauptkreis und die Minuten kreisen um die Stunde, die Sekunden um die Minuten und die Millisekunden und die Sekunden. Abfragen
  • Stunde: hour()
  • Minuten: minute()
  • Sekunden: second()
  • Millisekunden seit Programmstart: millis()
  • Aktuelle Systemzeit: System.currentTimeMillis()
Ideengang
  1. Zuerst habe ich zwei Prototypen mit Gradienten erstellt. Die Idee dabei war, dass jede Zeiteinheit (Stunde/Minute/Sekunde) einen Helligkeitswert besitzt und sich der Hintergrund dem Wert der aktuellen Stunde anpasst, sodass sich ein Fadeout beim Abschnitt der aktuellen Stunde ergibt.
  2. Danach habe ich innerhalb der Stundenbalken noch einen vertikalen Gradienten für die Minuten eingeführt. Hierbei hat sich gezeigt, dass die Abstufungen des Verlaufes durch die 60 Abschnitte so fein werden, dass diese fast nicht mehr zu unterscheiden sind, was das Ablesen der Zeit erschwerte.
  3. Nach verschiedene Varianten mit 1 Verlauf über 24h, oder einem zunehmenden und abnehmenden Verlauf über diese Zeit, bin ich dann von den rechteckigen Abschnitten bei runden gelandet.
  4. Hier war mir dann das Ganze zu statisch, sprich die Helligkeitswerte wurden angepasst, aber nur wenig Animation konnte ich in diesem Konzept umsetzen.
  5. So habe ich die Zeiteinheiten neu zusammenzustellen versucht und bin dann beim finalen Konzept gelandet, bei die kleinere Zeiteinheit als Kreis um die grössere dreht.
Koordinaten eines Kreisabschnittes berechnen: xP = xM + r*cos(ß) yP = yM + r*sin(ß) xP: x-Koordinate des Punktes yP: y-Koordinate des Punktes xM: x-Koordinate des Mittelpunktes yM: y-Koordinate des Mittelpunktes r: Radius des Kreises ß: Winkel Meine entsprechende Processing-Funktion
// get coords (x/y) of point on circle with given angle
PVector getCoordsOnCircle(float xM, float yM, float radius, float angle) {

  PVector cP = new PVector();
  cP.x = xM + radius*cos(radians(angle)); // xP = xM + r*cos(ß)
  cP.y = yM + radius*sin(radians(angle)); // yP = yM + r*sin(ß)

  return cP;
}
Der gesamte Processing-Code
int colorIncrease = 60; // added to rgb from bg circle to millis circle
int[] colorSelectedBase = {102,51,51}; // rgb for selected hour
int[] colorDefaultBase =  {51,51,102}; // rgb default color
int scaleH = 3;
int scaleM = 2;
int radiusH = 300; // radius circle hours are placed on
int radiusT = 200;  // radius circle texts are placed on

void setup()
{
  size(800, 800);
  smooth();
  // load font and set font size
  PFont font = loadFont("00Basix-48.vlw");
  textFont(font, 24);
}

void draw()
{
  background(224,224,255);
  noStroke();

  // get milliseconds (system)
  // modulo 1000 used to get current
  int mi = int(System.currentTimeMillis()%1000);

  // Background Circles
  // I split up the background circles and the animated indexes (minutes, secondds)
  // in order to have the stacking order right. Animated indexes overlap neighbouring circles
  for(int i=0; i<24; i++) {

    int angleH = (360/24)*i-90;// minute()*6;
    PVector pH = getCoordsOnCircle(width/2, height/2, radiusH, angleH);
    pushStyle();
      setFillColor(i, 0, false);
      ellipse(pH.x, pH.y, 24*scaleH, 24*scaleH);
    popStyle();

    int angleT = angleH-1;// minute()*6;
    PVector pT = getCoordsOnCircle(width/2, height/2, radiusT, angleT);
    pushStyle();
      // text label
      setFillColor(i, 0, false);
      text(i,pT.x,pT.y);
    popStyle();
  }

  // Indexes Minutes / Seconds / Millis
  for(int i=0; i<24; i++) {

    int angleH = (360/24)*i-90;// minute()*6;
    PVector pH = getCoordsOnCircle(width/2, height/2, radiusH, angleH);

      // Minutes
      int radiusM = 24*scaleM;
      int angleM = (minute()*6)-90;
      PVector pM = getCoordsOnCircle(pH.x, pH.y, radiusM, angleM);
      pushStyle();
        setStrokeColor(i, 0, false);
        setFillColor(i, 1, false);
        ellipse(pM.x, pM.y, 28*scaleM, 28*scaleM);
      popStyle();

      // Seconds
      int radiusS = 8*scaleH;
      int angleS = (second()*6)-90;
      PVector pS = getCoordsOnCircle(pM.x, pM.y, radiusS, angleS);
      pushStyle();
        setStrokeColor(i, 1, false);
        setFillColor(i, 2, false);
        ellipse(pS.x, pS.y, 12*scaleH, 12*scaleH);
      popStyle();

      // Milliseconds
      int radiusMs = 6*scaleH;
      float angleMs = (360*(mi/1000.0));
      PVector pMs = getCoordsOnCircle(pS.x, pS.y, radiusMs, angleMs);
      pushStyle();
        setStrokeColor(i, 2, false);
        setFillColor(i, 3, true);
        ellipse(pMs.x, pMs.y, 24, 24);
      popStyle();

  }

}

// get coords (x/y) of point on circle with given angle
PVector getCoordsOnCircle(float xM, float yM, float radius, float angle) {

  PVector cP = new PVector();
  cP.x = xM + radius*cos(radians(angle)); // xP = xM + r*cos(ß)
  cP.y = yM + radius*sin(radians(angle)); // yP = yM + r*sin(ß)

  return cP;
}

// set fill color (current hour highlighted)
void setFillColor(int cHour, int depth, boolean special) {
  if (cHour==hour()) {
    if (special==true) {
      fill(255);
    } else {
      fill(colorSelectedBase[0]+(colorIncrease*depth), colorSelectedBase[1]+(colorIncrease*depth), colorSelectedBase[2]+(colorIncrease*depth));
    }
  } else {
    fill(colorDefaultBase[0]+(colorIncrease*depth), colorDefaultBase[1]+(colorIncrease*depth), colorDefaultBase[2]+(colorIncrease*depth));
  }
}

// set stroke color (current hour highlighted)
void setStrokeColor(int cHour, int depth, boolean special) {
  if (cHour==hour()) {
    if (special==true) {
      stroke(255);
    } else {
      stroke(colorSelectedBase[0]+(colorIncrease*depth), colorSelectedBase[1]+(colorIncrease*depth), colorSelectedBase[2]+(colorIncrease*depth));
    }
  } else {
    stroke(colorDefaultBase[0]+(colorIncrease*depth), colorDefaultBase[1]+(colorIncrease*depth), colorDefaultBase[2]+(colorIncrease*depth));
  }
}