2014 dxdy logo

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

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




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


28/09/06
8619
Предлагаю эту тему для вопросов и ответов, касающихся написания кодов для TeX-совместимой рисовалки Asymptote.

И для затравки предлагаю первый вопрос:
Каким образом обеспечивается гладкое склеивание патчей, из которых строятся поверхности?

Раскрою суть вопроса подробнее. Поверхности (в коде Asymptote они определяются структурой surface) составляются из четырёхугольных заплаток -- патчей, которые в коде определяются структурой patch. То бишь атрибут $s$ поверхности является массивом патчей. Соответственно, каждый патч имеет атрибут $P$, который представляет собой двумерный размера $4\times4$ массив точек (объектов типа triple). Точки этого массива имеют такой смысл:

1) $P[0][0]$, $P[0][3]$, $P[3][3]$ и $P[3][0]$ являются жёстко фиксированными углами заплатки.
2) $P[0][1]$, $P[0][2]$, $P[1][3]$, $P[2][3]$, $P[3][2]$, $P[3][1]$, $P[2][0]$ и $P[1][0]$ являются парами "контрольных точек" для соответствующих сторон. Т.е. они не обязательно лежат на границе заплатки, но направление, под которым выходит линия соответствующей границы из соответствующего угла, обязательно является направлением на соответствующую контрольную точку.
3) $P[1][1]$, $P[1][2]$, $P[2][2]$ и $P[2][1]$ являются т.н. "внутренними" точками патча. И мой вопрос касается именно их функций, ибо в документации никаких подробностей про них я не нашёл. (В то время как принцип построения кривых Безье -- которыми в том числе рисуются и границы заплатки -- в книжке "Andy Hammerlindl, John Bowman, and Tom Prince. Asymptote: the Vector Graphics Language" описан очень понятно).

Например, если посмотреть, какой объект создаётся командой unitsphere, то можно обнаружить, что эта поверхность состоит из восьми патчей такого типа:

Изображение

Здесь для наглядности помимо системы координат показаны 16 зелёных точек, определяющих патч, а также в квадратных скобках указано каким индексам массива соответствует каждая точка. Нетрудно заметить, что в данном случае четырёхугольная заплатка превращена в треугольную, благодаря тому, что одна из её сторон взята нулевой длины (см. верхний угол). На первый взгляд здесь всё понятно: Например, точки $P[1][0]$ и $P[2][0]$ определяют форму нижней границы. Соответственно, точка $P[1][1]$, например, имеет единичную координату $x$ и такую же координату $y$, как у точки $P[1][0]$, что очевидно гарантирует тот факт, что поверхность подходит к нижней границе вертикально.

Но дело в том, что в этом случае у заплатки все углы прямые, а поэтому всё выглядит достаточно простым, но в жизни не всегда может быть так. На самом деле можно создать заплатку даже с развёрнутым углом (т.е. 180 градусов). И вот здесь у меня возникают непонятки с алгоритмом построения. Скажем, я захотел покрыть одной заплаткой не осьмушку сферы (как в вышеприведённом примере), а сразу четвертушку. В таком случае я пишу такой простенький код:
Код:
      path halfcircle=arc((0,0),1,0,180);
      path3 XYhalfcircle=path3(halfcircle);
      path3 XZhalfcircle=reverse(rotate(90,X)*XYhalfcircle);
      surface S=surface(XYhalfcircle&XZhalfcircle&cycle);


Т.е. я построил полуокружность, повернул её на 90 градусов вокруг прямой, проходящей через концы, а потом на получившийся замкнутый контур натянул поверхность. Разумеется, в итоге всё же получим не четвертушку сферы, а сегмент эллиптического цилиндра:

Изображение

Но это поправимо. Главное, что мы видим, что эта поверхность состоит из одного патча, причём два из его чертырёх углов ($P[3][0]$ и $P[0][3]$) являются развёрнутыми! Теперь, в надежде на превращение этого патча в нечто похожее на четвертушку сферы, мы должны как-то откорректировать положение внутренних точек. Первое, что приходит в голову, это расставить их примерно так же, как в примере со сферическим треугольником. Т.е. ниже добавляем код:

Код:
      triple[][] P=S.s[0].P;
      P[1][1]=(1,P[1][0].y,P[0][1].z);
      P[1][2]=(0,P[1][0].y,1);
      P[2][1]=(0,1,P[0][1].z);
      P[2][2]=(-1,P[3][2].y,P[2][3].z);


Увы, то, что наблюдается на картинке, далеко не похоже на сегмент сферы. В частности, поверхность подходит к нижней границе в области её (границы) середины совсем не вертикально:

Изображение

Поскольку в области углов (которые по 90 градусов) эта фигура больше всего похожа на часть сферы, можно сделать очевидный вывод, что с точками $P[1][1]$ и $P[2][2]$ всё в порядке, а вот с точками $P[1][2]$ и $P[2][1]$ надо что-то менять. Опытным путём я подобрал такое решение:

Код:
      P[1][2]=(0,1+P[1][0].y,1+P[0][1].z);
      P[2][1]=(0,1+P[1][0].y,1+P[0][1].z);


