Построение спирали Корну


33

Корень спираль может быть вычислена с использованием методы Фейнман для интегралов по путям распространения света. Мы аппроксимируем этот интеграл, используя следующую дискретизацию.

Рассмотрим зеркало, как на этом изображении, где Sнаходится источник света и Pточка, где мы собираем свет. Мы предполагаем, что свет отражается прямым лучом от Sкаждой точки в зеркале, а затем до точки P. Разделим зеркало в Nсегментах, в данном примере 13, меченого Aс M, так что длина пути света R=SN+NP, где SNэто расстояние от Sдо зеркального сегмента N, и аналогичные для P. ( Обратите внимание , что на изображении расстояния точек Sи Pк зеркалу было сокращено много, для визуальных целей. Блок Qскорее не имеет значения, и помещает чисто , чтобы обеспечить отражение через зеркало, и избежать прямого света от SдоP, )

Отражающее зеркало

Для заданного волнового числа Фазор луча света может быть вычислена как , где находится мнимая единица. Построение всех этих векторов от головы до хвоста от левого зеркального сегмента вправо приводит к спирали Корну. Для 13 элементов и значений, описанных ниже, это дает:kexp(i k R)i

введите описание изображения здесь

Для больших N, то есть множества зеркальных сегментов, спираль приближается к «истинной» спирали Корну. Посмотрите это изображение, используя различные значения для N:

введите описание изображения здесь

Вызов

Для данного Nпусть x(n)будет x -координатный центр n-го зеркального сегмента ( 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 пикселей или с использованием векторной графики. Цвет линии, масштаб осей и т. Д. Не важны, пока форма видна.

Поскольку это код-гольф, выигрывает самый короткий код в байтах.

Обратите внимание, что это не настоящая спираль Корну, а ее приближение. Начальный интеграл по траектории был аппроксимирован с использованием приближения Френеля, и зеркало не имеет бесконечной длины и не содержит бесконечного числа сегментов, а также упомянуто, что оно не нормируется по амплитудам отдельных лучей.


5
У меня были значения в nдиапазоне от 1, но, согласившись с Луисом и Флауром, которые были единственными ответчиками во время изменений, я исправил его, чтобы сделать так 0, чтобы зеркало было симметричным и соответствовало остальной части задачи. Извиняюсь.
Адриан

Ответы:


20

MATL , 29 26 25 байт

Спасибо @Adriaan за 3 байта!

Q:qG/q1e3YytP+1e6j*ZeYsXG

Вот пример с вводом ... потому что сегодня первый день рождения MATL! (и 2016 год високосный; спасибо @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
С Днем Рождения, МАТЛ!
Suever

1
2016 год не високосный?
Безумный физик

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

Каждая строка вводится отдельно в строку ввода. Ввод берется из поля ввода.

Вот рисунок исполнения:

Спираль корну

Как это работает

Ввод 1и 1E6неявное назначение значений aи bсоответственно. Затем InputBox[a]команда создает поле ввода и связывает его с a.

Внутренняя Sequenceкоманда перебирает целочисленные значения kот 0до до aвключительно. Для каждого значения kтребуемое расстояние рассчитывается с использованием выражения ((k/a)^2+b)^.5+((k/a-1)^2+b)^.5). Затем это умножается на i*b, где iмнимая единица, и eповышается до результата. Это дает список комплексных чисел.

После этого внешнее Sequenceвыполняет накопительное суммирование, перебирая целочисленные значения lот 1до до aвключительно. Для каждого значения lпервые lэлементы списка суммируются с помощью Sumкоманды, снова получая список комплексных чисел.

GeoGebra рассматривает комплексное число a + biкак точку (a, b). Следовательно, комплексные числа могут быть нанесены с помощью Polylineкоманды, которая объединяет все точки в списке комплексных чисел с отрезками прямых.


5

R, 102 82 80 байт

Редактировать: отменить функцию для расчета расстояния

Edit2: заметил почти идентичный ответ @Plannapus (о хорошо)

Edit3: 2 байта также сохранены благодаря @Plannapus

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 R ответы в течение 2 минут. Странно, я попробовал то же самое, и я не мог заставить его работать, но это прекрасно работает для меня: S В любом случае, хорошая работа!
JAD

Кроме того, использование сканирования как такового plot(cumsum(exp(1e6i*(sqrt(1e6+(0:(N<-scan())/N)^2)+sqrt(1e6+(0:N/N-1)^2)))),t="l")сохраняет несколько байтов
JAD

1

Mathematica 89 байт (87 символов)

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

Использование:

%@100

доходность

введите описание изображения здесь

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.