Traçage de la spirale de Cornu

33

La spirale de Cornu peut être calculée à l'aide de la méthode de Feynman pour les intégrales de chemin de propagation de la lumière. Nous allons approximer cette intégrale en utilisant la discrétisation suivante.

Considérons un miroir comme dans cette image, où se Strouve la source de lumière et Ple point de collecte de la lumière. Nous supposons que la lumière rebondit dans un rayon droit de Schaque point du miroir à un point P. Nous divisons le miroir en Nsegments, dans cet exemple 13, étiquetés Aen M, de sorte que la longueur du trajet de la lumière soit égale à R=SN+NP, où SNest la distance entre le Ssegment du miroir Net similaire pour P. ( On notera que dans l'image de la distance de points Set Ple miroir a été raccourci d' un lot, à des fins visuelles. Le bloc Qest relativement sans importance, et placé uniquement pour assurer la réflexion via le miroir, et d' éviter la lumière directe provenant SdeP. )

Miroir réfléchissant

Pour un nombre d'onde donné, kle phaseur d'un rayon de lumière peut être calculé comme suit exp(i k R), où iest l'unité imaginaire. Le tracé de tous ces phaseurs de bout en bout à partir du segment de miroir gauche mène à la spirale de Cornu. Pour 13 éléments et les valeurs décrites ci-dessous, cela donne:

entrez la description de l'image ici

Pour les grands Nsegments de miroir, la spirale se rapproche de la "vraie" spirale de Cornu. Voir cette image en utilisant différentes valeurs pour N:

entrez la description de l'image ici

Défi

Pour une donnée Nlaisser x(n)être les x du centre -Coordonner du n segment de miroir -ième ( n = 0,1,2,...,N):

x(n) := n/N-0.5

Soit SN(n)la distance du S = (-1/2, 1000)n-ième segment de miroir:

SN(n) := sqrt((x(n)-(-1/2))^2 + 1000^2) 

et pareillement

NP(n) := sqrt((x(n)-1/2)^2 + 1000^2) 

Ainsi , la distance totale parcourue par le n ième rayon lumineux est

R(n) := SN(n) + NP(n) 

Ensuite, nous définissons le phaseur (un nombre complexe) du rayon lumineux passant par le n- ème segment du miroir comme suit:

P(n) = exp(i * 1e6 * R(n)) 

Nous considérons maintenant les sommes cumulées (comme une approximation d'une intégrale)

C(n) = P(0)+P(1)+...+P(n)

Le but est maintenant de tracer une courbe linéaire par morceaux à travers les points (C(0), C(1), ..., C(n)), où la partie imaginaire de C(n)devrait être tracée par rapport à sa partie réelle.

L' entrée doit être le nombre d'éléments N, avec un minimum de 100 et un maximum d'au moins 1 million d'éléments (plus est autorisé).

La sortie doit être un tracé ou une image de tout format d'au moins 400 × 400 pixels, ou utiliser des graphiques vectoriels. La couleur de la ligne, l'échelle des axes, etc. sont sans importance, tant que la forme est visible.

Puisqu'il s'agit de code-golf, le code le plus court en octets gagne.

Veuillez noter qu'il ne s'agit pas d'une spirale de Cornu, mais d'une approximation. L'intégrale initiale du trajet a été approximée à l'aide de l'approximation de Fresnel, et le miroir n'a pas de longueur infinie ni de nombre infini de segments, de même qu'il n'est pas normalisé par les amplitudes des rayons individuels.

Adriaan
la source
5
J'avais les valeurs de ndépart 1, mais en accord avec Luis et flawr, qui étaient les seuls à répondre au moment du changement, je l'ai corrigé 0, ce qui rend le miroir symétrique et correspond au reste du défi. Excuses.
Adriaan

Réponses:

20

MATL , 29 26 25 octets

Merci à @Adriaan pour 3 octets de moins!

Q:qG/q1e3YytP+1e6j*ZeYsXG

Voici un exemple avec entrée … parce que c'est aujourd'hui le premier anniversaire de MATL! (et 2016 est une année bissextile; merci à @MadPhysicist pour la correction).365 366

Ou essayez-le dans MATL en ligne! (compilateur expérimental; actualisez la page si cela ne fonctionne pas).

entrez la description de l'image ici

Explication

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
la source
8
Attrape la serviette la plus proche et la jette dans ...
Magic Octopus Urn
10
Joyeux anniversaire MATL!
Suever
1
2016 n'est-elle pas une année bissextile?
Mad Physicist
14

MATLAB, 88 84 81 79 octets

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

Merci @LuisMendo pour -3 octets et @Adriaan pour -2 octets!

La fonction gest la fonction de distance que nous utilisons dans SNet NP, et heffectue le reste du calcul plus le traçage. fla fonction réelle que nous voulons et produit le vecteur dont nous avons besoin.

Ceci est la sortie pour N=1111

sortie pour N = 1111

flawr
la source
12

GeoGebra , 107 octets

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]]

Chaque ligne est entrée séparément dans la barre de saisie. L'entrée est prise à partir d'une zone de saisie.

Voici un gif de l'exécution:

Spirale de Cornu

Comment ça marche

La saisie 1et 1E6attribue implicitement les valeurs à aet brespectivement. Ensuite, la InputBox[a]commande crée une zone de saisie et l’associe àa .

La Sequencecommande interne effectue une itération sur les valeurs entières comprises entre kde 0et celles aincluses. Pour chaque valeur de k, la distance requise est calculée à l'aide de l'expression ((k/a)^2+b)^.5+((k/a-1)^2+b)^.5). Ceci est ensuite multiplié par i*b, où iest l'unité imaginaire, ete est élevé au résultat. Cela donne une liste de nombres complexes.

Après cela, l’extérieur Sequenceeffectue la sommation cumulative en itérant des valeurs entières lallant de de 1à ainclus. Pour chaque valeur de l, les premiers léléments de la liste sont additionnés à l'aide de la Sumcommande, produisant à nouveau une liste de nombres complexes.

GeoGebra traite le nombre complexe a + bicomme le point (a, b). Par conséquent, les nombres complexes peuvent être tracés à l'aide de la Polylinecommande, qui associe tous les points de la liste des nombres complexes à des segments de droite.

TheBikingViking
la source
5

R, 102 82 80 octets

Edit: mis au rebut la fonction de calcul de la distance

Edit2: Remarqué une réponse presque identique par @Plannapus (eh bien)

Edit3: 2 octets enregistrés grâce à @Plannapus également

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

Pour N=1000nous obtenons:

entrez la description de l'image ici

Billywob
la source
En fait, vous pouvez aller aussi bas que 80 octets puisque vous n’avez plus besoin des parenthèses 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 octets

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

Merci @JarkoDubbeldam pour les 3 octets supplémentaires.

Pour N = 1000:

N = 1e3

planificateur
la source
Wow, 2 R répond dans les 2 minutes. C'est étrange, j'ai essayé la même chose et je ne pouvais pas le faire fonctionner, mais cela fonctionne bien pour moi: S En tout cas, bon travail!
JAD
De plus, l’utilisation de scan en tant que tel plot(cumsum(exp(1e6i*(sqrt(1e6+(0:(N<-scan())/N)^2)+sqrt(1e6+(0:N/N-1)^2)))),t="l")économise quelques octets
JAD
1

Mathematica 89 octets (87 caractères)

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

Usage:

%@100

les rendements

entrez la description de l'image ici

Kelly Lowder
la source