2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2
 
 Re: Вопросы по программированию на Asymptote
Сообщение26.07.2015, 19:07 
Заслуженный участник
Аватара пользователя


31/01/14
11467
Hogtown
epros в сообщении #1040668 писал(а):
Как-то странно ставить себе невесть что, взятое невесть откуда.

С сайта адобе.

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение26.07.2015, 20:47 
Заслуженный участник
Аватара пользователя


28/09/06
11175
Red_Herring в сообщении #1040678 писал(а):
С сайта адобе
Что-то я не нашёл. Все версии, включая 9, для любых систем, кроме линукса.

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение26.07.2015, 21:02 
Заслуженный участник
Аватара пользователя


31/01/14
11467
Hogtown
epros в сообщении #1040689 писал(а):
то-то я не нашёл. Все версии, включая 9, для любых систем, кроме линукса.

Точно.
http://www.omgubuntu.co.uk/2014/10/adobe-reader-linux-download-pulled-website
https://www.reddit.com/r/linux/comments/2hsgq6/linux_version_of_adobe_reader_no_longer/
Все знают что Adobe is evil.

Надо будет спросить на адобовском форуме

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение27.07.2015, 19:34 
Заслуженный участник
Аватара пользователя


28/09/06
11175
Red_Herring в сообщении #1040568 писал(а):
А как раскрасить в градиентные цвета: скажем от red!50 до blue!30 ?
Решил с Вашей подачи изучить вопросы градиентной закраски. Способов обнаружилось довольно много, от простого градиента по направлению или радиально от окружности к окружности (что мало интересно в силу примитивности), до закраски согласно произвольно заданной пользователем функции (что мало интересно как раз в силу произвольности). Но есть и специфические способы. Например, метод тонирования Гуро. Простейший пример применения этого метода -- градиентная закраска треугольника с заданными цветами в углах (например, red, green, blue):

Изображение

Код:
      pair O=(0,0);
      transform r=rotate(360/3,O);
      pair A0=(1,0),A1=r*A0,A2=r*A1;
      path g=A0..A1..A2..cycle;
      // Обратите внимание, что контур гладкий (почти окружность),
      // но закрашивается только треугольник, образованный узлами
      gouraudshade(g=g, p=new pen[] {red,green,blue}, edges=new int[] {0,0,0});


Ну, этот пример слишком тривиальный. Давайте теперь закрасим правильный шестиугольник:

Изображение

Код:
      // Делаем правильный шестиугольник, закрашенный по методу Гуро
      pair O=(0,0);
      transform r=rotate(360/6,O);
      pair A0=(1,0),A1=r*A0,A2=r*A1,A3=r*A2,A4=r*A3,A5=r*A4;
      path g=A0..A1..A2..A3..A4..A5..cycle;
      gouraudshade(g=g, p=new pen[] {white,red,yellow,green,cyan,blue,magenta,red}, z=new pair[] {O,A0,A1,A2,A3,A4,A5,A0}, edges=new int[] {0,0,0,2,2,2,2,2});


Самое интересное в этом коде -- это массив edges. Элемент этого массива определяет номер стороны текущего треугольника, к которой приделывается следующий треугольник.

Однако получилось не очень хорошо, потому что яркость смешанных цветов, таких как yellow=red+green, вдвое больше яркости базовых цветов. Соответственно, яркость цвета white -- втрое больше. Чтобы было больше похоже на гладкий "цветовой круг", нужно откорректировать яркость посредством такого изменения в коде:

Код:
      gouraudshade(g=g, p=new pen[] {.33white,red,.5yellow,green,.5cyan,blue,.5magenta,red}, z=new pair[] {O,A0,A1,A2,A3,A4,A5,A0}, edges=new int[] {0,0,0,2,2,2,2,2});


Результат больше похож на то, что получилось в случае треугольника:

Изображение

Однако здесь плохо то, что в центре -- не белый, а тёмно-серый цвет. Можно попробовать такой компромисс:

Код:
      gouraudshade(g=g, p=new pen[] {white,red,.5yellow,green,.5cyan,blue,.5magenta,red}, z=new pair[] {O,A0,A1,A2,A3,A4,A5,A0}, edges=new int[] {0,0,0,2,2,2,2,2});


Вот результат:

Изображение

