Спираль непересекающихся кругов - PullRequest
3 голосов
/ 07 апреля 2019

Я хочу создать спираль из круговых маркеров, которые никогда не пересекаются друг с другом. Это то, что я получил до сих пор, но оно перекрывает первые маркеры, а последние слишком далеко друг от друга.

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, чтобы маркеры не перекрывались?

enter image description here

enter image description here

Ответы [ 2 ]

4 голосов
/ 08 апреля 2019

Вы можете приблизить длину дуги, значительно упрощая решение Жиля-Филиппа .Это упрощение, которое означает, что расстояние между маркерами не везде одинаково.Однако расстояния довольно постоянны, особенно дальше.

Приближением здесь является допущение, что спираль локально является окружностью.Длина дуги в этом случае равна 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

spiral with almost-equidistant markers

3 голосов
/ 07 апреля 2019

Попробуйте это:

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, решая уравнение.Поскольку это не может быть легко решено символически, мы используем числовое решение.

Обратите внимание, что масштаб и соотношение сторон графика действительно важны для того, чтобы они выглядели равномерно и не перекрывались.Вот почему я добавил определение оси / отношения.Поскольку каждая точка решается численно, оценка может занять некоторое время.Может быть более быстрый способ сделать это, но по крайней мере у вас есть результат.

Я получаю следующий результат:

Uniform Sampling Spiral

...