Wie ein Strahl eine Kugel findet
Ein Strahl ist eine Gerade, die an einem Punkt beginnt und in eine Richtung läuft. Beim Ray Tracing, auf Deutsch Strahlverfolgung, schickt ein Programm für jedes Pixel einen Strahl in die Szene und fragt, welches Objekt er zuerst trifft.
Bei einer Kugel führt diese Frage auf eine Gleichung, die Sie mit der Schulformel lösen. Damit finden Sie, ob und wo ein Strahl eine Kugel trifft.
Am Ende dieser Lektion
Notiz
Ich kann berechnen, ob und wo ein Strahl eine Kugel trifft.
Schlüsselwörter
| Begriff | Was er bedeutet |
|---|---|
| Strahl | eine Gerade mit Startpunkt und Richtung |
| Vektor | drei Zahlen für einen Punkt oder eine Richtung |
| Skalarprodukt | Zahlen paarweise malnehmen und addieren |
| Diskriminante | die Zahl, die über die Treffer entscheidet |
| Treffer | ein Punkt, an dem der Strahl die Kugel schneidet |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Ein Strahl ist ein Startpunkt plus t Schritte
Ein Strahl hat einen Startpunkt O und eine Richtung D. Beide sind Vektoren, also drei Zahlen (x, y, z). Der Punkt nach t Schritten ist O plus t mal D, jede Zahl einzeln gerechnet.
Bei t gleich 0 sind Sie am Start. Je größer t, desto weiter sind Sie auf dem Strahl. Ein negatives t läge hinter dem Start und zählt nicht.
Beispiel: ein Strahl nach z
| t | Rechnung | Punkt auf dem Strahl |
|---|---|---|
| 0 | (0, 0, 0) plus 0 mal (0, 0, 1) | (0, 0, 0) |
| 3 | (0, 0, 0) plus 3 mal (0, 0, 1) | (0, 0, 3) |
| 5 | (0, 0, 0) plus 5 mal (0, 0, 1) | (0, 0, 5) |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Die Kugel führt auf eine quadratische Gleichung
Ein Punkt liegt auf der Kugel mit Mitte C und Radius r, wenn sein Abstand zu C genau r ist. Setzen Sie den Punkt O plus t mal D ein, entsteht a mal t im Quadrat plus b mal t plus k gleich null.
Dabei ist a das Skalarprodukt D mit D. Es ist b das Doppelte von D mit (O minus C). Es ist k das Skalarprodukt (O minus C) mit sich selbst, minus r im Quadrat. Das Skalarprodukt nimmt die drei Zahlen paarweise mal und addiert.
Die Diskriminante sagt, ob der Strahl trifft
Die Diskriminante ist b im Quadrat minus 4 mal a mal k. Ist sie größer als null, gibt es zwei Treffer: der Strahl geht vorn hinein und hinten hinaus. Ist sie null, berührt er die Kugel nur. Ist sie kleiner als null, verfehlt er sie.
Das Beispiel nutzt eine Kugel bei (0, 0, 5) mit Radius 2 und drei Strahlen nach z. Der nähere Treffer liegt bei t gleich (minus b minus Wurzel der Diskriminante) geteilt durch (2 mal a).
Beispiel: drei Strahlen auf eine Kugel
| Start | a, b, k | Diskriminante | Ergebnis |
|---|---|---|---|
| (0, 0, 0) | 1, -10, 21 | 16 | zwei Treffer, t gleich 3 und 7 |
| (0, 2, 0) | 1, -10, 25 | 0 | eine Berührung, t gleich 5 |
| (0, 3, 0) | 1, -10, 30 | -20 | verfehlt |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Die Diskriminante und den Treffer rechnen
# Ein Strahl vom Ursprung in Richtung z, eine Kugel bei (0, 0, 5) mit Radius 2.
a = 1
b = -10
k = 21
disc = b * b - 4 * a * k
print("Diskriminante:", disc)
if disc >= 0:
t = (-b - disc ** 0.5) / (2 * a)
print("Erster Treffer bei t =", t)
else:
print("Der Strahl verfehlt die Kugel.")
# Ändern Sie k auf 30 und starten Sie erneut.
Das Lab rechnet den Strahl mit NumPy nach
Im Befehl steht @ für das Skalarprodukt zweier Vektoren. Er rechnet a, b und k für den Strahl aus der Tabelle, danach die Diskriminante und den ersten Treffer.
Er gibt 1 -10 21 16 3.0 aus. Der zweite Befehl nimmt den Start (0, 3, 0) und gibt die Diskriminante -20 aus: Der Strahl geht an der Kugel vorbei.
Den Strahl auf die Kugel rechnen
docker exec jupyter python3 -c "import numpy as np; o = np.array([0, 0, 0]); d = np.array([0, 0, 1]); c = np.array([0, 0, 5]); r = 2; a = d @ d; b = 2 * d @ (o - c); k = (o - c) @ (o - c) - r * r; print(a, b, k, b * b - 4 * a * k, (-b - np.sqrt(b * b - 4 * a * k)) / (2 * a))"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Einen Strahl neben der Kugel rechnen
docker exec jupyter python3 -c "import numpy as np; o = np.array([0, 3, 0]); d = np.array([0, 0, 1]); c = np.array([0, 0, 5]); r = 2; a = d @ d; b = 2 * d @ (o - c); k = (o - c) @ (o - c) - r * r; print(b * b - 4 * a * k)"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Ein Strahl je Pixel ergibt die Kugel
Für jedes Pixel schickt das Programm einen Strahl los und färbt das Pixel weiß, wenn die Diskriminante nicht negativ ist. Laufen alle Strahlen parallel nach z, ist das genau dann der Fall, wenn der Abstand des Pixels zur Mitte höchstens der Radius ist.
Das Ergebnis ist eine Kreisscheibe: die Kugel, von vorn gesehen.
Die Kugel als Text zeichnen
docker exec jupyter python3 -c "print('\n'.join(''.join('#' if (x - 4) ** 2 + (y - 4) ** 2 <= 16 else '.' for x in range(9)) for y in range(9)))"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Kugel als Bild speichern
docker exec jupyter python3 -c "import numpy as np; from PIL import Image; y, x = np.mgrid[0:41, 0:41]; treffer = (x - 20) ** 2 + (y - 20) ** 2 <= 400; Image.fromarray((treffer * 255).astype('uint8')).save('kugel.png'); print(treffer.sum())"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Ein häufiger Fehler
Warnung
Viele denken, eine Diskriminante größer als null heiße schon, dass die Kugel zu sehen ist. Sie gilt aber für die ganze Gerade, auch hinter dem Start. Prüfen Sie darum, dass t nicht negativ ist, und nehmen Sie das kleinste t, das nicht negativ ist.