gatoazul (gatoazul) wrote,
gatoazul
gatoazul

Category:

Шедевры искусства своими руками

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

Вот он:


Запускаем программу по имени Asymptote - незаменимый инструмент рисования по математическим формулам и разглядываем оригинал.

Чего там рисовать? Набор эллипсов, равномерно располагающихся по кругу, то есть каждый повернут на один и тот же угол по сравнению с предыдущим.

Непосредственные замеры показывают, что всего эллипсов сорок штук, соотношение сторон у них 5:2, основной эллипс имеет пропорции 5:3.

Набрасываем цикл и видим нечто похожее, но только местами.



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

Чтобы это исправить, надо повернуть внутренний эллипс на небольшой угол, так, чтобы он соприкасался с внешним контуром ровно в одной точке.
Если попытаться рассчитать это математически, то получается нелинейная система с кучей синусов и косинусов. Нелинейные системы рассчитываются итерационно, по хитрым алгоритмам - то есть, по существу, в цикле.

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

Результат радует глаз:


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


// воспроизведение узора с 2 гривен

size(300,300);

path el = scale(5,3)*unitcircle;

int count = 40;

//////////////////////////////

real fit_ellipses(path big, path small, real phi, bool decrement)
{
  real precision = 0.001;
  real angle = phi;
  while(true)
  {
    real[][] pt = intersections(big, rotate(degrees(angle))*small);
    if (pt.length<2)
    {
      return angle;
    }
    angle = decrement ? angle-precision : angle+precision;
  }
 
  return phi;
}

//////////////////////////////

for(int i=0; i<count; i=i+1)
{
  real angle = i*2pi/count;
  pair pt = (5*cos(angle), 3*sin(angle));
  real a = length(pt);
  path smel = shift(a/2,0)*scale(a/2,a/5)*unitcircle;
  if (i%10!=0)
  {
    int quadrant = quotient(i,10);
    angle = fit_ellipses(el, smel, angle, quadrant==0 || quadrant==2);
  }
  draw(rotate(degrees(angle))*smel);
}

draw(el);
Subscribe

  • Путешествия слов - 2 (загадка)

    Тюркское слово "казак" означало "потерявший род". Так назывались молодые мужчины, ищущие судьбу и славу за пределами обжитой…

  • Путешествия слов (загадка)

    В вульгарной латыни слово extufa jозначало какую-то разновидность бани. Оно было заимствовано в древневерхненемецкий как stuba, что означало уже…

  • Загадка древнегреческая

    Переведите на греческий язык: 1) Соразмерность 2) Соименность 3) Созвучие 4) Сообзор 5) Сочувствие 6) Современность

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 9 comments