Vẽ hình xoắn ốc Cornu


33

Các Cornu Spiral thể được tính toán sử dụng phương pháp của Feynman cho tích phân đường của công tác tuyên truyền ánh sáng. Chúng tôi sẽ tính gần đúng tích phân này bằng cách sử dụng sự phân biệt sau đây.

Hãy xem xét một tấm gương như trong hình ảnh này, nơi Slà nguồn sáng và Pđiểm mà chúng ta thu thập ánh sáng. Chúng ta giả sử ánh sáng dội vào một tia thẳng từ Sđến từng điểm trong gương rồi đến điểm P. Chúng tôi chia gương vào Nphân đoạn, trong ví dụ này 13, dán nhãn Ađể M, do đó độ dài đường đi của ánh sáng là R=SN+NP, nơi SNlà khoảng cách từ Sphân khúc gương N, và tương tự cho P. ( Lưu ý rằng trong hình ảnh khoảng cách của điểm SPđể gương đã được rút ngắn rất nhiều, cho các mục đích thị giác. Khối Qlà khá thích hợp, và được đặt hoàn toàn để đảm bảo phản ánh qua gương, và tránh ánh sáng trực tiếp từ SđếnP. )

Gương phản chiếu

Đối với một số sóng cho kcác phasor của một tia ánh sáng có thể được tính như exp(i k R), nơi ilà đơn vị ảo. Vẽ tất cả các pha này từ đầu đến đuôi từ đoạn gương bên trái sang phải dẫn đến xoắn ốc Cornu. Đối với 13 phần tử và các giá trị được mô tả bên dưới, điều này mang lại:

nhập mô tả hình ảnh ở đây

Đối với lớn N, tức là rất nhiều phân khúc gương, xoắn ốc tiếp cận với xoắn ốc Cornu "thật". Xem hình ảnh này bằng các giá trị khác nhau cho N:

nhập mô tả hình ảnh ở đây

Thử thách

Đối với một cho trước, Nhãy x(n)là trung tâm x- phối hợp của phân đoạn gương thứ n ( n = 0,1,2,...,N):

x(n) := n/N-0.5

Đặt SN(n)khoảng cách S = (-1/2, 1000)đến đoạn gương thứ n:

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

và tương tự

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

Vậy tổng quãng đường mà tia sáng thứ n đi được là

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

Sau đó, chúng tôi xác định phasor (một số phức) của tia sáng đi qua đoạn gương thứ n

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

Bây giờ chúng tôi xem xét các khoản tiền tích lũy (như một xấp xỉ với một tích phân)

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

Mục tiêu hiện đang vẽ một đường cong tuyến tính từng phần thông qua các điểm (C(0), C(1), ..., C(n)), trong đó phần ảo của C(n)nên được vẽ trên phần thực của nó.

Đầu vào phải là số lượng phần tử N, có tối thiểu 100 và tối đa ít nhất 1 triệu phần tử (tất nhiên là nhiều hơn được phép).

Đầu ra phải là một âm mưu hoặc hình ảnh ở bất kỳ định dạng nào ít nhất 400 × 400 pixel hoặc sử dụng đồ họa vector. Màu sắc của đường, tỷ lệ trục vv là không quan trọng, miễn là hình dạng được nhìn thấy.

Vì đây là mã golf, mã ngắn nhất tính bằng byte sẽ thắng.

Xin lưu ý rằng đây không phải là một vòng xoắn Cornu thực tế, mà là một xấp xỉ với nó. Tích phân đường dẫn ban đầu đã được xấp xỉ bằng cách sử dụng xấp xỉ Fresnel và gương không có độ dài vô hạn và không chứa vô số phân đoạn, cũng như được đề cập, nó không được chuẩn hóa bởi biên độ của các tia riêng lẻ.


5
Tôi có các giá trị nkhác nhau 1, nhưng theo thỏa thuận với Luis và flawr, những người trả lời duy nhất tại thời điểm thay đổi, tôi đã sửa nó thành từ 0đó, làm cho gương đối xứng và phù hợp với phần còn lại của thử thách. Lời xin lỗi.
Adriaan