Тоже не идеально, конечно. Очевидно, что применение этого метода ограничено теми областями, где нас устраивает линейная интерполяция цветов. С помощью пользовательских функций явно можно сделать лучше.

-- Пн июл 27, 2015 21:26:03 --

А вот ещё простейший пример тензорной закраски (применяется к четырёхугольным патчам):

Изображение

Код:
   pair O=(0,0);
   transform r=rotate(90,O);
   pair A0=(1,0),A1=r*A0,A2=r*A1,A3=r*A2;
   path p=A0..A1..A2..A3..cycle;
   tensorshade(g=p,p=new pen[] {red,yellow,green,black});


Здесь, как видите, в отличие от метода Гуро, закрашивается вся область внутри контура.

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение27.07.2015, 21:35 
Заслуженный участник
Аватара пользователя


28/09/06
11175
Вот чуть более продвинутый пример тензорной раскраски кольца, составленного из трёх равных патчей (секторов):

Изображение

Код:
   transform r=rotate(120,(0,0));
   pair A0=(1,0),A1=r*A0,A2=r*A1;
   pair B0=(3,0),B1=r*B0,B2=r*B1;
   path pa=A0..A1..A2..cycle,pb=B0..B1..B2..cycle;
   path[] ps={
      subpath(pa,1,0)--subpath(pb,0,1)--cycle,
      subpath(pa,2,1)--subpath(pb,1,2)--cycle,
      subpath(pa,3,2)--subpath(pb,2,3)--cycle,
   };
   pen[][] pe={
      {red,blue,yellow,cyan},
      {green,red,cyan,magenta},
      {blue,green,magenta,yellow}
   };
   tensorshade(g=ps,p=pe);


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

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение27.07.2015, 23:35 
Заслуженный участник
Аватара пользователя


28/09/06
11175
О, произведение называется "Привет Красной Армии". :lol:

Изображение

Код:
   transform r=rotate(72,(0,0)),s=scale(1/sqrt(2(1+sin(38)))),f=reflect((0,0),(1,0));
   pair A0=(0,1),A1=r*A0,A2=r*A1,A3=r*A2,A4=r*A3;
   path[] ps={A0--A2--A4--A1--A3--cycle};
   for(int i=0; i<10; ++i) ps.push(f*s*ps[i]);
   fill(ps,evenodd+red);


Интересно, на Tikz код проще получится?

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение28.07.2015, 00:08 
Заслуженный участник
Аватара пользователя


31/01/14
11467
Hogtown
epros в сообщении #1040924 писал(а):
Интересно, на Tikz код проще получится?

Думаю что нет, но не слишком сложный. Там тоже есть \foreach

Но дело не только в простоте кода:

1) если я вставляю tikz код в источник, то все скомпилируется, а вот асимптотовский код сначала из латех должен быть экспортирован в отдельный файл напр. через \filecontent, затем пропущен через asy и лишь в конце импотирован в латех

2) есть пакеты—надстройки над tikz

3) Ни асимптоте, ни gnuplot ОДЕ решать не умеют (и много чего другого). А вот octave умеет, и у нее есть экспорт для gnuplot ибо octave использует gnuplot для графического вывода. А тут и на tikz передать можно

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение28.07.2015, 13:23 
Заслуженный участник
Аватара пользователя


28/09/06
11175
Red_Herring в сообщении #1040929 писал(а):
1) если я вставляю tikz код в источник, то все скомпилируется, а вот асимптотовский код сначала из латех должен быть экспортирован в отдельный файл напр. через \filecontent, затем пропущен через asy и лишь в конце импотирован в латех
Чтобы всё это делалось автоматически, нужно поставить latexmk.

Red_Herring в сообщении #1040929 писал(а):
2) есть пакеты—надстройки над tikz
Ну, дык, надстройки над asymptote реализуются в виде *.asy файлов. Их есть куча как в стандартной поставке, так и от сторонних разработчиков. И самому можно написать что-то часто употребимое, если его ещё кто-то другой не написал.

Честно говоря, бегло пролистав книжку Tantau про TikZ, я не очень впечатлился: Понаписано о-о-чень много, но напоминает какую-то свалку -- нужные именно тебе вещи найти очень трудно. Найденный в сети набор примеров тоже не впечатлил: В частности, с 3D там, по-моему, как-то слабовато. Может я просто не разобрался...

