Lösung der Aufgabe Baywatch oder das Prinzip von Fermat

Pierre de Fermat

 

// baywatch

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

int main(void)
{
  double x1, y1, x2, y2;  // Punkte am Land und im Wasser
  double v1, v2;          // Geschwindigkeit am Land und im Wasser
  double x;               // aktueller Zwischenpunkt auf der x-Achse
  double dx, dxMin;       // Schrittweite für x, Grenze der Schrittweite
  double s1, s2;          // Strecke am Land und im Wasser
  double t1, t2, t, talt;

  /*
    |y
    |                          o P2(x2,y2)
    |
    |    Wasser v2
    |               
    +--------------------o-------------->  x
    |                    x
    |
    |                  Land v1
    |
    o P1(x1,y1)
    |
  */

  x1 = 0;
  y1 = -20;
  x2 = 50;
  y2 = 20;
  v1 = 10.0;
  v2 = 4.0;
  dx = -100.0;
  dxMin = 0.01;

  x = 0.0;
  
  // Schleife, welche die Schrittweite jeweils verkleinert und die Richtung ändert
  // damit wir die Lösung immer mehr abwechselnd von rechts und links "eingekreist"
  do {
    dx = - 0.1*dx;
    printf("dx = %8.4f\n", dx);

    /* 
      die folgende Schleife berechnet für fortlaufende x-Werte 
      die Zeit um von P1 nach P2 zu kommen und merkt sich immer die Zeit aus der
      letzten Berechnung
      x und dx ist so gewählt, dass die Zeit zunächst immer kleiner wird, also x immer
      näher an den Punkt für die kleinste Zeit heranrückt. Wenn x Über diesen Punkt hinauskommt,
      wird die Zeit wieder grösser, das beendet die Schleife.
    */
    t = 1E20;
    do
    {
      talt = t;
      x = x + dx;
      s1 = sqrt(y1*y1 + x*x);
      t1 = s1/v1;
      s2 = sqrt( (x2 - x)*(x2 - x) + y2 * y2 );
      t2 = s2/v2;
      t = t1 + t2;
      printf("%7.3f  %13.9f\n", x, t);  // Kontrollausgabe
    } while (t < talt);  // solange die Zeit kleiner wird
      
  } while (fabs(dx) > dxMin);

  printf("Kleinste Zeit t = %8.3f bei x = %8.3f\n", talt, x - dx);
}