Я хочу создать спираль круговых маркеров, которые никогда не пересекаются друг с другом. Это то, что у меня пока получилось, но оно перекрывает первые маркеры, а последние слишком далеко друг от друга.
t = pi : pi/20 : 20*pi;
t = asind(1./t);
r = t;
x = r .* cos(t);
y = r .* sin(t);
plot(x,y,'o-');
axis equal; hold on
График без переопределения t как asinf(1/t) показан на втором графике.
t = pi : pi/20 : 20*pi;
r = t;
x = r .* cos(t);
y = r .* sin(t);
plot(x,y,'o-');
Любые идеи о том, как должно быть расстояние между углами t, чтобы маркеры не перекрывались?
Согласованный. Это именно тот интервал, который я пытаюсь найти. Спасибо!
Вторая формула, которую вы указали для интервала, точно такая же, как и первая. Это ошибка?
Попробуй это:
syms s;
scale = 10;
l = scale/2 : scale/2 : 40*scale;
t = double(arrayfun(@(y) vpasolve((0.5*(s*sqrt(1+s^2)+asinh(s)))==y,s), l));
x = t .* cos(t);
y = t .* sin(t);
plot(x,y,'o-');
pbaspect([1 1 1]);
axis(scale*[-5 5 -5 5])
Идея состоит в том, чтобы параметризовать, используя длину дуги кривой. Длина дуги этой спирали равна l=1/2*(t*sqrt(1+t*t)+asinh(t))
(можно найти с помощью символьного интегрирования Matlab). Чтобы разместить точки равномерно, мы делаем равномерную выборку длины дуги и находим соответствующий t
, решая уравнение. Так как это не может быть легко решено символически, мы используем численный решатель.
Обратите внимание, что масштаб и соотношение сторон графика очень важны для того, чтобы он выглядел однородным и не перекрывался. Вот почему я добавил определение оси/отношения. Поскольку каждая точка решается численно, оценка может занять довольно много времени. Возможно, есть более быстрый способ сделать это, но, по крайней мере, у вас есть результат.
Я получаю следующий результат:
Для этого я использовал Octave Online, так как на моем компьютере нет Matlab. Синтаксис и поведение должны быть одинаковыми. Скажите, работает ли это и решает ли это вашу проблему.
Вы можете аппроксимировать длину дуги, значительно упростив Решение Жиля-Филиппа. Это упрощение, означающее, что расстояние между маркерами не везде одинаково. Однако расстояния довольно постоянны, особенно дальше.
Приближение здесь состоит в том, чтобы предположить, что спираль локально представляет собой круг. Тогда длина дуги равна r*dt
в положении спирали на расстоянии r
от начала координат при изменении угла на dt
радиан.
Теперь нам больше не нужно решать символьные уравнения. Я написал код в цикле. Я уверен, что его можно векторизовать, сделав всего две строки кода, но я оставлю это упражнение читателю.
Это код:
d = 1; % step size
q = 1/(2*pi); % spiral constant -- radius grows by q every 1 radian turn
N = 300; % number of points
t = 0; % initial angle
r = d; % initial radius
p = zeros(100,2);
p(1,:) = [r*cos(t),r*sin(t)]; % first point
for ii=2:N
dt = d/r;
t = t+dt;
r = r+dt*q;
p(ii,:) = [r*cos(t),r*sin(t)];
end
clf
plot(p(:,1),p(:,2),'o-')
axis equal
Я продолжу и сформулирую очевидное высказывание о том, что расстояние не должно быть постоянным. Но вам понадобится кто-то лучше меня в математике, чтобы получить правильную форму интервала.