Die Cornu-Spirale kann mit der Feynman-Methode für Pfadintegrale der Lichtausbreitung berechnet werden. Wir werden dieses Integral annähern die folgende Diskretisierung verwendet.
Betrachten Sie einen Spiegel wie in diesem Bild, wo S
sich die Lichtquelle befindet und P
wo wir Licht sammeln. Wir nehmen an, dass das Licht in einem geraden Strahl von S
jedem Punkt im Spiegel und dann zu jedem Punkt reflektiert wird P
. Wir unterteilen den Spiegel in N
Segmente, in diesem Beispiel 13 mit der Bezeichnung A
bis M
, so dass die Weglänge des Lichts R=SN+NP
, wo SN
ist der Abstand S
zum Spiegelsegment N
und ähnliches für P
. ( Beachten Sie, dass im Bild die Entfernung von Punkten S
und P
zum Spiegel aus visuellen Gründen stark verkürzt wurde. Der Block Q
ist eher irrelevant und dient nur dazu, die Reflexion über den Spiegel sicherzustellen und direktes Licht von S
bis zu vermeidenP
. )
Für eine gegebene Wellenzahl kann k
der Zeiger eines Lichtstrahls wie folgt berechnet werden exp(i k R)
: Wo i
ist die imaginäre Einheit? Wenn alle diese Zeiger von Kopf bis Schwanz vom linken Spiegelsegment nach rechts aufgetragen werden, entsteht die Cornu-Spirale. Für 13 - Elemente und die unten beschriebenen Werte gibt:
Bei großen N
, dh vielen Spiegelsegmenten nähert sich die Spirale der "wahren" Cornu-Spirale. Dieses Bild zeigt verschiedene Werte für N
:
Herausforderung
Für ein gegebenes N
sei x(n)
das x- Koordinatenzentrum des n- ten Spiegelsegments ( n = 0,1,2,...,N
):
x(n) := n/N-0.5
Lassen SN(n)
der Abstand der S = (-1/2, 1000)
an den n-ten Spiegelsegment:
SN(n) := sqrt((x(n)-(-1/2))^2 + 1000^2)
und ähnlich
NP(n) := sqrt((x(n)-1/2)^2 + 1000^2)
Die vom n- ten Lichtstrahl zurückgelegte Gesamtstrecke beträgt also
R(n) := SN(n) + NP(n)
Dann definieren wir den Zeiger (eine komplexe Zahl) des Lichtstrahls, der durch das n- te Spiegelsegment geht, als
P(n) = exp(i * 1e6 * R(n))
Wir betrachten nun die kumulativen Summen (als Annäherung an ein Integral)
C(n) = P(0)+P(1)+...+P(n)
Das Ziel ist nun, eine stückweise lineare Kurve durch die Punkte zu zeichnen (C(0), C(1), ..., C(n))
, an denen der Imaginärteil von C(n)
gegen seinen Realteil aufgetragen werden soll.
Die Eingabe sollte die Anzahl der Elemente sein N
, die ein Minimum von 100 und ein Maximum von mindestens 1 Million Elementen hat (mehr ist natürlich erlaubt).
Die Ausgabe sollte ein Plot oder ein Bild in einem beliebigen Format von mindestens 400 × 400 Pixel oder unter Verwendung von Vektorgrafiken sein. Die Farbe der Linie, der Achsenskala usw. ist unwichtig, solange die Form sichtbar ist.
Da dies Codegolf ist, gewinnt der kürzeste Code in Bytes.
Bitte beachten Sie, dass dies keine tatsächliche Cornu-Spirale ist, sondern eine Annäherung an diese. Das Anfangspfadintegral wurde unter Verwendung der Fresnel-Näherung angenähert, und der Spiegel hat sowohl keine unendliche Länge als auch keine unendliche Anzahl von Segmenten und wird auch nicht durch die Amplituden der einzelnen Strahlen normiert.
quelle
n
von1
, aber in Übereinstimmung mit Luis und Flawr, die zum Zeitpunkt des Wandels die einzigen Antwortenden waren, korrigierte ich es auf von0
, was den Spiegel symmetrisch macht und mit dem Rest der Herausforderung übereinstimmt. Entschuldigung.Antworten:
MATL ,
292625 BytesVielen Dank an @Adriaan für 3 Bytes!
Hier ist ein Beispiel mit Eingaben ... denn heute hat MATL seinen ersten Geburtstag! (und 2016 ist ein Schaltjahr; danke an @MadPhysicist für die Korrektur).
365
366
Oder versuchen Sie es in MATL online! (experimenteller Compiler; aktualisieren Sie die Seite, wenn es nicht funktioniert).
Erläuterung
quelle
MATLAB,
88 8481 79 BytesVielen Dank an @LuisMendo für -3 Bytes und @Adriaan für -2 Bytes!
Die Funktion
g
ist die Distanzfunktion, die wir inSN
und verwendenNP
, undh
führt den Rest der Berechnung plus Plotten aus.f
die tatsächliche Funktion, die wir wollen, und sie erzeugt den Vektor, den wir brauchen.Dies ist die Ausgabe für
N=1111
quelle
GeoGebra , 107 Bytes
Jede Zeile wird separat in die Eingabeleiste eingegeben. Die Eingabe erfolgt aus einem Eingabefeld.
Hier ist ein GIF der Ausführung:
Wie es funktioniert
Die Eingabe
1
und1E6
weist implizit die Werte aufa
undb
sind. Als Nächstes erstellt derInputBox[a]
Befehl ein Eingabefeld und ordnet es diesem zua
.Der innere
Sequence
Befehl iteriert über ganzzahlige Werte vonk
von0
bisa
einschließlich. Für jeden Wert vonk
wird der erforderliche Abstand mithilfe des Ausdrucks berechnet((k/a)^2+b)^.5+((k/a-1)^2+b)^.5)
. Dies wird dann mit multiplizierti*b
, wobeii
die imaginäre Einheit ist, unde
zum Ergebnis angehoben. Dies ergibt eine Liste komplexer Zahlen.Danach führt der äußere
Sequence
die kumulative Summierung durch, indem er über ganzzahlige Werte vonl
von1
bisa
einschließlich iteriert . Für jeden Wert vonl
werden die erstenl
Elemente der Liste mit demSum
Befehl summiert , was wiederum eine Liste komplexer Zahlen ergibt.GeoGebra behandelt die komplexe Zahl
a + bi
als Punkt(a, b)
. Daher können die komplexen Zahlen mit demPolyline
Befehl geplottet werden , der alle Punkte in der Liste der komplexen Zahlen mit geraden Liniensegmenten verbindet.quelle
R,
102 8280 BytesBearbeiten: Funktion zur Entfernungsberechnung abgeschafft
Edit2: Bemerkte eine fast identische Antwort von @Plannapus (na ja)
Edit3: Dank @Plannapus auch 2 Bytes gespeichert
Denn
N=1000
wir bekommen:quelle
x
N=scan();x=1:N/N;plot(cumsum(exp((sqrt(x^2+1e6)+sqrt((x-1)^2+1e6))*1e6i)),t="l")
R
868381 BytesVielen Dank an @JarkoDubbeldam für die zusätzlichen 3 Bytes.
Für N = 1000:
quelle
plot(cumsum(exp(1e6i*(sqrt(1e6+(0:(N<-scan())/N)^2)+sqrt(1e6+(0:N/N-1)^2)))),t="l")
einige Bytes gespartMathematica 89 Bytes (87 Zeichen)
Verwendung:
Ausbeuten
quelle