A espiral de Cornu pode ser calculada usando o método de Feynman para integrais de caminho da propagação da luz. Vamos aproximar essa integral usando a seguinte discretização.
Considere um espelho como nesta imagem, onde S
está a fonte de luz e P
o ponto em que coletamos a luz. Assumimos que a luz salta em um raio reto de S
cada ponto no espelho e depois para apontar P
. Dividimos o espelho em N
segmentos, neste exemplo 13, rotulados A
como M
, para que o comprimento do caminho da luz seja R=SN+NP
, onde SN
está a distância do S
segmento do espelho N
e semelhante para P
. ( Note que na imagem a distância de pontos S
e P
para o espelho foi encurtado muito, para efeitos visuais. O bloco Q
é bastante irrelevante, e colocou puramente para garantir reflexão através do espelho, e evitar a luz direta S
paraP
. )
Para um dado número de onda, k
o fasor de um raio de luz pode ser calculado como exp(i k R)
, onde i
está a unidade imaginária. A plotagem de todos esses fasores da cabeça para a cauda, do segmento de espelho esquerdo para a direita, leva à espiral de Cornu. Para 13 elementos e os valores descritos abaixo, isso fornece:
Para grandes N
segmentos de espelhos, isto é, a espiral se aproxima da "verdadeira" espiral de Cornu. Veja esta imagem usando vários valores para N
:
Desafio
Para um dado N
deixe x(n)
ser os x centro da coordenada x n segmento de espelho -ésimo ( n = 0,1,2,...,N
):
x(n) := n/N-0.5
Seja SN(n)
a distância do S = (-1/2, 1000)
n-ésimo segmento de espelho:
SN(n) := sqrt((x(n)-(-1/2))^2 + 1000^2)
e da mesma forma
NP(n) := sqrt((x(n)-1/2)^2 + 1000^2)
Portanto, a distância total percorrida pelo n- ésimo raio de luz é
R(n) := SN(n) + NP(n)
Em seguida, definimos o fasor (um número complexo) do raio de luz que passa pelo n- ésimo segmento de espelho como
P(n) = exp(i * 1e6 * R(n))
Agora, consideramos as somas cumulativas (como uma aproximação a uma integral)
C(n) = P(0)+P(1)+...+P(n)
O objetivo agora é traçar uma curva linear por partes através dos pontos (C(0), C(1), ..., C(n))
, onde a parte imaginária C(n)
deve ser plotada em relação à sua parte real.
A entrada deve ser o número de elementos N
, que tem um mínimo de 100 e um máximo de pelo menos 1 milhão de elementos (é claro que é permitido mais).
A saída deve ser uma plotagem ou imagem em qualquer formato de pelo menos 400 × 400 pixels ou usando gráficos vetoriais. A cor da linha, a escala dos eixos etc. não são importantes, desde que a forma seja visível.
Como esse é o código-golfe, o código mais curto em bytes vence.
Observe que esta não é uma espiral real de Cornu, mas uma aproximação a ela. A integral do caminho inicial foi aproximada usando a aproximação de Fresnel, e o espelho não é de comprimento infinito nem contém um número infinito de segmentos, assim como mencionado, não é normalizado pelas amplitudes dos raios individuais.
fonte
n
variar de1
, mas, de acordo com Luis e flawr, que eram os únicos responsáveis pela resposta no momento da mudança, eu o corrigi0
, o que torna o espelho simétrico e está de acordo com o resto do desafio. Desculpas.Respostas:
MATL ,
292625 bytesGraças a @Adriaan por 3 bytes de desconto!
Aqui está um exemplo com entrada ... porque hoje é o primeiro aniversário do MATL! (e 2016 é um ano bissexto; obrigado a @MadPhysicist pela correção).
365
366
Ou experimente no MATL online! (compilador experimental; atualize a página se não funcionar).
Explicação
fonte
MATLAB,
88 8481 79 bytesObrigado @LuisMendo por -3 bytes e @Adriaan por -2 bytes!
A função
g
é a função de distância em que usamosSN
eNP
, eh
faz o restante do cálculo mais a plotagem.f
a função real que queremos e produz o vetor que precisamos.Essa é a saída para
N=1111
fonte
GeoGebra , 107 bytes
Cada linha é inserida separadamente na barra de entrada. A entrada é obtida de uma caixa de entrada.
Aqui está um gif da execução:
Como funciona
Inserir
1
e1E6
atribuir implicitamente os valores aa
eb
respectivamente. Em seguida, oInputBox[a]
comando cria uma caixa de entrada e a associaa
.O
Sequence
comando interno itera sobre valores inteiros dek
de0
atéa
inclusivo. Para cada valor dek
, a distância necessária é calculada utilizando a expressão((k/a)^2+b)^.5+((k/a-1)^2+b)^.5)
. Isso é multiplicado pori*b
ondei
está a unidade imaginária ee
elevado ao resultado. Isso produz uma lista de números complexos.Depois disso, o externo
Sequence
executa a soma cumulativa iterando sobre valores inteiros del
de1
atéa
inclusivo. Para cada valor del
, os primeirosl
elementos da lista são somados usando oSum
comando, produzindo novamente uma lista de números complexos.O GeoGebra trata o número complexo
a + bi
como o ponto(a, b)
. Portanto, os números complexos podem ser plotados usando oPolyline
comando, que une todos os pontos da lista de números complexos com segmentos de linha reta.fonte
R,
102 8280 bytesEditar: descartou a função para calcular a distância
Edit2: Notou uma resposta quase idêntica por @Plannapus (oh bem)
Edit3: salvou 2 bytes graças ao @Plannapus também
Pois
N=1000
temos:fonte
x
:N=scan();x=1:N/N;plot(cumsum(exp((sqrt(x^2+1e6)+sqrt((x-1)^2+1e6))*1e6i)),t="l")
R,
868381 bytesObrigado a @JarkoDubbeldam pelos 3 bytes extras.
Para N = 1000:
fonte
plot(cumsum(exp(1e6i*(sqrt(1e6+(0:(N<-scan())/N)^2)+sqrt(1e6+(0:N/N-1)^2)))),t="l")
economiza alguns bytesMathematica 89 bytes (87 caracteres)
Uso:
rendimentos
fonte