http://wiki.linuxformat.ru/wiki/index.php?title=LXF77:MetaPost&feed=atom&action=historyLXF77:MetaPost - История изменений2024-03-28T10:05:02ZИстория изменений этой страницы в викиMediaWiki 1.19.20+dfsg-0+deb7u3http://wiki.linuxformat.ru/wiki/index.php?title=LXF77:MetaPost&diff=4640&oldid=prevLockal: {{Цикл/MetaPost}}2008-05-16T19:14:41Z<p>{{Цикл/MetaPost}}</p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr valign='top'>
<td colspan='2' style="background-color: white; color:black;">← Предыдущая</td>
<td colspan='2' style="background-color: white; color:black;">Версия 19:14, 16 мая 2008</td>
</tr><tr><td colspan="2" class="diff-lineno">Строка 1:</td>
<td colspan="2" class="diff-lineno">Строка 1:</td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">{{Цикл/MetaPost}}</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== MetaPost Базовые элементы ==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>== MetaPost Базовые элементы ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>''Определённо всё из чего-то состоит. Элементарные кирпичики – вот что интересно. '''Евгений Балдин''' продолжает уроки рисования.''</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>''Определённо всё из чего-то состоит. Элементарные кирпичики – вот что интересно. '''Евгений Балдин''' продолжает уроки рисования.''</div></td></tr>
</table>Lockalhttp://wiki.linuxformat.ru/wiki/index.php?title=LXF77:MetaPost&diff=4635&oldid=prevYaleks: /* Рисуем по точкам */2008-05-16T15:37:43Z<p><span dir="auto"><span class="autocomment">Рисуем по точкам</span></span></p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr valign='top'>
<td colspan='2' style="background-color: white; color:black;">← Предыдущая</td>
<td colspan='2' style="background-color: white; color:black;">Версия 15:37, 16 мая 2008</td>
</tr><tr><td colspan="2" class="diff-lineno">Строка 63:</td>
<td colspan="2" class="diff-lineno">Строка 63:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>для составления какого-либо узора:</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>для составления какого-либо узора:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins class="diffchange diffchange-inline">[[Изображение:Img 77 97 1.png|Img 77 97 1.png]]</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>Обратите внимание, что почти все числовые значения представляют</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>Обратите внимание, что почти все числовые значения представляют</div></td></tr>
<tr><td colspan="2" class="diff-lineno">Строка 74:</td>
<td colspan="2" class="diff-lineno">Строка 74:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>гвоздями». В данном случае наличие параметра позволяет легко изменить масштаб рисунка:</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>гвоздями». В данном случае наличие параметра позволяет легко изменить масштаб рисунка:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="background: #ffa; color:black; font-size: smaller;"><div> </div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins class="diffchange diffchange-inline">[[Изображение:Img 77 97 2.png|Img 77 97 2.png]]</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>Очевидно, что в предложенном решении одного параметра мало,</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>Очевидно, что в предложенном решении одного параметра мало,</div></td></tr>
</table>Yalekshttp://wiki.linuxformat.ru/wiki/index.php?title=LXF77:MetaPost&diff=4631&oldid=prevYaleks: Новая: == MetaPost Базовые элементы == ''Определённо всё из чего-то состоит. Элементарные кирпичики – вот что интер...2008-05-16T12:26:20Z<p>Новая: == MetaPost Базовые элементы == ''Определённо всё из чего-то состоит. Элементарные кирпичики – вот что интер...</p>
<p><b>Новая страница</b></p><div>== MetaPost Базовые элементы ==<br />
''Определённо всё из чего-то состоит. Элементарные кирпичики – вот что интересно. '''Евгений Балдин''' продолжает уроки рисования.''<br />
<br />
Объяснять компьютеру что Вы хотите сделать гораздо сложнее, чем нарисовать самому. Компьютеру надо объяснять<br />
абсолютно всё – телепатические способности у машин на<br />
текущий момент отсутствуют. Но, объяснив один раз, все похожие действия выполняются путём небольшой модификации уже готовых инструкций. В результате, потраченное на объяснение время себя полностью<br />
оправдывает, правда, при этом требуются дополнительные «мозговые<br />
усилия».<br />
<br />
=== Рисуем по точкам ===<br />
Первое, что надо сделать перед созданием нового рисунка, это сделать<br />
его набросок на миллиметровке. Допустим, необходимо нарисовать<br />
черепашку:<br />
<br />
[[Изображение:Img 77 96 1.png|Img 77 96 1.png]]<br />
<br />
Делаем это, как можем, а затем очень подробно объясняем компьютеру, что мы хотим от него. Инструкции очень простые:<br />
<source lang="latex"><br />
%Файл coord.mp<br />
%Черепашка<br />
beginfig(1) ;<br />
numeric u;u:=5mm;<br />
draw (-5u,0u){dir 90}..{dir 0}(0,3.5u){dir0}..<br />
{dir -90}(5u,0){dir -90}..{dir 180}(0u,-3.5u){dir 180}..<br />
{dir 90}cycle withpen pencircle scaled 0.4u;<br />
draw (4.5u,1.5u)..(7u,1.5u)..(8u,0u)..(7u,-1.5u)..<br />
(4.5u,-1.5u) withpen pencircle scaled 0.4u;<br />
draw (6.5u,.5u) withpen pencircle scaled 0.8u;<br />
draw (6.5u,-.5u) withpen pencircle scaled 0.8u;<br />
draw (-3.5u,-2.5u)..(-4.2u,-4.5u)..(-3.7u,-5u)..<br />
(-2.4u,-4u)..(-2u,-3.5u) withpen pencircle scaled 0.4u;<br />
draw (-3.5u,2.5u)..(-4.2u,4.5u)..(-3.7u,5u)..(-2.4u,4u)..<br />
(-2u,3.5u) withpen pencircle scaled 0.4u;<br />
draw (3.5u,-2.5u)..(4.2u,-4.5u)..(3.7u,-5u)..(2.4u,-4u)..<br />
(2u,-3.5u) withpen pencircle scaled 0.4u;<br />
draw (3.5u,2.5u)..(4.2u,4.5u)..(3.7u,5u)..(2.4u,4u)..<br />
(2u,3.5u) withpen pencircle scaled 0.4u;<br />
draw (-5u,0.5u)--(-6.5u,0)--(-5u,-0.5u)<br />
withpen pencircle scaled 0.4u;<br />
draw (0u,2.5u)..(0,0u)..(0u,-2.5u)<br />
withpen pencircle scaled 0.3u;<br />
draw (-2.4u,2.4u)..(-2u,0u)..(-2.4u,-2.4u)<br />
withpen pencircle scaled 0.3u;<br />
draw (2.4u,2.4u)..(2u,0u)..(2.4u,-2.4u)<br />
withpen pencircle scaled 0.3u;<br />
draw (-3u,1.5u)..(0,1u)..(3u,1.5u)<br />
withpen pencircle scaled 0.3u;<br />
draw (-3u,-1.5u)..(0,-1u)..(3u,-1.5u)<br />
withpen pencircle scaled 0.3u;<br />
endfig ;<br />
</source><br />
Рисуем по точкам, используя команду draw. Каждая точка задаётся<br />
парой чисел «(x,y)» – x и y координаты соответственно. Точки соединяются либо прямыми линиями «--», либо кривыми «..». Кривые, соединяющие точки описываются полиномом Бернштейна третьей степени<br />
(Сергей Николаевич Бернштейн 1912). Часто их называют кубическими<br />
кривыми Безье (Piere Bezier 1960).<br />
<br />
Компьютер обязательно должен знать каким пером (withpen<br />
pencircle) и какой толщины (scaled 0.3u) рисуется текущая линия.<br />
Такие объяснения могут показаться избыточными, но всегда можно скопировать предыдущую инструкцию и поправить её под свои нужды, а<br />
многословность облегчает чтение кода.<br />
<br />
Далее этот рисунок можно использовать многократно, например,<br />
для составления какого-либо узора:<br />
<br />
<br />
<br />
Обратите внимание, что почти все числовые значения представляют<br />
из себя коэффициент умноженный на параметр, например, «2.4u».<br />
Параметру «u» можно присвоить числовое значение в миллиметрах<br />
(параметр «mm»). Есть несколько определённых по умолчанию значений длины, например, «cm» соответствует сантиметру.<br />
<br />
При программировании на Meta по мере возможности используйте<br />
параметрические зависимости. Нет необходимости «прибивать что-то<br />
гвоздями». В данном случае наличие параметра позволяет легко изменить масштаб рисунка:<br />
<br />
<br />
<br />
Очевидно, что в предложенном решении одного параметра мало,<br />
так как «u» контролирует не только геометрические размеры, но и размеры пера.<br />
Точки, также можно представить как переменные, имеющие тип pair:<br />
<source lang="latex"><br />
numeric u;<br />
u:=0.5mm;<br />
pair A,B;<br />
A:=(1u,2u);B=(5u,10u);<br />
draw A--B withpen pencircle scaled 0.3u;<br />
</source><br />
Следует обратить внимание, что знак присвоения «:=» в случае<br />
переменной A и знак равенства в случае переменной B здесь действует<br />
одинаково. Отличия возникают, когда используется уникальная способность Meta воспринимать и решать систему линейных уравнений. В<br />
дальнейшем в объяснениях буквы A и B будут использоваться как переменные типа точка.<br />
<br />
Meta позволяет создавать свои типы перьев, но для рисования простых рисунков использовать что-то отличное от круглого пера (pencircle)<br />
нет особой необходимости. Если вам хочется расширить ваши познания<br />
в этой области, то обратитесь к любому руководству по MetaFont или<br />
MetaPost. Нет необходимости каждый раз указывать каким пером следует рисовать. Достаточно выбрать какое-либо перо по умолчанию с<br />
помощью команды pickup, например, так:<br />
pickup pencircle scaled 0.2u;<br />
<br />
=== Пути ===<br />
[[Изображение:Img 77 97 3.png|right|frame]]<br />
Инструкции draw позволяет рисовать сплошную линию.<br />
На её основе в MetaPost создана команда для рисования стрелки drawarrow. Воспользуемся<br />
ей для изображения суммы векторов<br />
(рис. справа)<br />
<br />
Кроме непосредственно команды<br />
draw, в этом рисунке необходимо<br />
использовать команду для вставки<br />
текстовых меток label, которая<br />
будет подробно разобрана<br />
позже:<br />
<source lang="latex"><br />
%Файл path.mp<br />
%Закон Ньютона - векторная сумма сил<br />
beginfig(1);<br />
numeric u;<br />
u := 1mm;<br />
drawarrow (0,0)--(20u,30u) withpen pencircle scaled 0.3u;<br />
label.ulft(btex \(\vec{F}_1\) etex,1/2[(0,0),(20u,30u)]);<br />
drawarrow (20u,30u)--(40u,30u) withpen pencircle scaled 0.3u;<br />
label.top(btex \(\vec{F}_2\) etex,1/2[(20u,30u),(40u,30u)]);<br />
drawarrow (40u,30u)--(50u,10u) withpen pencircle scaled 0.3u;<br />
label.urt(btex \(\vec{F}_3\) etex,1/2[(40u,30u),(50u,10u)]);<br />
drawarrow (50u,10u)--(35u,15u) withpen pencircle scaled 0.3u;<br />
label.llft(btex \(\vec{F}_4\) etex,1/2[(50u,10u),(35u,15u)]);<br />
drawarrow (0u,0u)--(35u,15u) withpen pencircle scaled 0.8u;<br />
drawarrow (0u,0u)--(35u,15u) withpen pencircle scaled 0.3u<br />
withcolor white;<br />
draw (0u,0u) withpen pencircle scaled 2u ;<br />
label.bot(btex \(\vec{F}_1+\vec{F}_2+\vec{F}_3+\vec{F}_4\) etex,<br />
1/2[(35u,15u),(0u,0u)]) rotatedaround<br />
(1/2[(35u,15u),(0u,0u)],angle(35,15));<br />
endfig;<br />
</source><br />
Конструкция вида «1/2[A,B]» имеет тип pair и равна точке, расположенной ровно по середине между точками A и B. Точно так же можно<br />
выбрать точку на линии AB, но делящую эту линию в отношении 1 к 2:<br />
«1/3[A,B]», или 1 к 4: «0.2[A,B]»<br />
<br />
Кроме drawarrow в MetaPost определена команда drawdblarrow,<br />
которая рисует кончик стрелки на обоих концах пути.<br />
<br />
Команды, типа draw, работают с объектами path (путь). Путь – это<br />
набор из точек (тип pair) с описанием того, как эти точки соединяются<br />
друг с другом. Минимальный путь – это одна точка. При рисовании такого пути на рисунке остаётся отпечаток в форме пера. Во всех приведённых здесь примерах перо имеет круглую форму pencircle, поэтому в<br />
этом случае возникает просто точка. Часто бывает удобно создать переменную типа path:<br />
<source lang="latex"><br />
%Файл path.mp<br />
%Рис к 1.6.8 б) нить пропущенная через изогнутую трубу<br />
beginfig(2) ;<br />
numeric u;<br />
u = 0.8mm;<br />
path p;<br />
p:=(5u,0u)--(20u,0u){dir 0}..(20u,20u)..<br />
{dir 0}(20u,0u)--(35u,0u);<br />
cutdraw p withpen pencircle scaled 1.5u;<br />
draw p withpen pencircle scaled 1u withcolor white;<br />
draw p withpen pencircle scaled 0.3u<br />
dashed evenly scaled 1/2u;<br />
drawarrow (-10u,0u)--(0u,0u)<br />
withpen pencircle scaled 0.3u;<br />
draw (-10u,0u) withpen pencircle scaled 1u;<br />
draw (-10u,0u)--(5u,0u) withpen pencircle scaled 0.3u;<br />
drawarrow (30u,10u)--(50u,10u)<br />
withpen pencircle scaled 0.3u;<br />
draw (30u,10u) withpen pencircle scaled 1u;<br />
draw (35u,0u)--(45u,0u) withpen pencircle scaled 0.3u;<br />
label.top(btex \(\vec{v}\) etex,(-5u,0u));<br />
label.top(btex \(2\vec{v}\) etex,(40u,10u));<br />
endfig;<br />
</source><br />
В данном примере требовалось изобразить трубу изогнутую буквой<br />
«О», сквозь которую продета нить. Для этого определяем путь «p».<br />
Затем этот путь используется в трёх командах как переменная: рисуется<br />
толстая чёрная труба шириной «1.5u», внутри неё рисуется более тонкая шириной «1u» белого цвета (withcolor white) – получается полая<br />
труба, а затем внутри трубы отрисовывается нить, причём нить рисуется<br />
пунктиром (dashed evenly).<br />
<br />
[[Изображение:Img 77 98 1.png|Img 77 98 1.png]]<br />
<br />
Первый и последний участок изогнутой трубы прямые линии, поэтому соединение с первой и последней точкой описывается как «--».<br />
Чтобы нарисовать кривую, похожую на круг, достаточно двух точек:<br />
<source lang="latex"><br />
numeric u,R; u=1mm;R=10u;<br />
pair A,B; A:=(-R,0);B:=(0,R);<br />
path P; P:=A..B..cycle;<br />
draw P withpen pencircle 1u;<br />
</source><br />
В этом примере определяются две точки A и B. Путь P строится по<br />
этим точкам, при этом выходя из точки A, мы попадаем в точку B, а<br />
затем снова в точку A: команда cycle позволяет создавать замкнутую<br />
кривую. Настройки Meta по умолчанию таковы, что получившаяся кривая достаточно хорошо совпадает с точной окружностью. Чтобы лучше<br />
совпадать с окружностью нужно больше «опорных» точек. Для обычных<br />
рисунков хватает точности построения по двум точкам, но всё-таки надо<br />
осознавать, что отличие есть.<br />
<br />
Для уточнения пути в некоторых точках можно указать под каким<br />
углом должна подходить кривая к этой точке. Инструкция вида «dir »<br />
если она находится перед точкой, указывает под каким углом кривая<br />
должна подходить, а после точки – под каким углом кривая должна уходить. – угол в градусах от оси абсцисс.<br />
<br />
Для указания направления можно так же воспользоваться сокращениями left, right, up и down, которые означают, соответственно, влево,<br />
вправо, вверх и вниз.<br />
<br />
Существует несколько типов соединений между точками. Два из них<br />
«..» и «--» мы уже изучили. Из других типов полезен тип «&» – «сращивание» (объединение двух путей без влияния друг на друга) и «---» –<br />
«натянутая» линия (то же, что и «--», но влияет на соседние соединительные участки).<br />
<br />
Обратите внимания на команду cutdraw. Так как MetaPost рисует с<br />
помощью перьев, то в случае круглого пера (pencircle), концы линий<br />
также округлые. В случае, когда необходимо «обрубить» концы, избавиться от округлостей на концах линий, и используется эта инструкция.<br />
Следует отметить, что эта команда «подчистки» концов использует другую более общую команду<br />
cutoff(«точка»,«угол»);<br />
<br />
=== Вставка текста ===<br />
MetaFont был создан как специализированный инструмент для создания шрифтов. MetaPost создавался как инструмент для рисования<br />
любых изображений, поэтому в него был встроен довольно мощный<br />
механизм вставки текста. Работая совместно с LaTeX, MetaPost позволяет использовать всю мощь текстового процессора для создания надписей. Кроме всего прочего, иметь в рисунках те же шрифты, что и в тексте<br />
просто красиво.<br />
<br />
Разберём это на примере треугольник Паскаля – треугольной числовой таблицы для составления биномиальных коэффициентов. По боковым сторонам треугольника стоят единицы, внутри треугольника числа<br />
образуются сложением двух чисел, стоящих над данным:<br />
<br />
[[Изображение:Img 77 98 2.png|Img 77 98 2.png]]<br />
<br />
Так как нижние строки из-за увеличения разрядности чисел расползались, то для представления появилась необходимость уменьшить их<br />
геометрические размеры. В коде так же использовались циклы, которые<br />
будут разобраны позже. Команда show позволяет отлаживать код,<br />
выдавая значения переменных на экран во время компиляции рисунка с<br />
помощью mpost.<br />
<source lang="latex"><br />
%Файл pic.mp<br />
%Треугольник Паскаля<br />
beginfig(5) ;<br />
numeric u;<br />
u = 1.mm;<br />
numeric dy,dx,x,y,n[ ][ ],i,j,sy,ds,nlast;<br />
dy:=5u;dx:=5u;x=0;y=0;<br />
ds=0.04;sy=0.032;nlast=14;<br />
picture z;<br />
for i:=0 upto nlast:<br />
dy:=dy*(1-sy);<br />
y:=y-dy;<br />
for j:=0 upto i:<br />
if (j=0) or (j=i):<br />
n[i][j]:=1;<br />
else:<br />
n[i][j]:=n[i-1][j-1]+n[i-1][j];<br />
fi<br />
% show i,j,n[i][j];<br />
z:=thelabel(decimal(n[i][j]),(0,0));<br />
x:=dx*(j-i/2);<br />
label(z scaled (1-ds*i),(x,y));<br />
endfor<br />
z:=thelabel.lft(decimal(i)&”:”,(0,0));<br />
label(z scaled (1-ds*i),(dx*(-nlast/2-1),y));<br />
endfor<br />
label.rt(btex \((a+b)^n=\) etex,(5u,-5u));<br />
label.rt(btex \(=\sum C^k_na^kb^{n-k}\) etex,<br />
(10u,-10u));<br />
label.lft(btex Треугольник Паскаля etex<br />
rotated 56,(-5u,-20u));<br />
endfig ;<br />
</source><br />
Команда decimal делает из переменной типа numeric строку. Две<br />
строки можно слить с помощью операнда «&».<br />
<br />
Для того чтобы вставить текстовую метку в рисунок, необходимо<br />
получить на входе текстовую строку, которую, возможно, надо будет<br />
преобразовать с помощью LaTeX, и точку где эту строку следует<br />
расположить:<br />
label(“text string”,A);<br />
Полезно ещё уточнить с какой стороны от указанной точки расположить текстовую метку. Уточнение производится с помощью суффикса,<br />
который добавляется макросу label через точку. Всего существует<br />
восемь стандартных суффиксов: «.rt» – расположить справа, «.lft» –<br />
слева, «.top» – сверху, «.bot» – снизу, «.llft» – расположить снизу и<br />
слева по диагонали, «.lrt» – снизу и справа, «.ulft» – сверху и слева,<br />
«.urt» – сверху и справа.<br />
<br />
Если label передаётся просто строка (тип string), то текст обрабатывается силами MetaPost и всё, что выходит за пределы ASCII-таблицы с<br />
большой вероятностью не отобразится. Для того чтобы строка была<br />
обработана LaTeX, необходимо указать это с помощью разделителей<br />
btex и etex. Строка между этими разделителями обрабатывается LaTeX,<br />
при этом в качестве заголовка используются инструкции перечисленные<br />
в начале mp-файла между verbatimtex и etex. Таким образом можно<br />
использовать кириллицу и любую конструкцию, которую понимает<br />
LaTeX.<br />
<br />
В некоторых случаях команде label удобно передавать не строку, а<br />
картинку picture. В нашем случае это было необходимо, так как надпись<br />
надо было масштабировать. Объект picture представляет из себя совокупность примитивов типа путей и точек, поэтому его можно трансформировать. Команда thelabel создаёт такую картинку. Объект, заключённый между btex и etex так же является картинкой.<br />
<br />
=== Заливка ===<br />
[[Изображение:Img 77 99 1.png|right|frame]]<br />
Кроме рисования кривых часто бывает необходимо закрасить какую-либо замкнутую область.<br />
Для этого сущест-<br />
вует команда fill. На<br />
вход команды fill<br />
подаётся объект типа<br />
path, при этом путь<br />
должен быть замкну-<br />
тым, то есть оканчи-<br />
ваться командой cycle. Команда cycle автоматически замыкает<br />
кривую.<br />
<source lang="latex"><br />
%Файл pic.mp<br />
%Рис к 1.6.20 а) струя под углом, разбивающаяся о пол<br />
beginfig(10) ;<br />
numeric u;<br />
u = 1mm;<br />
numeric st;st:=u/(sqrt 3);<br />
path p;<br />
p:=(0,10u)--(18u,10u){dir 0}..{dir 30}(22u,10u+2st)--<br />
(50u,10u+30st){dir -90}..{dir -90}(60u,5u+20st)--<br />
(42u,5u+2st){dir -150}..{dir 0}(42u,5u)--<br />
(60u,5u){dir -120}..{dir -120}(60u,0u)--<br />
(0u,0u){dir 60}..{dir 60}cycle;<br />
fill p withcolor 0.8 white;<br />
draw ((40u,5u)+10u*dir 30){dir -60}..{dir -90}(50u,5u);<br />
label(btex \(\alpha\) etex,(53u,8u));<br />
draw (0u,0)--(60u,0u) withpen pencircle scaled 0.8u;<br />
numeric R,alpha;R:=12u;alpha=30;<br />
drawarrow (25u+25u,5u+25st)--<br />
((25u+25u,5u+25st)-R*dir alpha)<br />
withpen pencircle scaled 0.6u;<br />
label.ulft(btex \(\vec{v}\) etex,1/2[(25u+25u,5u+25st),<br />
((25u+25u,5u+25st)-R*dir alpha)]);<br />
drawarrow (20u,5u)--(20u-R,5u)<br />
withpen pencircle scaled 0.6u;<br />
label.top(btex \(\vec{v}\) etex,(20u-R/2,5u));<br />
drawarrow (45u,2.5u)--(45u+R,2.5u)<br />
withpen pencircle scaled 0.6u;<br />
label.lft(btex \(\vec{v}\) etex,(45u,2.5u));<br />
endfig ;<br />
</source><br />
Для fill существует противоположная по смыслу команда unfill,<br />
которая, соответственно, убирает заливку в выбранной окрестности.<br />
Если вы планируете использовать эти команды, то изучите соответствующий раздел «Всё про METAFONT» Кнута, так как влияние этих команд<br />
друг на друга не совсем тривиально. Дело в том, что при наложении<br />
друг на друга двух заливок в месте пересечения образуется «двойной<br />
слой краски» и для того чтобы убрать его необходимо дважды вызывать<br />
команду unfill. Команда unfill действует схоже, только число «слоёв<br />
краски» становится отрицательным. Для сведения всё к ситуации когда<br />
краска либо есть (один слой), либо её нет используется команда<br />
«выравнивания» cullit.<br />
<br />
Обратите внимание, что точку можно задать не только парой чисел:<br />
«(x,y)» – Декартова система координат, но и радиусом с направлением<br />
«R*dir » – полярные координаты.<br />
<br />
=== Цвета ===<br />
Ещё одно важное отличие MetaPost от MetaFont – это наличие цвета.<br />
Работа с цветом обычно сложнее, чем работа с чёрно-белым рисунком.<br />
До сих пор процедура переноса электронного цветного рисунка на бумагу не является тривиальной. Но время идёт, и цветные принтеры становятся всё доступней. Кроме того, хорошие чисто электронные тексты, не<br />
привязанные к твёрдой копии, так же становятся весьма распространёнными. Поэтому если необходимо, то следует пользоваться цветом,<br />
естественно, если вы знаете что делать. В случае простого рисунка цвет,<br />
как правило, только отвлекает.<br />
<br />
В MetaPost управление цветом реализовано на довольно низком<br />
уровне. Цвет определяется объектом типа color и представляет из себя<br />
тройку чисел принимающих значение от 0 до 1: «(r,g,b)», где r соответствует красной, g – зелёной, а b – голубой компоненте. Существует<br />
пять предопределённых цветовых констант: red (1,0,0), green (0,1,0),<br />
blue (0,0,1), а так же black (1,1,1) и white (0,0,0).<br />
<br />
Нарисовать объект, выбранным цветом, можно с помощью инструкции withcolor за которой следует сам цвет. Цвета можно складывать,<br />
вычитать, умножать на число. Пользуясь базовыми определениями<br />
можно создать более сложные объекта. Например как этот спектр:<br />
<br />
[[Изображение:Img 77 99 2.jpg|Img 77 99 2.jpg]]<br />
<br />
Код, создающий эту картинку, далёк от совершенства, но он прост,<br />
и его можно улучшать в случае необходимости.<br />
<source lang="latex"><br />
%Файл colors.mp<br />
def spectrline(expr ic,c,l,w,dw) =<br />
begingroup<br />
save i,ifirst,ilast,istep,icc;<br />
color icc;<br />
if (ic>0):istep:=1;ifirst:=0;ilast=255;<br />
else:istep:=-1;ifirst=0;ilast:=-255; fi;<br />
if (abs(ic)=1):icc:=red;fi;<br />
if (abs(ic)=2):icc:=green;fi;<br />
if (abs(ic)=3):icc:=blue;fi;<br />
for i:=ifirst step istep until ilast:<br />
draw ((0u,0u)--(0u,l)) shifted (w+(dw/2*abs(i),0))<br />
withpen pencircle scaled dw withcolor (c+i/255*icc);<br />
endfor;<br />
endgroup;<br />
enddef;<br />
%спектр<br />
beginfig(1) ;<br />
color current;<br />
u:=1mm;w:=200u;dw:=w/512;l:=5u;<br />
current:=(1,0,0);<br />
spectrline(2,current,l,(1/4w,0u),dw)<br />
current:=(1,1,0);<br />
spectrline(-1,current,l,(1/2w,0u),dw)<br />
current:=(0,1,0);<br />
spectrline(3,current,l,(3/4w,0u),dw)<br />
current:=(0,1,1);<br />
spectrline(-2,current,l,(w,0u),dw)<br />
endfig ;<br />
</source><br />
В примере используется макрос spectrline для уменьшения<br />
размера кода.</div>Yaleks