/** * Relativistischer Flug durch ein Gitter * * Corvin Zahn 1.3.2003 * * Beispielprogramm zum in * ASTRONOMIE+RAUMFAHRT im Unterricht 2/2003 * erschienenen Artikel * Tempolimit: Lichtgeschwindigkeit * -- Beobachtungen bei Hochgeschwindigkeitsfluegen -- * v. U. Kraus * * (Onlineversion des Artikels: http://www.tempolimit-lichtgeschwindigkeit.de/) * */ /** Dieses Programm berechnet, wie ein relativistischer Flug durch ein Gitter aussieht. Komponenten =========== Objekt-Beschreibung ------------------- class Punkt, Kante, Objekt allgemeine Datenstrukturen zur Speicherung eines beliebigen "Drahtobjektes". konkrete Definition eines Gitterobjektes ---------------------------------------- class Gitter definiert ein Gitter der Groesse 10*10 am Koordinatenursprung. Das Gitter ist parallel zur yz-Ebene ausgerichtet, die Kamera bewegt sich laengs der x-Achse darauf zu. Physik ------ class Objekt, Funktion projiziere_punkt Abbildung eines Objektpunktes auf die Bildebene. Grafische Darstellung, user interface ------------------------------------- class RealFlug verwendete Einheiten ==================== Zeiteinheit: 1 Sekunde Laengeneinheit: 1 Lichtsekunde = 300000km */ import java.applet.Applet; import java.awt.*; import java.awt.event.*; /** * Konstanten */ class CONST { // Lichtgeschwindigkeit = 1 Lichtsekunde/Sekunde public static final double c = 1; // l ist die Laenge der Kamera public static final double l = 1; // Startposition der Kamera public static final double kamera_start_pos = -20; } /** * beschreibt einen Punkt im dreidimensionalen Raum */ class Punkt { /// erzeugt Punkt an den Koordinaten x,y,z public Punkt(double x, double y, double z) { s = new double[3]; //{x, y, z}; s[0] = x; s[1] = y; s[2] = z; } /// speichert die Koordinaten eines Punktes double s[]; } /** * beschreibt eine Objektkante bestehend aus einer Reihe von Punkten */ class Kante { /// erzeugt neue Kante, bestehend aus n Punkten public Kante(int n) { punkte = new Punkt[n]; } /// speichert eine Liste v. Punkten Punkt punkte[]; } /** * beschreibt ein Drahtgitterobjekt bestehend aus einer Anzahl von Kanten. * Dies ist eine Basisklasse fuer beliebige Objekte. Ein konkretes Objekt * wird in einer abgeleiteten Klasse (s.u. class Gitter) definiert. */ class Objekt { /// Konstruktor public Objekt() { } /** * Projiziert den Punkt raumpunkt auf die Bildebene der bei * (kamera_pos, 0, 0) befindlichen, sich mit der Geschwindigkeit v * in x-Richtung bewegenden Kamera. * Falls die Projektion moeglich ist, werden in bildpunkt die Koordinaten * auf der Bildebene zurueckgegeben und der Rueckgabewert ist true. */ public boolean projiziere_punkt(double kamera_pos, double v, Punkt raumpunkt, double[] bildpunkt) { // Koordinaten des abzubildenden Punktes relativ zur Kamera // = -Richtungsvektor des Lichtstrahls double x = raumpunkt.s[0] - kamera_pos; double y = raumpunkt.s[1]; double z = raumpunkt.s[2]; // Richtungsvektor in einen Photonengeschwindigkeitsvektor umrechnen double cx = CONST.c * x/Math.sqrt(x*x + y*y + z*z); double cy = CONST.c * y/Math.sqrt(x*x + y*y + z*z); double cz = CONST.c * z/Math.sqrt(x*x + y*y + z*z); // Auftreffpunkt eines Photons auf der Bildebene berechnen: try { // ll ist die Lorentz-kontrahierte Laenge der Kamera double ll = CONST.l * Math.sqrt(1 - (v*v)/(CONST.c*CONST.c)); // Zeit, die ein Photon zum Durchqueren der Kamera benoetigt double dt = ll / (v + cx); // Die Zeit muss > 0 sein (sonst trifft das Photon nicht auf // das Bildfeld) if (dt < 0) return false; // Der vom Photon getroffene Punkt auf dem Bildfeld wird durch // Multiplikation dieser Zeitspanne mit den Geschwindigkeits- // komponenten parallel zum Bildfeld berechnet bildpunkt[0] = cy * dt; bildpunkt[1] = cz * dt; return true; } catch (Exception ex) { // falls wir zB durch Null geteilt haben, gibt es keine Projektion return false; } } /** * Projiziere das Objekt auf die Bildebene der bei (x, 0, 0) * befindlichen, sich mit der Geschwindigkeit v in x-Richtung * bewegenden Kamera */ public void draw(Graphics g, double x, double v) { double[] letzter_bildpunkt = null; // alle Kanten durchgehen for (int i=0; i= 0 && x0 < bild_breite && y0 >= 0 && y0 < bild_hoehe && x1 >= 0 && x1 < bild_breite && y1 >= 0 && y1 < bild_hoehe) { g.drawLine(x0, y0, x1, y1); // zuletzt gezeichneten Bildpunkt merken letzter_bildpunkt = bildpunkt; } else { // Wenn Linie nicht mehr aufs Bild passt, das // naechste Mal eine neue Linie beginnen neue_linie = true; } } } else { neue_linie = true; } } } } /// speichert eine Liste v. Kanten Kante[] kanten; } /** * erzeugt ein Gitter */ class Gitter extends Objekt { /** * Konstruktor */ public Gitter() { // Gitter besteht aus 10 horizontalen u. 10 vertikalen Kanten und // hat eine Groesse v. 10 auf 10 Lichtsekunden int res = 10; double kantenlaenge = 10; double x_position = 0; kanten = new Kante[2*res]; // horizontale Kanten for (int i=0; i