绘制Cornu螺旋


33

可以使用Feynman方法计算光传播的路径积分的Cornu螺旋。我们将使用以下离散化近似该积分。

考虑这张图中的镜子,S光源P在哪里,我们在哪里收集光。我们假设光线以直线光线从S反射镜中的每个点反射然后指向P。我们将镜子分成若干N段,在本例中为13,标记AM,以使光的路径长度为R=SN+NP,其中SNS到镜段的距离N,与相似P。(请注意,在图像中的点的距离SP到反射镜已缩短了很多,对于视觉的目的。该块Q是相当无关的,并且纯粹放置经由反射镜,以确保反射,并避免直接光照SP

反光镜

对于给定的波数k,可以将光线的相量计算为exp(i k R),其中i是虚数单位。将所有这些相量从左后视镜面到右图从头到尾绘制会导致Cornu螺旋。对于13个元素及其下面描述的值,得出:

在此处输入图片说明

对于较大N的镜面段(即很多镜面段),螺旋线接近“真正的” Cornu螺旋线。使用各种值查看此图像N

在此处输入图片说明

挑战

对于给定的Nx(n)X的的-协调中心Ñ个反射镜区段(n = 0,1,2,...,N):

x(n) := n/N-0.5

SN(n)是的距离S = (-1/2, 1000)到第n个反射镜部分:

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

同样

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

因此,第n条光线传播的总距离为

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

然后我们定义通过第n个镜面段的光线的相量(复数)为

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

现在,我们考虑累积总和(作为积分的近似值)

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

现在的目标是通过各点绘制分段线性曲线(C(0), C(1), ..., C(n)),其中的虚部C(n)应相对于其实部绘制。

输入应该是元件的数量N,其具有至少100和最大至少为1种百万个元素的(更是当然允许)。

输出应在至少400×400像素,或者使用矢量图形的任何格式的曲线图或图像。只要形状可见,线条的颜色,轴的比例等都不重要。

由于这是代码高尔夫球,因此以字节为单位的最短代码为准。

请注意,这不是实际的Cornu螺旋,而是近似值。初始路径积分已使用菲涅耳近似法进行了近似,并且反射镜既不是无限长的,也不包含无限数量的线段,而且提到的它还没有通过各个光线的振幅进行归一化。


5
我的取值n范围是从1,但与路易斯·弗拉克(他们在更改时唯一的回答者)一致,我将其更正为from 0,这使镜像对称,并且与其余挑战保持一致。道歉。
Adriaan

Answers:


20

MATL29 26 25字节

感谢@Adriaan提供3个字节的折扣!

Q:qG/q1e3YytP+1e6j*ZeYsXG

这是输入示例...因为今天是MATL的第一个生日!(并且2016年是a年;感谢@MadPhysicist的纠正)。365 366

或在MATL在线试用(实验性编译器;如果无效,请刷新页面)。

在此处输入图片说明

说明

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
拿起最近的毛巾扔进去
魔术章鱼缸

10
MATL生日快乐!
Suever 2016年

1
2016年不是a年吗?
疯狂物理学家

14

MATLAB,88 84 81 79字节

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

感谢@LuisMendo提供-3个字节,以及@Adriaan提供-2个字节!

该函数g是我们在SN和中使用的距离函数NP,并h执行其余的计算和绘图。f我们想要的实际函数,并产生我们需要的向量。

这是输出 N=1111

N = 1111的输出


12

GeoGebra,107个字节

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

每行分别输入到输入栏中。输入来自输入框。

这是执行的gif:

Cornu螺旋

怎么运行的

输入和分别为11E6隐式分配值。接下来,该命令创建一个输入框,并将其与关联。abInputBox[a]a

内部Sequence命令对k0到的整数值进行迭代a。对于的每个值k,使用表达式计算所需距离((k/a)^2+b)^.5+((k/a-1)^2+b)^.5)。然后,将其乘以i*b,其中i虚部为,并e得出结果。这将产生一个复数列表。

此后,外部Sequence通过迭代l1a包括的整数值来执行累积求和。对于的每个值ll使用Sum命令将列表的前几个元素相加,再次产生一个复数列表。

GeoGebra将复数a + bi视为点(a, b)。因此,可以使用Polyline命令绘制复数,该命令将复数列表中的所有点与直线段连接在一起。


5

R,102 82 80字节

编辑:取消计算距离的函数

Edit2:@Plannapus注意到一个几乎相同的答案(哦)

Edit3:由于@Plannapus也节省了2个字节

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

因为N=1000我们得到:

在此处输入图片说明


实际上,您可以低至80个字节,因为您不再需要括号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字节

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

感谢@JarkoDubbeldam额外的3个字节。

对于N = 1000:

N = 1e3


哇,2分钟内有2个R答案。奇怪的是,我尝试了相同的方法,但无法正常工作,但这对我来说很好:S无论如何,不​​错!
2016年

同样,使用scan这样plot(cumsum(exp(1e6i*(sqrt(1e6+(0:(N<-scan())/N)^2)+sqrt(1e6+(0:N/N-1)^2)))),t="l")可以节省一些字节
JAD

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.