La espiral de Cornu se puede calcular utilizando el método de Feynman para integrales de trayectoria de propagación de luz. Aproximaremos esta integral utilizando la siguiente discretización.
Considere un espejo como en esta imagen, donde S
está la fuente de luz y P
el punto donde recogemos la luz. Suponemos que la luz rebota en un rayo recto desde S
cada punto del espejo y luego hacia el punto P
. Dividimos el espejo en N
segmentos, en este ejemplo 13, etiquetados A
como M
, de modo que la longitud de la trayectoria de la luz es R=SN+NP
, donde SN
está la distancia desde el S
segmento del espejo N
, y similar para P
. ( Nótese que en la imagen de la distancia de los puntos S
y P
el espejo se ha reducido mucho, a efectos visuales. El bloque Q
es bastante irrelevante, y se coloca únicamente para garantizar la reflexión a través del espejo, y evitar la luz directa del S
aP
. )
Para un número de onda dado, k
el fasor de un rayo de luz puede calcularse como exp(i k R)
, donde i
está la unidad imaginaria. Al trazar todos estos fasores cabeza a cola desde el segmento del espejo izquierdo hacia la derecha, se llega a la espiral de Cornu. Para 13 elementos y los valores descritos a continuación, esto da:
Para N
segmentos grandes , es decir, muchos espejos, la espiral se aproxima a la espiral "verdadera" de Cornu. Vea esta imagen usando varios valores para N
:
Reto
Para un dado N
, x(n)
sea el centro de coordenadas x del segmento de espejo n -ésimo ( n = 0,1,2,...,N
):
x(n) := n/N-0.5
Sea SN(n)
la distancia S = (-1/2, 1000)
al segmento n-ésimo espejo:
SN(n) := sqrt((x(n)-(-1/2))^2 + 1000^2)
y de manera similar
NP(n) := sqrt((x(n)-1/2)^2 + 1000^2)
Por lo que la distancia total recorrida por el n -ésimo rayo de luz es
R(n) := SN(n) + NP(n)
Luego definimos el fasor (un número complejo) del rayo de luz que va a través de la n segmento de espejo -ésimo como
P(n) = exp(i * 1e6 * R(n))
Ahora consideramos las sumas acumulativas (como una aproximación a una integral)
C(n) = P(0)+P(1)+...+P(n)
El objetivo ahora es trazar una curva lineal por partes a través de los puntos (C(0), C(1), ..., C(n))
, donde la parte imaginaria de C(n)
debe trazarse contra su parte real.
La entrada debe ser el número de elementos N
, que tiene un mínimo de 100 y un máximo de al menos 1 millón de elementos (por supuesto, se permiten más).
El resultado debe ser un gráfico o una imagen en cualquier formato de al menos 400 × 400 píxeles, o utilizando gráficos vectoriales. El color de la línea, la escala de los ejes, etc. no son importantes, siempre que la forma sea visible.
Como se trata de código de golf, gana el código más corto en bytes.
Tenga en cuenta que esto no es una espiral real de Cornu, sino una aproximación. La integral de trayectoria inicial se ha aproximado utilizando la aproximación de Fresnel, y el espejo no tiene una longitud infinita y no contiene un número infinito de segmentos, además de que no está normalizado por las amplitudes de los rayos individuales.
fuente
n
ir desde1
, pero de acuerdo con Luis y flawr, que eran los únicos que respondieron en el momento del cambio, lo corregí para que sea0
, lo que hace que el espejo sea simétrico y está de acuerdo con el resto del desafío. DisculpasRespuestas:
MATL ,
292625 bytes¡Gracias a @Adriaan por 3 bytes de descuento!
Aquí hay un ejemplo con entrada ... ¡porque hoy es el primer cumpleaños de MATL! (y 2016 es un año bisiesto; gracias a @MadPhysicist por la corrección).
365
366
¡O pruébalo en MATL en línea! (compilador experimental; actualice la página si no funciona).
Explicación
fuente
MATLAB,
88 8481 79 bytes¡Gracias @LuisMendo por -3 bytes y @Adriaan por -2 bytes!
La función
g
es la función de distancia que usamos enSN
yNP
, yh
realiza el resto del cálculo más el trazado.f
la función real que queremos y produce el vector que necesitamos.Esta es la salida para
N=1111
fuente
GeoGebra , 107 bytes
Cada línea se ingresa por separado en la barra de entrada. La entrada se toma de un cuadro de entrada.
Aquí hay un gif de la ejecución:
Cómo funciona
Al ingresar
1
e1E6
implícitamente se asignan los valores aa
yb
respectivamente. A continuación, elInputBox[a]
comando crea un cuadro de entrada y lo asocia cona
.El
Sequence
comando interno itera sobre valores enteros dek
from0
aa
inclusive. Para cada valor dek
, la distancia requerida se calcula utilizando la expresión((k/a)^2+b)^.5+((k/a-1)^2+b)^.5)
. Esto se multiplica pori*b
, dondei
está la unidad imaginaria, ye
se eleva al resultado. Esto produce una lista de números complejos.Después de esto, el externo
Sequence
realiza la suma acumulativa iterando sobre valores enteros del
from1
aa
inclusive. Para cada valor del
, los primerosl
elementos de la lista se suman utilizando elSum
comando, obteniendo nuevamente una lista de números complejos.GeoGebra trata el número complejo
a + bi
como el punto(a, b)
. Por lo tanto, los números complejos se pueden trazar utilizando elPolyline
comando, que une todos los puntos de la lista de números complejos con segmentos de línea recta.fuente
R,
102 8280 bytesEditar: desechó la función para calcular la distancia
Edit2: Noté una respuesta casi idéntica por @Plannapus (oh, bueno)
Edit3: Guardado 2 bytes gracias a @Plannapus también
Porque
N=1000
obtenemos:fuente
x
:N=scan();x=1:N/N;plot(cumsum(exp((sqrt(x^2+1e6)+sqrt((x-1)^2+1e6))*1e6i)),t="l")
R,
868381 bytesGracias @JarkoDubbeldam por los 3 bytes adicionales.
Para N = 1000:
fuente
plot(cumsum(exp(1e6i*(sqrt(1e6+(0:(N<-scan())/N)^2)+sqrt(1e6+(0:N/N-1)^2)))),t="l")
ahorra algunos bytesMathematica 89 Bytes (87 caracteres)
Uso:
rendimientos
fuente