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.

Adriaan
sumber
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
Luis Mendo
sumber
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

cacat
sumber
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.

TheBikingViking
sumber
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

Billywob
sumber
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

plannapus
sumber
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

Kelly Lowder
sumber