Câu trả lời:


20

MATL , 29 26 25 byte

Cảm ơn @Adriaan đã tắt 3 byte!

Q:qG/q1e3YytP+1e6j*ZeYsXG

Đây là một ví dụ với đầu vào ... bởi vì hôm nay là sinh nhật đầu tiên của MATL! (và năm 2016 là một năm nhuận; cảm ơn @MadPhysicist đã sửa lỗi).365 366

Hoặc thử nó trong MATL trực tuyến! (trình biên dịch thử nghiệm; làm mới trang nếu nó không hoạt động).

nhập mô tả hình ảnh ở đây

Giải trình

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
Lấy khăn gần nhất và ném nó vào ...
Magic Octopus Urn

10
Chúc mừng sinh nhật MATL!
Suever

1
Không phải năm 2016 là một năm nhuận?
Nhà vật lý điên

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)

Cảm ơn @LuisMendo cho -3 byte và @Adriaan cho -2 byte!

Hàm gnày là hàm khoảng cách chúng ta sử dụng SNNP, và hphần còn lại của phép tính cộng với vẽ đồ thị. fhàm thực tế chúng ta muốn và nó tạo ra vectơ chúng ta cần.

Đây là đầu ra cho N=1111

đầu ra cho 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]]

Mỗi dòng được nhập riêng vào thanh đầu vào. Đầu vào được lấy từ một hộp đầu vào.

Đây là một gif của việc thực hiện:

Cornu xoắn ốc

Làm thế nào nó hoạt động

Nhập 11E6ngầm định gán các giá trị abtương ứng. Tiếp theo, InputBox[a]lệnh tạo một hộp đầu vào và liên kết nó với a.

Lệnh bên trong Sequencelặp lại các giá trị nguyên ktừ 0đến abao gồm. Đối với mỗi giá trị của k, khoảng cách cần thiết được tính bằng biểu thức ((k/a)^2+b)^.5+((k/a-1)^2+b)^.5). Điều này sau đó được nhân với i*b, iđơn vị tưởng tượng ở đâu và eđược nâng lên thành kết quả. Điều này mang lại một danh sách các số phức.

Sau này, bên ngoài Sequencethực hiện phép cộng gộp bằng cách lặp qua các giá trị nguyên ltừ 1đến abao gồm. Đối với mỗi giá trị của l, các lphần tử đầu tiên của danh sách được tính tổng bằng cách sử dụng Sumlệnh, một lần nữa thu được một danh sách các số phức.

GeoGebra coi số phức a + bilà điểm (a, b). Do đó, các số phức có thể được vẽ bằng cách sử dụng Polylinelệnh, tham gia tất cả các điểm trong danh sách số phức với các đoạn thẳng.


5

R, 102 82 80 byte

Chỉnh sửa: loại bỏ chức năng tính toán khoảng cách

Edit2: Nhận thấy một câu trả lời gần như giống hệt bởi @Plannapus (oh well)

Edit3: Đã lưu 2 byte nhờ @Plannapus

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

Đối với N=1000chúng tôi nhận được:

nhập mô tả hình ảnh ở đây


Trên thực tế, bạn có thể xuống thấp tới 80 byte vì bạn không cần dấu ngoặc đơn xnữa: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")

Cảm ơn @JarkoDubbeldam vì đã có thêm 3 byte.

Với N = 1000:

N = 1e3


Wow, 2 R câu trả lời trong vòng 2 phút. Thật kỳ lạ, tôi đã cố gắng như vậy và tôi không thể làm cho nó hoạt động, nhưng điều này hoạt động tốt với tôi: S Dù sao, công việc tốt!
JAD

Ngoài ra, sử dụng quét như vậy sẽ plot(cumsum(exp(1e6i*(sqrt(1e6+(0:(N<-scan())/N)^2)+sqrt(1e6+(0:N/N-1)^2)))),t="l")tiết kiệm một vài byte
JAD

1

Mathicala 89 Byte (87 ký tự)

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

Sử dụng:

%@100

sản lượng

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.