2014 dxdy logo

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

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




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


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

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

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


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

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


31/01/14
11305
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
10849
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
10849
Вот чуть более продвинутый пример тензорной раскраски кольца, составленного из трёх равных патчей (секторов):

Изображение

Код:
   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
10849
О, произведение называется "Привет Красной Армии". :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
11305
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
10849
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
11305
Hogtown
Надо будет попробовать (когда закончу мой главный проект). Впрочем с ODE разберусь пораньше (а то приходится полагаться на maple)

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


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

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


28/09/06
10849
В продолжение темы 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
10849
Рекомендую вновь написанный модуль 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, Супермодераторы



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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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