Результат получается ОЧЕНЬ похож на четвертушку сферы. Хотя всё же не идеально. Если убрать прозрачность и пристыковать к этой фигуре снизу её зеркальное отражение относительно плоскости XY, то становится виден шов:

Изображение

Я не понимаю: Можно ли как-то рассчитать положение внутренних точек, чтобы стык был совершенно гладким?

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


31/01/14
9766
Hogtown
С большой вероятностью Вы будете здесь местным гуру по асимптоте: мои знания на зачаточном уровне.

 Профиль  
                  
 
 Re: Вопросы по программированию на Asymptote
Сообщение22.07.2015, 07:27 


13/07/14
249
И в свете предыдущего комментария предлагаю провести небольшой ликбез по асимптоте на русском (и желательно, чтобы не только прожженные математики понимали суть и примеры).
Как подключать? Как построить двумерный график полиномиальной функции с настраиваемыми параметрами осей, границ, толщин линий? (Есть ли разница при компиляции в pdflatex и xelatex? Есть ли примеры для асимптоты и tikz, которые можно бок-о-бок поставить и сравнить результаты и код? Есть ли проблемы при применении с beamer (в частности с командами в духе \alt<2> \only<3>)?

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


28/09/06
8619
На русском языке есть хорошая книжка для начинающих: "Ю.Г. Крячков. Asymptote для начинающих". К сожалению, она не настолько подробна, как хотелось бы. Достаточно подробное официальное англоязычное руководство называется: "Andy Hammerlindl, John Bowman, and Tom Prince. Asymptote: the Vector Graphics Language". Я бы дал ссылку на официальный сайт, но он размещён на лежащем уже неделю SourceForge.net. Так что лучше ищите литературу поиском. В принципе, в подключении нет ничего сложного. Касательно более специфических вопросов: я мог бы попытаться на что-то ответить в меру своего, увы, достаточно скромного понимания, но только при наличии конкретных вопросов. "Ликбез" общего плана, увы, на потяну.

P.S. Поскольку официальный сайт наконец ожил, я добавил выше ссылку на официальное руководство по Asymptote,

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


06/10/08
6301
epros в сообщении #1039216 писал(а):
3) $P[1][1]$, $P[1][2]$, $P[2][2]$ и $P[2][1]$ являются т.н. "внутренними" точками патча. И мой вопрос касается именно их функций, ибо в документации никаких подробностей про них я не нашёл. (В то время как принцип построения кривых Безье -- которыми в том числе рисуются и границы заплатки -- в книжке "Andy Hammerlindl, John Bowman, and Tom Prince. Asymptote: the Vector Graphics Language" описан очень понятно).
Скорее всего, используюся bicubic Bezier patches, обобщение кривых Безье. Если построить кривые Безье по точкам P[0][*], P[1][*], P[2][*], P[3][*], получится 4 кривых $S_1(t), S_2(t), S_3(t), S_4(t)$. Поверхность составлена из кривых Безье, построенным по четверкам точек на этих кривых с одинаковым $t$.

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

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


28/09/06
8619
Так-с, касательно моего собственного вопроса о гладком склеивании патчей: Я, вроде бы, разобрался со случаем склейки, когда патч не имеет развёрнутых углов. Вот такая нетривиальная фигура собирается из восьми патчей:

Изображение

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

Изображение

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

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


31/01/14
9766
Hogtown
epros в сообщении #1039440 писал(а):
Так что лучше ищите литературу поиском.

Ну я же дал ссылку на CTAN (если в документации TeX на компьютере нет). Более того, sourceforge частично работает

http://sourceforge.net/projects/asymptote/
http://sourceforge.net/p/asymptote/discussion/409349

и, кстати, один из участников дискуссии за 2 недели до того предложил перейти на другой хостинг

http://sourceforge.net/p/asymptote/discussion/409349/thread/3ffb2e10/

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


28/09/06
8619
Xaositect в сообщении #1039443 писал(а):
Сейчас поищу константы для аппроксимации окружности и попробую приблизить четвертушку сферы.
Я тупо беру значения из координат контрольных точек уже построенной границы патча, не задумываясь о расчёте констант. Пусть алгоритм за меня думает. :-)

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


28/09/06
8619
Xaositect в сообщении #1039443 писал(а):
Мне, правда, кажется, что восьмушка все равно будет более точная.
Да, если кривой Безье приближать слишком длинную дугу окружности, то приближение получается не очень хорошим. Вот построение для дуги длиной 240 градусов (кривая Безье -- чёрной сплошной линией, окружность -- зелёной):

Изображение
Код:
      pair O=(0,0),A=(-sqrt(3)/2,-1/2),B=(-1-sqrt(3)/2,3/2),C=(1+sqrt(3)/2,3/2),D=(sqrt(3)/2,-1/2);
      path p1=A ..controls B and C .. D;


Но всё-таки моя четвертушка сферы ограничена дугами окружности всего в 90 градусов, т.е. точно так же, как восьмушка. Но, похоже, что вся проблема в наличии развёрнутого угла: Хорошо склеить патчи в области развёрнутого угла никак не получается. Похоже, такие патчи всегда нужно резать на куски.

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