Red_Herring в сообщении #1040929 писал(а):
3) Ни асимптоте, ни gnuplot ОДЕ решать не умеют (и много чего другого). А вот octave умеет, и у нее есть экспорт для gnuplot ибо octave использует gnuplot для графического вывода. А тут и на tikz передать можно
Как это asymptote не умеет? Есть же специальный модуль ode.asy в стандартной поставке. Я, правда, с ним пока ещё не разбирался...

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение28.07.2015, 16:06 
Заслуженный участник
Аватара пользователя


31/01/14
11467
Hogtown
Надо будет попробовать (когда закончу мой главный проект). Впрочем с ODE разберусь пораньше (а то приходится полагаться на maple)

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение28.07.2015, 23:28 
Заслуженный участник
Аватара пользователя


28/09/06
11175
В продолжении вопроса гладких склеек: Покопавшись в коде модуля three_surface.asy, я нашёл в функции pair[][] coons(path p) вот такой интересный код:

Код:
   for(int j=0; j < 4; ++j) {
      internal[j]=nineth*(-4*point(p,j)
      +6*(precontrol(p,j)+postcontrol(p,j))
      -2*(point(p,j-1)+point(p,j+1))
      +3*(precontrol(p,j-1)+postcontrol(p,j+1))
      -point(p,j+2));
   };


Судя по всему, это и есть то, что называется "Coons interpolation": для заданного четырёхугольного контура строится массив из 4 внутренних точек (остальные 12 точек уже есть -- это 4 угла контура и 8 его контрольных точек). Я попробовал применить этот алгоритм к четырёхугольному контуру, ограничивающему четвертушку сферы (см. первое сообщение темы). Получившийся патч вполне ожидаемо оказался сегментом эллиптическлого цилиндра (а не сферы), который я уже рисовал в первом сообщении...

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение03.08.2015, 15:14 
Заслуженный участник
Аватара пользователя


28/09/06
11175
epros в сообщении #1041160 писал(а):
Судя по всему, это и есть то, что называется "Coons interpolation"
Всё-таки это не совсем то. По крайней мере, если я определяю этим алгоритмом внутренние точки для патча в виде сферического треугольника, то ожидаю, что координата $x$ внутренней точки, ближайшей к углу $(1,0,0)$, должна быть равна $1$. Однако она оказывается равна $0.8889$. Странно. Если построить сферу командой unitsphere, то для её первого патча внутренняя точка, ближайшая к этому углу, будет иметь координату $x=1$. Что-то не так с этим алгоритмом. То-то я удивлялся, зачем нужно при расчёте координат внутренней точки учитывать координаты самого дальнего от неё угла...

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение07.08.2015, 16:28 
Заслуженный участник
Аватара пользователя


28/09/06
11175
В продолжение темы Coons interpolation и состояния задачи гладкого склеивания патчей, в котором я застрял:

1) Итак, родной алгоритм, который применяет Asymptote, я нахожу некорректным. Обоснование очень простое: Если взять треугольный контур, ограничивающий осьмушку сферы, и вычислить внутренние точки патча с помощью родного алгоритма Asymptote, то получившийся треугольный патч очень похож на осьмушку сферы, но линия соединения таких патчей имеет видимую негладкость.

Изображение

Здесь для вычисления внутренних точек патчей (ближайших к линии склейки) использован такой код:

Код:
      P1[2][1]=(6*P1[2][0]+6*P1[3][1]+3*P1[0][1]+3*P1[2][3]-4*P1[3][0]-2*P1[0][0]-2*P1[3][3]-P1[0][3])/9;
      P2[2][1]=(6*P2[2][0]+6*P2[3][1]+3*P2[0][1]+3*P2[2][3]-4*P2[3][0]-2*P2[0][0]-2*P2[3][3]-P2[0][3])/9;
      P1[2][2]=(6*P1[3][2]+6*P1[2][3]+3*P1[0][2]+3*P1[2][0]-4*P1[3][3]-2*P1[3][0]-2*P1[0][3]-P1[0][0])/9;
      P2[2][2]=(6*P2[3][2]+6*P2[2][3]+3*P2[0][2]+3*P2[2][0]-4*P2[3][3]-2*P2[3][0]-2*P2[0][3]-P2[0][0])/9;


