Merencanakan spiral Cornu


33

The Cornu Spiral dapat dihitung dengan menggunakan metode Feynman untuk integral lintasan propagasi cahaya. Kami akan memperkirakan integral ini menggunakan diskresi berikut.

Pertimbangkan cermin seperti pada gambar ini, di mana Ssumber cahaya dan Ptitik di mana kita mengumpulkan cahaya. Kami menganggap cahaya memantul dalam sinar lurus dari Ske setiap titik di cermin dan kemudian ke titik P. Kami membagi cermin menjadi Nsegmen, dalam contoh ini 13, berlabel Auntuk M, sehingga panjang jalan cahaya R=SN+NP, di mana SNadalah jarak dari Ssegmen cermin N, dan sama untuk P. ( Perhatikan bahwa dalam gambar jarak titik Sdan Pke cermin telah diperpendek banyak, untuk tujuan visual. Blok Qagak tidak relevan, dan ditempatkan murni untuk memastikan refleksi melalui cermin, dan menghindari cahaya langsung dari SkeP. )

Cermin pantulan

Untuk bilangan gelombang tertentu k, fasor sinar cahaya dapat dihitung sebagai exp(i k R), di mana iadalah unit imajiner. Merencanakan semua fasor ini dari ujung ke ujung dari segmen cermin kiri ke kanan mengarah ke spiral Cornu. Untuk 13 elemen dan nilai yang dijelaskan di bawah ini memberikan:

masukkan deskripsi gambar di sini

Untuk besar N, yaitu banyak segmen cermin, spiral mendekati spiral Cornu "benar". Lihat gambar ini menggunakan berbagai nilai untuk N:

masukkan deskripsi gambar di sini

Tantangan

Untuk yang diberikan Nbiarkan x(n)menjadi pusat x- koordinat segmen cermin ke- n ( n = 0,1,2,...,N):

x(n) := n/N-0.5

Membiarkan SN(n)menjadi jarak S = (-1/2, 1000)ke segmen cermin ke-n:

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

dan demikian pula

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

Jadi total jarak yang ditempuh oleh sinar ke- n adalah

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

Kemudian kita mendefinisikan fasor (bilangan kompleks) dari sinar cahaya melalui segmen cermin ke- n sebagai

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

Kami sekarang mempertimbangkan jumlah kumulatif (sebagai perkiraan untuk integral)

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

Tujuannya sekarang adalah memetakan kurva linier piecewise melalui titik-titik (C(0), C(1), ..., C(n)), di mana bagian imajiner C(n)harus diplot terhadap bagian aslinya.

The masukan harus jumlah elemen N, yang memiliki minimal 100 dan maksimal minimal 1 juta elemen (lebih tentu saja diperbolehkan).

The keluaran harus plot atau gambar dalam format apapun minimal 400 × 400 piksel, atau menggunakan grafis vektor. Warna garis, skala sumbu dll tidak penting, asalkan bentuknya terlihat.

Karena ini adalah kode-golf, kode terpendek dalam byte akan menang.

Harap dicatat bahwa ini bukan spiral Cornu yang sebenarnya, tetapi perkiraan untuk itu. Integral jalur awal telah diperkirakan dengan menggunakan perkiraan Fresnel, dan cermin keduanya tidak memiliki panjang yang tak terbatas dan tidak mengandung jumlah segmen yang tak terbatas, serta disebutkan tidak dinormalisasi oleh amplitudo dari masing-masing sinar.


5
Saya memiliki nilai-nilai nmulai dari 1, tetapi dalam perjanjian dengan Luis dan flawr, yang merupakan satu-satunya penjawab pada saat perubahan, saya memperbaikinya dari 0, yang menjadikan cermin simetris dan sesuai dengan sisa tantangan. Permintaan maaf.
Adriaan

Jawaban:


20

MATL , 29 26 25 byte

Terima kasih kepada @Adriaan selama 3 byte!

