Trazando la espiral de Cornu

33

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 Sestá la fuente de luz y Pel punto donde recogemos la luz. Suponemos que la luz rebota en un rayo recto desde Scada punto del espejo y luego hacia el punto P. Dividimos el espejo en Nsegmentos, en este ejemplo 13, etiquetados Acomo M, de modo que la longitud de la trayectoria de la luz es R=SN+NP, donde SNestá la distancia desde el Ssegmento del espejo N, y similar para P. ( Nótese que en la imagen de la distancia de los puntos Sy Pel espejo se ha reducido mucho, a efectos visuales. El bloque Qes bastante irrelevante, y se coloca únicamente para garantizar la reflexión a través del espejo, y evitar la luz directa del SaP. )

Espejo reflectante

Para un número de onda dado, kel fasor de un rayo de luz puede calcularse como exp(i k R), donde iestá 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:

ingrese la descripción de la imagen aquí

Para Nsegmentos grandes , es decir, muchos espejos, la espiral se aproxima a la espiral "verdadera" de Cornu. Vea esta imagen usando varios valores para N:

ingrese la descripción de la imagen aquí

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.

Adriaan
fuente
55
Tenía los valores de nir desde 1, pero de acuerdo con Luis y flawr, que eran los únicos que respondieron en el momento del cambio, lo corregí para que sea 0, lo que hace que el espejo sea simétrico y está de acuerdo con el resto del desafío. Disculpas
Adriaan

Respuestas:

20

MATL , 29 26 25 bytes

¡Gracias a @Adriaan por 3 bytes de descuento!

Q:qG/q1e3YytP+1e6j*ZeYsXG

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).

ingrese la descripción de la imagen aquí

Explicación

Q:q    % Input N implicitly. Push range [0 1 ... N] (row vector)
G/     % Divide by N, element-wise
q      % Subtract 1. This gives NP projected onto the x axis for each mirror element
1e3    % Push 1000. This is NP projected onto the y axis
Yy     % Hypotenuse function: computes distance NP
tP     % Duplicate, reverse. By symmetry, this is the distance SN
+      % Add. This is distance SNP for each mirror element (row vector)
1e6j   % Push 1e6*1i
*      % Multiply
Ze     % Exponential
Ys     % Cumulative sum
XG     % Plot in the complex plane
Luis Mendo
fuente
8
Agarra la toalla más cercana y la tira ...
Urna de pulpo mágico
10
Feliz cumpleaños MATL!
Suever
1
¿No es 2016 un año bisiesto?
Físico loco
14

MATLAB, 88 84 81 79 bytes

g=@(x)hypot(1e3,x);h=@(x)plot(cumsum(exp(1e6i*(g(x)+g(1-x)))));f=@(N)h(0:1/N:1)

¡Gracias @LuisMendo por -3 bytes y @Adriaan por -2 bytes!

La función ges la función de distancia que usamos en SNy NP, y hrealiza el resto del cálculo más el trazado. fla función real que queremos y produce el vector que necesitamos.

Esta es la salida para N=1111

salida para N = 1111

falla
fuente
12

GeoGebra , 107 bytes

1
1E6
InputBox[a]
Polyline[Sequence[Sum[Sequence[e^(i*b(((k/a)^2+b)^.5+((k/a-1)^2+b)^.5)),k,0,a],l],l,1,a]]

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:

Espiral de Cornu

Cómo funciona

Al ingresar 1e 1E6implícitamente se asignan los valores a ay brespectivamente. A continuación, el InputBox[a]comando crea un cuadro de entrada y lo asocia con a.

El Sequencecomando interno itera sobre valores enteros de kfrom 0a ainclusive. Para cada valor de k, la distancia requerida se calcula utilizando la expresión ((k/a)^2+b)^.5+((k/a-1)^2+b)^.5). Esto se multiplica por i*b, donde iestá la unidad imaginaria, y ese eleva al resultado. Esto produce una lista de números complejos.

Después de esto, el externo Sequencerealiza la suma acumulativa iterando sobre valores enteros de lfrom 1a ainclusive. Para cada valor de l, los primeros lelementos de la lista se suman utilizando el Sumcomando, obteniendo nuevamente una lista de números complejos.

GeoGebra trata el número complejo a + bicomo el punto (a, b). Por lo tanto, los números complejos se pueden trazar utilizando el Polylinecomando, que une todos los puntos de la lista de números complejos con segmentos de línea recta.

TheBikingViking
fuente
5

R, 102 82 80 bytes

Editar: 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

N=scan();x=1:N/N;plot(cumsum(exp((sqrt(x^2+1e6)+sqrt((x-1)^2+1e6))*1e6i)),t="l")

Porque N=1000obtenemos:

ingrese la descripción de la imagen aquí

Billywob
fuente
En realidad, puede bajar hasta 80 bytes ya que ya no necesita los paréntesis x:N=scan();x=1:N/N;plot(cumsum(exp((sqrt(x^2+1e6)+sqrt((x-1)^2+1e6))*1e6i)),t="l")
plannapus
4

R, 86 83 81 bytes

plot(cumsum(exp(1e6i*((1e6+(0:(N<-scan())/N)^2)^.5+(1e6+(0:N/N-1)^2)^.5))),t="l")

Gracias @JarkoDubbeldam por los 3 bytes adicionales.

Para N = 1000:

N = 1e3

plannapus
fuente
Wow, 2 R responde en 2 minutos. Es extraño, intenté lo mismo y no pude hacerlo funcionar, pero esto funciona bien para mí: S De todos modos, ¡buen trabajo!
JAD
Además, el uso de la exploración como tal plot(cumsum(exp(1e6i*(sqrt(1e6+(0:(N<-scan())/N)^2)+sqrt(1e6+(0:N/N-1)^2)))),t="l")ahorra algunos bytes
JAD
1

Mathematica 89 Bytes (87 caracteres)

Graphics[Line[ReIm/@Tr/@Table[E^(I*10^6*Tr[√(10^6+(-{0,1}+j/#)^2)]),{i,0,#},{j,0,i}]]]&

Uso:

%@100

rendimientos

ingrese la descripción de la imagen aquí

Kelly Lowder
fuente