Я проверил, именно этот алгоритм Asymptote использует при генерации поверхности по заданному контуру. Т.е. мы получим такой же "негладко склеиваемый" патч, например, таким кодом:

Код:
      path3 outline=octant1.external();
      surface S=surface(outline);


Сравните со склейкой двух осьмушек сферы, внутренние точки которых определены вручную, т.е. не глядя ни на какие алгоритмы "Coons interpolation":

Изображение

Здесь линия склейки выглядит абсолютно гладкой (притом, что границы патчей в обоих примерах абсолютно одинаковые, отличаются только внутренние точки патчей). Потому что в качестве кода для вычисления внутренних точек патчей выбрана гораздо более простая вещь:

Код:
      P1[2][1]=P1[2][0]+P1[3][1]-P1[3][0];
      P2[2][1]=P2[2][0]+P2[3][1]-P2[3][0];
      P1[2][2]=P1[2][3]+P1[3][2]-P1[3][3];
      P2[2][2]=P2[2][3]+P2[3][2]-P2[3][3];


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

2) К сожалению, этот способ не работает в случае треугольного патча, в том угле, в который стянута одна из четырёх сторон. А без треугольных патчей не обойтись.
Но самое печальное, что этот способ не работает, если угол патча не прямой или направления из углов на точки P1[2][0] и P1[2][3] не коллинеарны: Линия склейки сразу становится видна.

3) Попытавшись формализовать задачу, я столкнулся с вычислительными сложностями. Бикубическая поверхность Безье определяется достаточно простым отображением единичного плоского квадрата $u \times v$, $u,v \in [0,1]$ в трёхмерное пространство. Формула такая: $$\vec{P}(u,v)=\sum\limits_{i,j=0}^3 \frac{3!}{i!(3-i)!} u^i(1-u)^{3-i} \frac{3!}{j!(3-j)!} v^j(1-v)^{3-j} \vec{P}_{i j}.$$ Здесь матрица $$||\vec{P}_{i j}||$ размера $4 \times 4$ составлена из 16 точек, определяющих патч.

Если подсчитать $\frac{\partial}{\partial v} \vec{P}(u,0)$, то нетрудно убедиться, что получим кривую Безье (кубический сплайн) с граничными точками $\vec{P}_{0 1}-\vec{P}_{0 0}$ и $\vec{P}_{3 1}-\vec{P}_{3 0}$, и с контрольными точками $\vec{P}_{1 1}-\vec{P}_{1 0}$ и $\vec{P}_{2 1}-\vec{P}_{2 0}$. Т.е как внутренние точки патча влияют на наклон поверхности на границе -- в принципе понятно. К сожалению, вектор $\frac{\partial}{\partial v} \vec{P}(u,0)$ определяет не совсем наклон поверхности. Этот удачный случай имеет место только тогда, когда все четыре вектора $\vec{P}_{0 1}-\vec{P}_{0 0}$, $\vec{P}_{3 1}-\vec{P}_{3 0}$, $\vec{P}_{1 1}-\vec{P}_{1 0}$ и $\vec{P}_{2 1}-\vec{P}_{2 0}$ ортогональны к границе патча. Попытка подсчитать, собственно, формулу для нормали к поверхности на её границе приводит к формуле какого-то громоздкого полинома (сплайна) пятой степени...

Итак, задача такая: Придумать алгоритм расчёта четырёх внутренних точек патча через 12 заданных остальных точек, который гарантировал бы гладкую склейку патчей, имеющих:
а) общую линию границы,
б) общие направления нормалей в тех углах, в которых они соединяются.
Гладкость означает совпадение нормалей на всей линии соединения патчей.

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение10.08.2015, 17:08 
Заслуженный участник
Аватара пользователя


28/09/06
11175
Рекомендую вновь написанный модуль Asymptote smoothcontour3.asy

Вот пример (жмите на картинку):

Изображение

Это семейство поверхностей, удовлетворяющих уравнению $$|\vec{r}-\vec{V_1}|\cdot|\vec{r}-\vec{V_2}|\cdot|\vec{r}-\vec{V_3}|\cdot|\vec{r}-\vec{V_4}|=\operatorname{const}$$ при разных значениях $\operatorname{const}$, где $\vec{V_1}, \vec{V_2}, \vec{V_3}, \vec{V_4}$ -- вершины тетраэдра.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 28 ]  На страницу Пред.  1, 2

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: Lenchik


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group