Q:qG/q1e3YytP+1e6j*ZeYsXG

Berikut ini contoh dengan input 365 366 ... karena hari ini adalah ulang tahun pertama MATL! (dan 2016 adalah tahun kabisat; terima kasih kepada @MadPhysicist untuk koreksi).

Atau coba di MATL online! (kompiler eksperimental; menyegarkan halaman jika tidak berhasil).

masukkan deskripsi gambar di sini

Penjelasan

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

8
Raih handuk terdekat dan lemparkan ke ...
Magic Octopus Mm

10
Selamat Ulang Tahun MATL!
Suever

1
Bukankah 2016 tahun kabisat?
Fisikawan Gila

14

MATLAB, 88 84 81 79 byte

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

Terima kasih @LuisMendo untuk -3 byte, dan @Adriaan untuk -2 byte!

Fungsi gadalah fungsi jarak yang kita gunakan dalam SNdan NP, dan hmelakukan sisa perhitungan ditambah plot. ffungsi sebenarnya yang kita inginkan dan menghasilkan vektor yang kita butuhkan.

Ini adalah output untuk N=1111

output untuk N = 1111


12

GeoGebra , 107 byte

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

Setiap baris dimasukkan secara terpisah ke bilah input. Input diambil dari kotak input.

Berikut adalah gif dari eksekusi:

Cornu spiral

Bagaimana itu bekerja

Memasukkan 1dan 1E6secara implisit memberikan nilai kepada adan bmasing - masing. Selanjutnya, InputBox[a]perintah membuat kotak input dan mengaitkannya dengana .

SequencePerintah dalam iterate atas nilai integer dari kdari 0ke ainklusif. Untuk setiap nilai k, jarak yang diperlukan dihitung menggunakan ekspresi ((k/a)^2+b)^.5+((k/a-1)^2+b)^.5). Ini kemudian dikalikan dengan i*b, di mana iunit imajiner, dan edinaikkan ke hasilnya. Ini menghasilkan daftar bilangan kompleks.

Setelah ini, bagian luar Sequencemelakukan penjumlahan kumlatif dengan beralih lebih dari nilai integer dari ldari 1hingga ainklusif. Untuk setiap nilai l, lelemen pertama dari daftar dijumlahkan menggunakan Sumperintah, sekali lagi menghasilkan daftar bilangan kompleks.

GeoGebra memperlakukan bilangan kompleks a + bisebagai intinya (a, b). Oleh karena itu, bilangan kompleks dapat diplot menggunakan Polylineperintah, yang menggabungkan semua titik dalam daftar bilangan kompleks dengan segmen garis lurus.


5

R, 102 82 80 byte

Sunting: menghapus fungsi untuk menghitung jarak

Sunting2: Melihat jawaban yang hampir identik oleh @Plannapus (oh well)

Sunting3: Disimpan 2 byte berkat @Plannapus juga

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

Untuk N=1000kita dapatkan:

masukkan deskripsi gambar di sini


Sebenarnya Anda bisa mencapai serendah 80 byte karena Anda tidak perlu xlagi tanda kurung :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 byte

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

Terima kasih @JarkoDubbeldam untuk 3 byte tambahan.

Untuk N = 1000:

N = 1e3


Wow, 2 R menjawab dalam 2 menit. Aneh, saya mencoba yang sama dan saya tidak bisa membuatnya bekerja, tetapi ini bekerja dengan baik untuk saya: S Pokoknya, pekerjaan yang baik!
JAD

Juga, menggunakan pemindaian akan plot(cumsum(exp(1e6i*(sqrt(1e6+(0:(N<-scan())/N)^2)+sqrt(1e6+(0:N/N-1)^2)))),t="l")menghemat beberapa byte
JAD

1

Mathematica 89 Bytes (87 karakter)

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

Pemakaian:

%@100

hasil panen

masukkan deskripsi gambar di sini

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.