28/09/06
8619
Хм, как я понял из этой статьи, ключевыми словами для понимания являются "Coons interpolation". Осталось разобраться с тем, что это такое...

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


28/09/06
8619
Вот пример гладкой склейки фигуры из 4 патчей:

Изображение

Код:
import three;
import animation;
unitsize(400);
// Определяем контур из двух кривых Безье
path3 cont=O{Y-X}.. tension .75 ..{X-Y}-Y{Z}.. tension 1.5 ..{-Z}cycle;
triple[][] P={{},{},{},{}};
for(int i=0; i<4; ++i) {
   // Две противоположные стороны патча сжаты в углах контура
   P[0][i]=point(cont,0);
   P[3][i]=point(cont,1);
}
// Контрольные точки двух кривых, составляющих границу патча
P[1][3]=postcontrol(cont,0);
P[2][3]=precontrol(cont,1);
P[2][0]=postcontrol(cont,1);
P[1][0]=precontrol(cont,0);

// Внутренние точки патча
P[1][1]=(P[1][0]-P[0][0])+(P[1][3]-P[0][0])/2+P[0][0];
P[1][2]=(P[1][0]-P[0][0])/2+(P[1][3]-P[0][0])+P[0][0];
P[2][1]=(P[2][0]-P[3][3])+(P[2][3]-P[3][3])/2+P[3][3];
P[2][2]=(P[2][0]-P[3][3])/2+(P[2][3]-P[3][3])+P[3][3];

// Заполняем массив четырьмя патчами, полученными
// из исходного посредством отражений и поворотов
patch[] Ps={patch(P)};
Ps.push(patch(reflect(O,X,Y)*P));
Ps.push(patch(rotate(180,-Y/2,Z-Y/2)*P));
Ps.push(patch(reflect(O,X,Y)*rotate(180,-Y/2,Z-Y/2)*P));

// Делаем из этого массива патчей поверхность
surface S=new surface;
S.s=Ps;

// И рассматриваем её с разных сторон
animation A;
currentprojection=perspective((5,0,3),Y);
int maxi=30;
for(int i=0; i<maxi; ++i) {
  transform3 t=rotate(360*i/maxi,O,Y);
  // На каждом шаге поворачиваем поверхность и контур
  // исходного патча на угол 360/maxi градусов
  surface S1=t*S;
  path3 cont1=t*cont;
  save();
  // Невидимая сфера вокруг картинки нужна чтобы фигура
  // не масштабировалась по-разному в зависимости от угла поворота
  draw(shift(-Y/2)*scale3(.75)*unitsphere,invisible);
  draw(S1,red);
  draw(cont1,darkblue+2pt);
  A.add();
  restore();
}
A.movie(0,400);


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

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


31/01/14
9766
Hogtown
А как раскрасить в градиентные цвета: скажем от red!50 до blue!30 ?

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


28/09/06
8619
Red_Herring в сообщении #1040568 писал(а):
А как раскрасить в градиентные цвета: скажем от red!50 до blue!30 ?
С этим пока не разбирался, но, вроде, на их сайте есть примеры градиентной раскраски в разделе 3D Graphs.

Меня печалит другая вещь: Здесь есть мощный инструмент для программирования анимации (причем интерактивной -- с кнопочками), и эта анимация вставляется в pdf. Но... на линуксе нет нормальных читалок анимированных pdf файлов! Adobe перестал выпускать свой ридер для линукса, а другие читалки JavaScript-анимацию не понимают. Лучшее, что можно сделать, это переделать анимированный gif в видео и вставить его в LaTeX как multimedia объект.

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


31/01/14
9766
Hogtown
epros в сообщении #1040611 писал(а):
Здесь есть мощный инструмент для программирования анимации (причем интерактивной -- с кнопочками), и эта анимация вставляется в pdf. Но... на линуксе нет нормальных читалок анимированных pdf файлов! Adobe перестал выпускать свой ридер для линукса, а другие читалки JavaScript-анимацию не понимают.

AR9 ведь есть? И он (по крайней мере апгрейдированный до упора) прекрасно читает 3D модели и Javascript анимацию и movie.

(Адобе)

Другое дело, что ни он, и никакая другая читалка не изображает толком Adobe Portfolio (требует 10+) и есть ещё штучки, требующие 11+ (возникают в LaTeX пакете interactive plot, кажется, связаны с ocg), пока вроде ничто не требует 12+. Я об этом на этом форуме писал.

Я знаю людей, постоянно бета-тестирующих AR/AA и которые на внутренних адобовских форумах постоянно пишут о необходимости поддержки Linux, но это без эффекта. Кстати, AR/AA разрабатываются в индийском филиале Адобе.

Кстати, некоторые из топовых разработчиков всех этих штук в LaTeX используют Linux: Heiko Oberdiek и Alrxander Grahn—точно.

На другие читалки надежды нет: на poppler листе эти штуки не обсуждаются.

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


28/09/06
8619
Как-то странно ставить себе невесть что, взятое невесть откуда. С тех пор, как снёс себе виндоус, как-то я отвык от этого.

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

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



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

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


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

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