// Lissajou'sche Kurven
//
// Aufruf: lissa xfaktor yfaktor phasenversch
//
// Klaus Kusche, 2010

#include "sdlinterf.h"

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, const char *argv[])
{
  if (argc != 4) {
    fprintf(stderr, "Aufruf: %s xfaktor yfaktor phasenversch\n", argv[0]);
    exit(EXIT_FAILURE);
  }
  // Multiplikationsfaktoren der x- und y-Frequenz
  int xfaktor = atoi(argv[1]);
  int yfaktor = atoi(argv[2]);
  // Bewegungseffekt: Um welchen Winkel (Radiant) ändert sich
  // die Phasenverschiebung zwischen x- und y-Schwingung pro Bild?
  double phasenSchritt = atof(argv[3]);
  // winkelSchritt bestimmt die "Dichte" der Linie
  // (die Schrittweite der Zeichen-Schleife)
  // So berechnen, dass keine Löcher zwischen den Pixeln bleiben!
  // Je höher ein faktor, umso länger die Kurve, umso mehr Pixel sind nötig,
  // umso kleiner muss die Schrittweite sein
  double winkelSchritt;
  if (xfaktor >= yfaktor) {
    winkelSchritt = 1 / (500.0 * xfaktor);
  } else {
    winkelSchritt = 1 / (500.0 * yfaktor);
  }

  // Mitte des Fensters in x- und y-Richtung
  // SDL_X_SIZE ist die horizontale Fenstergröße in Pixeln
  const int mitteX = SDL_X_SIZE / 2;
  // SDL_Y_SIZE ist die vertikale Fenstergröße in Pixeln
  const int mitteY = SDL_Y_SIZE / 2;  
  
  sdlInit();

  // 1 Durchläuf der äußeren Schleife = ein komplettes Bild
  // Zählvariable der äußeren Schleife
  //  = Phasenverschiebung zwischen den beiden Sinuskurven
  // Schrittweite der äußeren Schleife = phasenSchritt (eingegeben)
  //  = Veränderung der Kurvenform zwischen zwei Bildern
  for (double phase = 0.0; ; phase += phasenSchritt) {  // endlos!
    sdlSetBlack();
    // Zählvariable der inneren Schleife: Aktueller Winkel der Grundschwingung
    // Eine Periode (360 Grad = 2 Pi Radiant) der Grundschwingung = ganze Kurve
    // Schrittweite der inneren Schleife = winkelSchritt (oben berechnet)
    for (double winkel = 0; winkel < 2 * M_PI; winkel += winkelSchritt) {
      // Berechnung der Pixelkoordinaten des aktuellen Punktes
      int x = mitteX + ((int) (sin(winkel * xfaktor) * (mitteX - 10)));
      int y = mitteY + ((int) (sin(winkel * yfaktor + phase) * (mitteY - 10)));
      sdlDrawPoint(x, y, 0, 255, 0);
    }
    sdlUpdate();
  }

  sdlExit();

  exit(EXIT_SUCCESS);
}
