Это многостраничный печатный вид этого раздела. Нажмите что бы печатать.

Вернуться к обычному просмотру страницы.

Графический пакет TIKZ для Latex

Дружелюбный функционал для полной графики в Latex. Картинки, иконки, графики и пр.

Дружелюбный функционал для полной графики в Latex. Картинки, иконки, графики и пр. Очень мощный пакет в котором можно нарисовать все.

Установка пакета

\usepackage{tikz}

Использование пакета

Окружение {tikzpicture} или команды \tikzpicture и \endtikzpicture

Использование дополнительных библиотек

\documentclass{article} % say

\usepackage{tikz}
\usetikzlibrary{arrows.meta,decorations.pathmorphing,backgrounds,positioning,fit,petri}

\begin{document}
\begin{tikzpicture}
  \draw (0,0) -- (1,1);
\end{tikzpicture}
\end{document}

1 - Дисплей для руководства пользователя

Практическая задача в LATEX по созданию настраиваемого дисплея при описании руководства пользователя

Примеры использования поисковых запросов POSIX

Постановка задачи

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

Дисплей имеет 22 знака в ширину и 7 строк.

disp1

Необходимо создать однострочную команду в Latex для удобного заполнения параметров дисплея и вывода графического изображения в любое место на странице документации.

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

  1. Дисплей должен отражать текстовые строки заглавными и строчными буквами латинского алфавита.
  2. На дисплее должны отображаться арабские цифры
  3. Графические элементы применяемые на дисплее:
    • аккумулятор
    • антенна
    • уровень сигнала
    • замок
    • линия под статусной строкой
    • линия середины экрана
  4. Типы строк дисплея:
    • строка с текстом выровненным по левому краю до 22 символов
    • строка подсвеченная прямоугольником с инвертированным цветом символов
    • строка с текстом выровненным по середине экрана
    • строка с текстом в две колонки
    • строка без текста
  5. Типы строк статусной строки
    • режим 1 с аккумулятором и антенной
    • режим 2 с аккумулятором
    • режим 3 текст
  6. Отдельный режим отображения средней линии на дисплее
  7. Режим вывода картинки в правой части дисплея
  8. Обозначение подсвеченных информационных кнопок в нижней части дисплея
  9. Информационный режим дисплея

Решение задачи

  1. Использование издательской системы Latex
  2. Загрузка специального графического пакета TIKZ
  3. Настройка графических примитивов с помощью библиотеки TIKZ для использования в строках
  4. Программирование Tex для создания простых команд для указания в строках дисплея выводимой информации
  5. Создание библиотеки с возможностью многократного использования дисплея в различных документах

Описание решения

\definecolor{disp}{HTML}{000041} % цвет дисплея
\definecolor{textdisp}{HTML}{f0ffff} %цвет текста дисплея

\tikzset{%настройки стиля шрифта для вывода символов на терминал дисплея
terminal/.style = {text=textdisp,inner sep=0pt, anchor=west,font=\fontfamily{cmtt}\fontsize{10}{10}\selectfont}}

Создание графических элементов

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Аккумулятор
%%%%%%%%%%%%%
\tikzset{
accum/.pic={[font=\ttfamily]
\path (.5,.35) coordinate(acbl) ++(1,0) coordinate(acbr)
    ++(0,.6) coordinate(actr) ++(-1,0) coordinate(actl);
\draw[pic actions,thick] (acbl) -- (acbr) -- ($(acbr)!.2!(actr)$)-- ++(1pt,0) |- ($(acbr)!.8!(actr)$) -- (actr) -- (actl) -- cycle; 
\fill[pic actions] (acbl) rectangle ($(actl)!#1!(actr)$);
}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Антенна
%%%%%%%%%%%%%
\tikzset{
antena/.pic={
 \path
    (0,.35) coordinate(anbot) ++(0,.6) coordinate(antop)
    +(-.3,0) coordinate(antl) +(.3,0) coordinate(antr);
\draw[pic actions,thick] (anbot) -- (antop) 
                 ($(anbot)!.5!(antop)$)--(antl)
                 ($(anbot)!.5!(antop)$)--(antr);
\path[pic actions] (anbot) ++(.4,.3) node[terminal]{100\%};
}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Уровень сигнала
%%%%%%%%%%%%%
\tikzset{
lsignal/.pic={
\coordinate (a) at (.35,.35);
\draw[pic actions,thick] (a) foreach \x in {1,...,#1} {+(.\x,0) -- +(.\x,.\x)};
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%замок LOCK
%%%%%%%%%%%
\tikzset{
lockc/.pic={
\path (0,.15) coordinate (bl) +(.4,0) coordinate (br) +(.4,.3) coordinate (tr) +(0,.3) coordinate (tl);
\draw[pic actions,thick,fill] (bl) rectangle (tr);
\draw[thick,out=90,in=90,distance=.3em] (tl) to (tr);
}
}

Настройка типов строк

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%активная строка
%%%%%%%%%%%%%
\tikzset{
araw/.pic={%отображает строку подсвеченной как активную без текста
 \path
    (.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
    ++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\fill[white!95,opacity=.7] (arbl) rectangle (artr); 
},
arawp/.pic={%выводит текст без подсветки
 \path
    (0.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
    ++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\node[terminal,text width=5.6em] at ($(arbl)!.5!(artl)$) {#1};%обычная строка
},
arawa/.pic={%выводит текст в активной строке
 \path
    (0.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
    ++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\node[terminal,text width=5.6em,text=disp] at ($(arbl)!.5!(artl)$) {#1} [fill=white!95,opacity=.7] (arbl) rectangle (artr);%обычная строка
},
lbut/.pic={%выводит текст в левой функциональной кнопке в нижнем ряду
 \path
    (.4,.2) coordinate(arbl) ++(5.7,0) coordinate(arbr)
    ++(0,.9) coordinate(artr) ++(-5.7,0) coordinate(artl);
\node[terminal,text=disp,anchor=center] at ($(arbl)!.5!(artr)$) {#1} [fill=white!95,opacity=.7] (arbl) rectangle (artr) ;
},
rbut/.pic={%выводит текст в правой функциональной кнопке в нижнем ряду
 \path
    (6.3,.2) coordinate(arbl) ++(5.7,0) coordinate(arbr)
    ++(0,.9) coordinate(artr) ++(-5.7,0) coordinate(artl);
\node[terminal,text=disp,anchor=center] at ($(arbl)!.5!(artr)$) {#1} [fill=white!95,opacity=.7] (arbl) rectangle (artr) ;
},
rawc/.pic={%строка через весь дисплей с выделенной активностью и текстом по центру
 \path
    (.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
    ++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\node[terminal,text=disp,anchor=center] at ($(arbl)!.5!(artr)$) {#1} [fill=white!95,opacity=.7] (arbl) rectangle (artr);
}
}

Оформление контура дисплея

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Дисплей маленького экрана
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tikzset{
display/.pic={%рамка для дисплея
\path[terminal] (0,.2) coordinate (dtl) ++(12.4,0) coordinate (dtr)  ++(0,-7.2) coordinate (dbr)  ++(-12.4,0) coordinate (dbl);
\draw[thick,gray!20,fill=disp,rounded corners] (dbl) rectangle (dtr);
}
}

Создание стилей строки статуса для различных режимов

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Строка состояния пульта
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tikzset{
pultmain/.pic={% режим 1 с произвольным текстом, часами и аккумулятором заголовок дисплея пульт на вход отправим text 
\path
    (0.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
    ++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\path ($(arbl)!.5!(artl)$) node[terminal] {#1} +(4,0) node[terminal] {08:20:46};
\pic[textdisp] at (10.4,0) {accum=.4};
\draw[textdisp,thick] (arbl.south west)--(arbr.south east);
},
pultfree/.pic={%заголовок дисплея пульт на вход отправим свободную строку
\path
    (0.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
    ++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\node[terminal,text width=10.5em] at ($(arbl)!.5!(artl)$) {#1};%обычная строка
\pic[textdisp] at (10.4,0) {accum=.4};%\fill[red](arbl.south west)circle (1pt);
\draw[textdisp,thick] (arbl.south west)--(arbr.south east);
},
priemfree/.pic={%заголовок дисплея приемника на вход отправим свободную строку
\path
    (0.4,.2) coordinate(arbl) ++(11.6,0) coordinate(arbr)
    ++(0,.9) coordinate(artr) ++(-11.6,0) coordinate(artl);
\pic[textdisp]{accum=.5};\pic[textdisp] at (9.4,0) {antena};
\draw[textdisp,thick] (arbl.south west)--(arbr.south east);
},
rawg/.pic={\node[terminal,text width=5.6em] {#1};%обычная строка
},
rawa/.pic={\pic{arow} node[terminal,text width=5.6em,text=disp] {#1};%активная строка
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%шаблон дисплея создаем команду \dispm с 8-ю входными параметрами
\def\dispm#1#2#3#4#5#6#7#8{
\begin{tikzpicture}[x=10pt,y=10pt,node distance=10pt]%установить масштаб отображения
\pic{display};%вывести фон дисплея
\pic at (0,-1) {#1};%строка состояния 
\pic at (0,-2) {#2};%вторая строка
\pic at (0,-3) {#3};%третья строка
\pic at (0,-4) {#4};%четвертая строка
\pic at (0,-5) {#5};%пятая строка
\pic at (0,-6) {#6};%шестая строка
\path (0,-7) pic{lbut=#7} pic{rbut=#8};%седьмая строка с кнопками состояния
\draw[textdisp,thick] (6.2,-.9) -- (6.2,-5.9);%линия по центру экрана вертикальная
\end{tikzpicture}
}

% \dispm
% {}%1-я строка значения входного параметра (pultmain=text priemfree, pultfree=TEXT)
% {}%2-я строка (arawa=TEXT - активная строка, )
% {}%3-я строка (arawp=TEXT - пассивная строка,)
% {}%4-я строка (rawc=TEXT - активная строка с текстом по центру)
% {}%5-я строка
% {}%6-я строка
% {}{}%нижние кнопки в 7-й строке
% 

Пример

\dispm
{pultmain=ARM}%1-я строка (pultmain=ARM, pultmain=DISARM, priemfree, pultfree=TEXT)
{arawa=TEXT}%2-я строка (arawa=TEXT - активная строка, )
{arawp=TEXT}%3-я строка (arawp=TEXT - пассивная строка,)
{}%4-я строка (rawc=TEXT - активная строка с текстом по центру)
{}%5-я строка
{rawc=TEXT}%6-я строка
{MENU}{SERVICE}%нижние кнопки в 7-й строке

disp

2 - Foreach for Tex

Пакет pgffor для использования функции FOREACH в TEX

Установка

\usepackage{pgffor} % LATEX 
\input pgffor.tex % plain TEX 
\usemodule[pgffor] % ConTEXt

Отдельный пакет для самостоятельного использования в документах Tex и Latex

По умолчанию сам загружает пакет \tikz

Он определяет две новые команды: \foreach и \breakforeach.

Синтаксис

\foreach 〈variables〉 [〈options〉] in 〈list〉 〈commands〉

Простой пример

\def\mylist{1,2,3,0}  
\foreach \x in \mylist {[\x]}

Выдаст: [1][2][3][0]

Вложенные циклы

\begin{tikzpicture} 
\foreach \x in {0,1,2,3} 
	\foreach \y in {0,1,2,3} 
		{  
			\draw (\x,\y) circle (0.2cm); 
			\fill (\x,\y) circle (0.1cm); 
		}  
\end{tikzpicture}

Списки через многоточие

\foreach \x in {a,b,9,8,...,1,2,2.125,...,2.5} {\x, } 

выдаст:
a, b, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 2.125, 2.25, 2.375, 2.5,

\foreach \x in {2^1,2^...,2^7} {$\x$, } yields 21, 22, 23, 24, 25, 26, 27,
\foreach \x in {0\pi,0.5\pi,...\pi,3\pi} {$\x$, } yields 0π, 0.5π, 1π, 1.5π, 2π, 2.5π, 3π,  
\foreach \x in {A_1,..._1,H_1} {$\x$, } yields A1, B1, C1, D1, E1, F1, G1, H1,

Координаты для TIKZ

\tikz \foreach \position in {(0,0), (1,1), (2,0), (3,1)} 
\draw \position rectangle +(.25,.5);

Несколько переменных в цикле

\begin{tikzpicture}  
	\foreach \x/\xtext in {0,...,3,2.72 / e} 
	\draw (\x,0) node{$\xtext$}; 
\end{tikzpicture}

задан паттерн для получения переменных \x второе значение через /\xtext Отсутствие значений для второго параметра замещается первым значением.

\begin{tikzpicture}  % Let's draw circles at interesting points:  
\foreach \x / \y / \r in {0 / 0 / 2mm, 1 / 1 / 3mm, 2 / 0 / 1mm} 
\draw (\x,\y) circle (\r);  

% Same effect  
\foreach \center/\r in {{(0,0)/2mm}, {(1,1)/3mm}, {(2,0)/1mm}} \draw[yshift=2.5cm] \center circle (\r); 
\end{tikzpicture}

Угловые координаты

\begin{tikzpicture}[line cap=round,line width=3pt] 
\filldraw [fill=yellow!80!black] (0,0) circle (2cm);  

\foreach \angle / \label in 
{0/3, 30/2, 60/1, 90/12, 120/11, 150/10, 180/9, 210/8, 240/7, 270/6, 300/5, 330/4} 
	{  
		\draw[line width=1pt] (\angle:1.8cm) -- (\angle:2cm); 
		\draw (\angle:1.4cm) node{\textsf{\label}}; 
	}  
\foreach \angle in {0,90,180,270} 
	\draw[line width=2pt] (\angle:1.6cm) -- (\angle:2cm);  
	
	\draw (0,0) -- (120:0.8cm); % hour 
	\draw (0,0) -- (90:1cm); % minute 
\end{tikzpicture}%

clock

Параметры настройки оператора foreach

Описанные ниже ключи можно использовать в аргументе 〈options〉 команды \foreach. Все они имеют путь /pgf/foreach/, однако путь устанавливается автоматически при анализе 〈options〉, поэтому его не нужно указывать явно.

  • /pgf/foreach/var=〈variable〉 — Этот ключ обеспечивает альтернативный способ указания переменных: \foreach [var=\x,var=\y] аналогичен \foreach \x/\y.
  • /pgf/foreach/evaluate=〈variable〉 as 〈macro〉 using 〈formula〉 — Этот ключ позволяет оценивать переменную с помощью математического механизма. \foreach \x [evaluate=\x] in {2^0,2^...,2^8}{$\x$, } вернет 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0,

as

или \foreach \x [evaluate=\x as \xeval] in {2^0,2^...,2^8}{$\x=\xeval$, } значение будет помещено в \xeval

using

указывает формулу для вычисления

\tikz\foreach \x [evaluate=\x as \shade using \x*10] in {0,1,...,10} \node [fill=red!\shade!yellow, minimum size=0.65cm] at (\x,0) {\x};

  • /pgf/foreach/remember=〈variable〉 as 〈macro〉 (initially 〈value〉) — Этот ключ позволяет запомнить значение элемента, хранящееся в 〈variable〉, во время следующей итерации, сохраненное в 〈macro〉.
\foreach \x [remember=\x as \lastx (initially A)] in {B,...,H}{$\overrightarrow{\lastx\x}$, }
  • /pgf/foreach/count=〈macro〉 from 〈value〉 — считает номер итерации
\tikz[x=0.75cm,y=0.75cm]  
\foreach \x [count=\xi] in {a,...,e} 
\foreach \y [count=\yi] in {\x,...,e} 
	\node [draw, top color=white, bottom color=blue!50, minimum size=0.666cm] 
		at (\xi,-\yi) {$\mathstrut\x\y$};
  • /pgf/foreach/parse={〈boolean〉} — Если для этого ключа установлено значение true, верхняя граница цикла будет передана в \pgfmathparse.
  • /pgf/foreach/expand list={〈boolean〉} — Если для этого ключа установлено значение true, содержимое списка полностью раскрывается с помощью \edef перед дальнейшей обработкой.

\breakforeach

Если эта команда задана внутри команды \foreach, дальнейшее выполнение 〈команд〉 происходить не будет. Однако текущее выполнение 〈команд〉 продолжается в обычном режиме, поэтому, вероятно, лучше использовать эту команду только в конце команды \foreach.

3 - Key Management

Key Management из пакета pgfkeys, может использоваться самостоятельно или в составе пакета TIKZ, управляет ключами пользователя

Введение

В основном этот раздел описываю, так как его активно используют библиотеки TIKZ.

А в общем этот вопрос вполне удовлетворяет знание TEX и его внутренней кухни по созданию макросов и переменных.

Подключение пакета

\usepackage{pgfkeys}

Отличия pgfkeys от xkeyval

  • pgfkeys организует дерево ключей
  • pgfkeys не влияет на состояние стека
  • pgfkeys медленнее keyval
  • pgfkeys поддерживает стили (полезно для TIKZ)
  • pgfkeys поддерживает множественные аргументы
  • pgfkeys поддерживает обработчики обратного вызова и ошибок

Краткое описание механизма Key Management

Организован по принципу файловой системы Unix, корень и как дерево ветвление всех элементов

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

Основная команда \pgfkeys берет пару ключ и значение.

Для каждого будет выполнен код с параметром, переданным в

\pgfkeys{/my key=hallo,/your keys/main key=something\strange,
        key name without path=something else}

Сначала установим код для ключа: стр.1 и затем выполним его с переданным параметром стр.2

\pgfkeys{/my key/.code=The value is '#1'.}
\pgfkeys{/my key=hi!}

В качестве параметров может быть несколько значений (ключевое слово /.code 2 args=)

\pgfkeys{/my key/.code 2 args=The values are '#1' and '#2'.}
\pgfkeys{/my key={a1}{a2}}

Может быть значение по умолчанию: \pgfkeys{/my key/.default=hello}

Можно указать обязательное значение /.value required или запрещенное значение /.value forbidden, т.е. не нужно вводить значение.

Ключ /.cd - изменит путь. Т.е. после этого ключа, все остальные будут выполнять команды с новым путем.

\pgfkeys{/tikz/.cd,line width=1cm,line cap=round}

т.е. все остальные команды будут начинаться с /tikz/

Ключи могут вызывать выполнение других ключей.

\pgfkeys{/a/.code=(a:#1)}
\pgfkeys{/b/.code=(b:#1)}
\pgfkeys{/my style/.style={/a=foo,/b=bar,/a=#1}}
\pgfkeys{/my style=wow}

получим (a:foo)(b:bar)(a:wow)

Еще пример с созданием стиля tikz

\pgfkeys{/tikz/.style=/tikz/.cd}
\pgfkeys{tikz,line width=1cm,draw=red}

Описание синтаксиса pgfkeys

Если ключ начинается с / — это ключ с полным путем, если без слеша, то это не полный путь.

\pgfkeyssetvalue{⟨full key⟩}{⟨token text⟩}

Эта команда сохраняет token text в full key

Это не может быть частичным ключом.

\pgfkeyssetvalue{/my family/my key}{Hello, world!}%установить ключ
\pgfkeysvalueof{/my family/my key}%вывести ключ

\pgfkeyssetevalue{⟨full key⟩}{⟨token text⟩} — это тоже, но \edef версия

\pgfkeyslet{⟨full key⟩}{⟨macro⟩}

\def\helloworld{Hello, world!}
\pgfkeyslet{/my family/my key}{\helloworld}
\pgfkeysvalueof{/my family/my key}

позволяет устанавливать для ключа значение макроса, в нашем случае будет подставлено значение \helloworld

Недопустимо,чтобы ключ совпадал с \relax — relax это пустышка

\pgfkeysgetvalue{⟨full key⟩}{⟨macro⟩}

Извлекает токены из ключа

Если ключ не установлен то токен будет равен \relax

\pgfkeysvalueof{⟨full key⟩}

Возвращает значение ключа и вставляет его в текст

\pgfkeysifdefined{⟨full key⟩}{⟨if⟩}{⟨else⟩}

\pgfkeyssetvalue{/my family/my key}{Hello, world!}
\pgfkeysifdefined{/my family/my key}{yes}{no}

проверяет, если ключ был определен, то выведет значение if, если не определен, то else

\pgfkeys

Ключи могут выполнять следующие действия:

  • выполняет команду,хранящуюся в key с аргументом value
  • сохраняет значение value в ключе key
  • если имя ключа известный обработчик,тогда обработчик все сделает
  • если ключ неизвестный, то вызовется обработчик неизвестных ключей

Синтаксис команд

\pgfkeys{key=value,key,key={val1}{val2}}

Возможно указать:

  • key=value,
  • key,
  • key={val1}{val2}

или просто значение в {} если оно содержит запятые или спецсимволы

\pgfqkeys{⟨default path⟩}{⟨key list⟩}

Эта команда имеет тот же эффект,что и \pgfkeys{⟨default path⟩/.cd,⟨key list⟩}

\pgfkeysalso{⟨key list⟩}

в этой команде путь не изменяется

\pgfqkeysalso{⟨default path⟩}{⟨key list⟩}

вызывает с изменением пути

Команда привязанная к 1 символу

Наверно это удобно.

Так работают во всех nodes кавычки " которые заменяются текстом \label={}

Для этого нужно:

  • Установить /handlers/first char syntax=〈true or false〉 в true
  • Привязать к волшебному слову the character <символ> макрос, который будет выполняться
  • Объявить привязанный макрос
\pgfkeys{ 
/handlers/first char syntax=true, 
/handlers/first char syntax/the character "/.initial=\myquotemacro, 
/handlers/first char syntax/the character </.initial=\mypointedmacro, 
}  

\def\myquotemacro#1{Quoted: #1. } 
\def\mypointedmacro#1{Pointed: #1. }  

\ttfamily \pgfkeys{"foo", <bar>}

Дальше все параметры в "" будут переданы в макрос myquotemacro, а в <> в макрос mypointedmacro

Значение по умолчанию 〈key〉/.@def

  • если не нужно вводить значения, то можно указать key=\pgfkeysnovalue
  • проверяется наличие ключа: 〈key〉/.@def
  • если ключ есть, то он замещается в токене

Для установки по умолчанию значения используем команду: \pgfkeys{/my key/.default=hello}

Команды выполняемые в ключах 〈key〉/.@cmd

Во всем макросах в \pgf параметры должны заканчиваться значением \pgfeov т.е. что сделает на самом деле пакет \pgf

\usepackage {shortvrb} \MakeShortVerb {\|}  
\def\mystore#1+#2\pgfeov{\def\a{#1}\def\b{#2}} 
\pgfkeyslet{/my key/.@cmd}{\mystore} 
\pgfkeys{/my key=hello+world}  

получим:
|\a| is `\a', |\b| is `\b'.
т.е. 
\a is ‘hello’, \b is ‘world’.

Что предлагает пакет взамен

  • \pgfkeysdef{〈key〉}{〈code〉} — Эта команда временно определяет TEX-макрос со списком аргументов #1\pgfeov, а затем позволяет 〈key〉/.@cmd быть равным этому макросу.
  • \pgfkeysedef{〈key〉}{〈code〉} — аналогично, но работает, как edef
  • \pgfkeysdefnargs{〈key〉}{〈argument count〉}{〈code〉} — Эта команда работает аналогично \pgfkeysdef, но позволяет вам указать произвольное «счетчик аргументов» от 0 до 9 (включительно).
\usepackage {shortvrb} \MakeShortVerb {\|}  
\pgfkeysdefnargs{/my key}{2}{\def\a{#1}\def\b{#2}} 
\pgfkeys{/my key= {hello} {world}} 

|\a| is `\a', |\b| is `\b'
  • \pgfkeysedefnargs{〈key〉}{〈argument count〉}{〈code〉} — аналогично, но edef
  • \pgfkeysdefargs{〈key〉}{〈argument pattern〉}{〈code〉} — Эта команда работает аналогично \pgfkeysdefnargs, но позволяет вам предоставить произвольный «шаблон аргумента», а не просто несколько аргументов. \pgfkeysdefargs{/my key}{#1+#2}{\def\a{#1}\def\b{#2}}
  • \pgfkeysedefargs{〈key〉}{〈argument pattern〉}{〈code〉} — это его edef версия

Хранение значений в ключах

Если у ключа не определен key/.@cmd, то он будет просто хранить значение которое может быть задано командой \pgfkeyssetvalue

Обработчики ключей

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

\pgfkeysdef{/handlers/.my code}{\pgfkeysdef{\pgfkeyscurrentpath}{#1}}
  • Путь ключа, хранится в макросе \pgfkeyscurrentpath

  • Имя ключа, хранится в макросе \pgfkeyscurrentname

  • обработчик должен начинаться с .

  • /handler config=all|only existing|full or existing — Изменяет исходную конфигурацию использования обработчиков ключей.

  • /handler config/only existing/add exception={〈key handler name〉} — Позволяет добавлять исключения к существующей функции /handler config=only.

Обработка ключей, которые неизвестны

Для некоторых ключей не определен ни сам ключ, ни его подраздел .@cmd, ни обработчик. В этом случае проверяется, существует ли ключ 〈текущий путь〉/.unknown/.@cmd.

Т.к. он существует, то будет выполнена какая-то странная вещь, как он ее поймет.

Пути поиска и обрабатываемые ключи

Обработчики ключей

Теперь мы опишем, какие обработчики клавиш определены по умолчанию.

Обработчик пути

  • Key handler 〈key〉/.cd — Этот обработчик устанавливает путь по умолчанию 〈key〉. Обратите внимание, что путь по умолчанию сбрасывается в начале каждого вызова \pgfkeys и становится равным /.
\pgfkeys{/tikz/.cd,...}
  • Key handler 〈key〉/.is family — Этот обработчик настраивает такие вещи, что при выполнении 〈key〉 текущий путь устанавливается на 〈key〉.
\pgfkeys{/tikz/.is family} 
\pgfkeys{tikz,line width=1cm}

Установка по умолчанию

  • Key handler 〈key〉/.default=〈value〉 — Устанавливает значение по умолчанию 〈key〉 в 〈value〉. Это означает, что всякий раз, когда при вызове \pgfkeys не указывается значение, вместо него будет использоваться это 〈значение〉. \pgfkeys{/width/.default=1cm}
  • Key handler 〈key〉/.value required — Этот обработчик вызывает выдачу ключа /errors/value сообщения об ошибке всякий раз, когда 〈key〉 используется без значения. \pgfkeys{/width/.value required} Т.е. требует обязательно указать значение.
  • Key handler 〈key〉/.value forbidden — не будет выдавать сообщение об ошибке, если указано будет значение ключа

Определение кода ключа

  • Key handler 〈key〉/.code=〈code〉 — Этот обработчик выполняет \pgfkeysdef с параметрами 〈key〉 и 〈code〉.
  • Key handler 〈key〉/.ecode=〈code〉 — выполнит команду \pgfkeysedef
  • Key handler 〈key〉/.code 2 args=〈code〉 — с двумя аргументами
  • Key handler 〈key〉/.ecode 2 args=〈code〉 — с двумя аргументами edef
  • Key handler 〈key〉/.code n args={〈argument count〉}{〈code〉} — с n аргументами
  • Key handler 〈key〉/.ecode n args={〈argument count〉}{〈code〉} — с n аргументами edef
  • Key handler 〈key〉/.code args={〈argument pattern〉}{〈code〉} — с произвольным паттерном аргументов
  • Key handler 〈key〉/.ecode args={〈argument pattern〉}{〈code〉} — с произвольным паттерном аргументов edef
  • Key handler 〈key〉/.add code={〈prefix code〉}{〈append code〉} — Этот обработчик добавляет код к существующему ключу. 〈код префикса〉 добавляется к коду, хранящемуся в 〈key〉/.@cmd, в начале, 〈код добавления〉 добавляется к этому коду в конце.
\pgfkeys{/par indent/.code={\parindent=#1}} 
\newdimen\myparindent 
\pgfkeys{/par indent/.add code={}{\myparindent=#1}} 
...  
\pgfkeys{/par indent=1cm} % This will set both \p
  • Key handler 〈key〉/.prefix code=〈prefix code〉 — Этот обработчик является ярлыком для 〈key〉/.add code={〈prefix code〉}{}. То есть этот обработчик добавляет 〈префиксный код〉 в начало кода, хранящегося в 〈key〉/.@cmd.
  • Key handler 〈key〉/.append code=〈append code〉 — Этот обработчик является ярлыком для 〈key〉/.add code={}{〈append code〉}.

Определение стиля

  • Key handler 〈key〉/.style=〈key list〉 — Этот обработчик настраивает ситуацию таким образом, что всякий раз, когда 〈ключ〉=〈значение〉 встречается в списке ключей, вместо этого обрабатывается 〈список ключей〉, в котором каждое вхождение #1 заменено на 〈значение〉. Как всегда, если 〈значение〉 не указано, используется значение по умолчанию, если оно определено, или специальное значение \pgfkeysnovalue.
\pgfkeys{/par indent/.code={\parindent=#1}} 
\pgfkeys{/no indent/.style={/par indent=0pt}} 
\pgfkeys{/normal indent/.style={/par indent=2em}} 
\pgfkeys{/no indent} 
... 
\pgfkeys{/normal indent}
  • Key handler 〈key〉/.estyle=〈key list〉 — определяет стиль через edef
  • Key handler 〈key〉/.style 2 args=〈key list〉 — с двумя аргументами
  • Key handler 〈key〉/.estyle 2 args=〈key list〉 — с двумя аргументами edef
  • Key handler 〈key〉/.style n args={〈argument count〉}〈key list〉 — n аргументов
  • Key handler 〈key〉/.add style={〈prefix key list〉}{〈append key list〉} — добавить значение к стилю
  • Key handler 〈key〉/.style args={〈argument pattern〉}{〈key list〉} — стиль с произвольным паттерном
  • Key handler 〈key〉/.estyle args={〈argument pattern〉}{〈code〉} — стиль с произвольным паттерном edef
  • Key handler 〈key〉/.prefix style=〈prefix key list〉 — prefix style добавить
  • Key handler 〈key〉/.append style=〈append key list〉 — добавить стиль в конец

Определение ключей значений, макросов, if и выбора

Для некоторых клавиш код, который должен по ним выполняться, достаточно «специализирован».

  • Key handler 〈key〉/.initial=〈value〉 — Этот обработчик устанавливает значение 〈key〉 в 〈value〉. Обратите внимание, что никакие подразделы не задействованы. После использования этого обработчика, согласно правилам, регулирующим ключи, вы можете впоследствии изменить значение 〈key〉, просто написав 〈key〉=〈value〉. Таким образом, этот обработчик используется для установки начального значения ключа.
  • Key handler 〈key〉/.get=〈macro〉 — выведет содержимое ключа и поместит в \macro
  • Key handler 〈key〉/.add={〈prefix value〉}{〈append value〉} — добавит к ключу
  • Key handler 〈key〉/.prefix={〈prefix value〉} — добавит префикс
  • Key handler 〈key〉/.append={〈append value〉} — добавит суффикс
  • Key handler 〈key〉/.link=〈another key〉 — сделает ссылку на другой ключ
  • Key handler 〈key〉/.store in=〈macro〉 — это прямой аналог \def\macro{#1}
\pgfkeys{/text/.store in=\mytext}  
\def\a{world} \pgfkeys{/text=Hello \a!} 
\def\a{Gruffalo}
\mytext

выведет:
Hello Gruffalo!
  • Key handler 〈key〉/.estore in=〈macro〉 — тоже, только edef
  • Key handler 〈key〉/.is if=〈TEX-if name〉 — имитация if Tex
\newif\iftheworldisflat  
\pgfkeys{/flat world/.is if=theworldisflat} 
\pgfkeys{/flat world=false} 
\iftheworldisflat 
Flat \else Round? 
\fi
  • Key handler 〈key〉/.is choice — Этот обработчик настраивает ситуацию так, что запись 〈key〉=〈value〉 приведет к выполнению подраздела 〈key〉/〈value〉. Таким образом, каждый из возможных вариантов должен быть задан подразделом 〈key〉.
\pgfkeys{/line cap/.is choice} 
\pgfkeys{/line cap/round/.code={\pgfsetroundcap}} 
\pgfkeys{/line cap/butt/.code={\pgfsetbuttcap}} 
\pgfkeys{/line cap/rect/.code={\pgfsetrectcap}} 
\pgfkeys{/line cap/rectangle/.style={/line cap=rect}} 
... 
\draw [/line cap=butt] ...

Расширенные и множественные значения

  • Key handler 〈key〉/.expand once=〈value〉 — Этот обработчик расширяет 〈value〉 один раз (точнее, он выполняет команду \expandafter для первого токена 〈value〉), а затем обрабатывает полученный 〈result〉, как если бы вы написали 〈key〉=〈result〉.
  • Key handler 〈key〉/.expand twice=〈value〉 — дважды расширяет значение
  • Key handler 〈key〉/.expanded=〈value〉 — Этот обработчик полностью расширит 〈value〉 (с помощью \edef) перед обработкой 〈key〉=〈result〉.
  • Key handler 〈key〉/.evaluated=〈value〉 — Этот обработчик оценит 〈value〉 как математическое выражение с помощью \pgfmathparse и присвоит 〈key〉=\pgfmathresult.
  • Key handler 〈key〉/.list=〈comma-separated list of values〉 — Этот обработчик вызывает многократное использование ключа, а именно один раз для каждого элемента списка значений. Что-то вроде foreach

Обработчик с пересылкой значений

  • Key handler 〈key〉/.forward to=〈another key〉 — Этот обработчик заставляет 〈key〉 «пересылать» свой аргумент 〈другому ключу〉. При использовании 〈key〉 сначала будет выполнен ее обычный код. Затем значение (дополнительно) передается «другому ключу».
\pgfkeys{  
/a/.code=(a:#1), 
/b/.code=(b:#1), 
/b/.forward to=/a, 
/c/.forward to=/a 
}  
\pgfkeys{/b=1} \pgfkeys{/c=2}

выведет 
(b:1)(a:1) (a:2)
  • Key handler 〈key〉/.search also={〈path list〉} — Стиль, который устанавливает обработчик /.unknown в 〈key〉. Этот обработчик /.unknown затем будет искать неизвестные ключи по каждому пути, указанному в {〈списке путей〉}.

Обработчики для тестирования ключей

  • Key handler 〈key〉/.try=〈value〉 — Этот обработчик вызывает то же самое, как если бы вместо этого было написано 〈key〉=〈value〉. Однако если ни 〈key〉/.@cmd, ни сам ключ не определены, обработчики вызываться не будут. Вместо этого выполнение ключа просто останавливается. Таким образом, этот обработчик «пытается» использовать ключ, но никаких дальнейших действий не предпринимается, если ключ не определен.
  • Key handler 〈key〉/.retry=〈value〉 — Этот обработчик работает так же, как /.try, только он ничего не будет делать, если \ifpgfkeyssuccess имеет значение false. Таким образом, этот обработчик попытается установить ключ только в том случае, если «последняя попытка не удалась».
  • Key handler 〈key〉/.lastretry=〈value〉 — Этот обработчик работает как /.retry, только он будет вызывать обычные обработчики для неизвестных ключей, если \ifpgfkeyssuccess имеет значение false.

Обработчики для проверки ключей

  • Key handler 〈key〉/.show value — Этот обработчик выполняет команду \show для значения, хранящегося в 〈key〉. Это полезно в основном для отладки.
  • Key handler 〈key〉/.show code — Этот обработчик выполняет команду \show для кода, хранящегося в 〈key〉/.@cmd. Это полезно в основном для отладки.

Обработка ошибок

В определенных ситуациях могут возникнуть ошибки, например, при использовании неопределенного ключа. В таких ситуациях выполняются ключи ошибок. Они должны хранить макрос, который получает два аргумента: первый — это ключ-нарушитель (возможно, только после раскрытия макроса), второй — значение, которое было передано в качестве параметра (также возможно, только после раскрытия макроса).

Ключевая фильтрация

Обычно вызов \pgfkeys устанавливает все ключи, указанные в списке аргументов. Обычно именно этого ожидают пользователи. Однако реализации различных пакетов или pgf-библиотек могут нуждаться в большем контроле над процедурой установки ключей: библиотека A может захотеть установить свои параметры напрямую и передать все оставшиеся в библиотеку B.

Установить библиотеку фильтрации

\usepgfkeyslibrary{filtered} % LATEX and plain TEX 
\usepgfkeyslibrary[filtered] % ConTEXt

4 - Примеры PIC в библиотеке TIKZ

Живой пример использования мощи TIKZ на примерах с маленькими картинками PIC

Примеры использования поисковых запросов POSIX

Постановка задачи

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

Было принято решение не рисовать в редакторе картинки, а запрограммировать в LATEX и на вход просто подавать массив с адресами и номерами выходов.

  1. рисуем матрицу с адресами
  2. адрес состоит из двух частей, разделенных :
  3. первая часть 4 разряда
  4. вторая часть 5 разрядов
  5. матрица может располагаться горизонтально и вертикально
  6. в вертикальном положении над каждым адресом необходимо указать номер порта в черном кружке и схематичное изображение в виде скобки с кружком
  7. в горизонтальном положении слева от адреса расположить номер порта в черном кружке

Решение

  1. Создать стили для вертикальных и горизонтальных адресов
  2. Создать шаблон для номера выходного порта (цифра в черном кружке)
  3. Создать шаблон для имитации скрепки с красной точкой
  4. Создать шаблон для формирования горизонтального адреса
  5. Создать шаблон для формирования вертикального адреса
  6. Создать матрицу из 5-ти горизонтальных адресов в одной строке с номерами выходных портов в черных кружках
  7. Создать матрицу из 5-ти вертикальных адресов в одной колонке с номерами выходных портов в черных кружках и скрепкой с красной точкой

h

Код с описанием

\tikzset{vad/.style={node distance=0pt,inner sep=2pt,rotate=90,draw}}%настройка стиля для вертикальных адресов
\tikzset{had/.style={node distance=0pt,inner sep=2pt,rotate=0,draw}}%настройка стиля для горизонтальных адресов
\tikzset{
  orr/.pic={%рисуем маленький красный кружок на белом фоне
    \fill[white] (0,-0.3mm) ellipse (.6mm and 1mm);
    \fill[red] (0,0) ellipse (.4mm and .6mm);},
  piro/.pic={%рисуем скобку и внизу скобки помещаем красный кружок orr
    \draw[thick,orange,rounded corners] (-.7ex,1cm) -- (-.7ex,.3cm) -- (0,0) pic{orr} -- (.7ex,.3cm) -- (.7ex,1cm);},
 pics/ntt/.style={%рисуем черный кружок с переменной номер внутри кружка
   code={\node [circle,fill=black,minimum size=1em,inner sep=0pt,text=white] {#1};}},
 sp/.pic={\path (0,0)--(.2,0);}%это хитрый pic пробел. Чтобы не разъезжались строки.
}

\def\haddr#1#2{%строим горизонтальный адрес в формате 4:5
\coordinate(a0)at(0,.12);
\foreach \z [count=\x,evaluate=\x as \y using \x-1] in {#1}{ 
\node(a\x)[had,right=of a\y] {\z};
};
\node(s0)[had,draw=none,right=of a4] {:};
\foreach \z [count=\x,evaluate=\x as \y using \x-1] in {#2}{ 
\node(s\x)[had,right=of s\y] {\z};
};
}

\def\vaddr#1#2{%строим вертикальный адрес в формате 4:5
\coordinate(a0)at(0,0);
\foreach \z [count=\x,evaluate=\x as \y using \x-1] in {#1}{ 
\node(a\x)[vad,right=of a\y] {\z};
};
\node(s0)[vad,draw=none,right=of a4] {:};
\foreach \z [count=\x,evaluate=\x as \y using \x-1] in {#2}{ 
\node(s\x)[vad,right=of s\y] {\z};
};
}

%рисуем горизонтальную матрицу из пяти адресов
%в первой колонке черный кружок с номером \pic{ntt=1}
%во второй колонке пробел \pic{sp}, чтобы отделить
%в третьей колонке горизонтальный адрес \haddr...
\begin{tikzpicture}
\matrix[matrix of nodes,row sep={0ex}]{
 \pic{ntt=1};&\pic{sp};&\haddr{0,0,0,1}{0,0,0,1,2}\\
 \pic{ntt=2};& &\haddr{0,0,0,1}{0,0,0,1,3}\\
 \pic{ntt=3};& &\haddr{0,0,0,1}{0,0,0,1,4}\\
 \pic{ntt=4};& &\haddr{0,0,0,1}{0,0,0,1,5}\\
 \pic{ntt=5};& &\haddr{0,0,0,1}{0,0,0,1,6}\\};
\end{tikzpicture}

%рисуем вертикальную матрицу из пяти адресов
%в первой строке черные кружки с номерами \pic{ntt=1}
%во второй строке скобки, \pic{piro}
%в третьей строке вертикальный адрес \vaddr...
\begin{tikzpicture}
\matrix[matrix of nodes,column sep={0ex}]{
\pic{ntt=1};&\pic{ntt=2};&\pic{ntt=3};&\pic{ntt=4};&\pic{ntt=5};\\
\pic{piro};&\pic{piro};&\pic{piro};&\pic{piro};&\pic{piro};\\
  \vaddr{0,0,0,1}{0,0,0,1,2}&
  \vaddr{0,0,0,1}{0,0,0,1,2}&
  \vaddr{0,0,0,1}{0,0,0,1,2}&
  \vaddr{0,0,0,1}{0,0,0,1,2}&
  \vaddr{0,0,0,1}{0,0,0,1,2}\\};
\end{tikzpicture}

v

5 - Matrix в модуле TIKZ

Матрицы в графическом мобуле TIKZ

Введение в MATRIX

при объявлении node просто указать, что это будет matrix

\node [matrix,fill=red!20,draw=blue,very thick]

а дальше как в обычной таблице или array

\draw (0,0)   circle (4mm); & \node[rotate=10] {Hello};        \\
    \draw (0.2,0) circle (2mm); & \fill[red]   (0,0) circle (3mm); \\
  };

вот и всё.

every matrix

определяет стиль matrix

every outer matrix

это настраивает внешний node в котором объявлен matrix

\matrix

специальная команда без node

аналог \path node[matrix]

Выравнивание matrix

column sep=⟨spacing list⟩

расстояние между колонками

matr1

column sep={1cm,between origins} — расстояние будет мерить не по краям, а по центрам

row sep=⟨spacing list⟩

расстояние между строк

Задавать можно целиком на matrix, так и на отдельную ячейку

\draw (0,0) circle (2mm); \\[1cm,between origins] — можно так

\node {8}; &[2mm] \node{1}; &[-1mm] \node {6}; \\ — а можно и так

&[between borders] \node (c) {6}; — а можно и так

параметры ячейки (размеры)

every cell={⟨row⟩}{⟨column⟩} задает параметры каждой ячейки

cells=⟨options⟩

это стиль ячейки cell/.append style=⟨options⟩

nodes=⟨options⟩

это тоже стиль для ячеек matrix node/.append style=⟨options⟩

\begin{tikzpicture}
  \matrix [nodes={fill=blue!20,minimum size=5mm}]
  {
    \node {8}; & \node{1}; & \node {6}; \\
    \node {3}; & \node{5}; & \node {7}; \\
    \node {4}; & \node{9}; & \node {2}; \\
  };
\end{tikzpicture}

стили колонок и строк

  • /tikz/column ⟨number⟩ — column 2/.style={green!50!black}
  • /tikz/every odd column — стиль для нечетной колонки
  • /tikz/every even column — стиль для четной колонки
  • /tikz/row ⟨number⟩ — row 3/.style={green!50!black}
  • /tikz/every odd row — стиль для нечетной строки
  • /tikz/every even row — стиль для четной строки
  • /tikz/row ⟨row number⟩ column ⟨column number⟩ — стиль для строки и колонки
\begin{tikzpicture}
  [row 1/.style={red},
   column 2/.style={green!50!black},
   row 3 column 3/.style={blue}]

  \matrix
  {
    \node {8}; & \node{1}; & \node {6}; \\
    \node {3}; & \node{5}; & \node {7}; \\
    \node {4}; & \node{9}; & \node {2}; \\
  };
\end{tikzpicture}

Выравнивание в ячейках и колонках

\begin{tikzpicture}
  [column 1/.style={anchor=base west},%выравнивает слева
   column 2/.style={anchor=base east},%выравнивает справа
   column 3/.style={anchor=base}]% выравнивает по центру
  \matrix
  {
    \node {123}; & \node{456}; & \node {789}; \\
    \node {12}; & \node{45}; & \node {78}; \\
    \node {1}; & \node{4}; & \node {7}; \\
  };
\end{tikzpicture}

Большая таблица

\usetikzlibrary {matrix,fit}
\begin{tikzpicture}[
  font=\sffamily,
  head color/.style args={#1/#2}{
    row 1 column #1/.append style={nodes={fill=#2}}},
  % swap order of row and column styles
  matrix/inner style order={
    every cell,
    row, even odd row,
    column, even odd column,
    cell

  }
]

\matrix [
   matrix of nodes, nodes in empty cells,
   nodes={text width=2cm, align=center,
          minimum height=1.5em, anchor=center},
   % add striped row style
   every even row/.style={nodes={fill=olive!50}},
   % modify the feature column and header row
   column 1/.style= {nodes={fill=olive, inner ysep=0}},
   row 1/.style= {nodes={text depth=0.2ex, text=white}},
   row 1 column 1/.style={nodes={fill=none, draw=none}},
   head color/.list={2/orange,3/teal,4/cyan,5/magenta} % specify header colors
  ] (m)
  {
            & Basic     & Standard   & Professional & Enterprise \\
  Feature A & $\bullet$ & $\bullet$  & $\bullet$    & $\bullet$  \\
  Feature B & $\bullet$ & $\bullet$  & $\bullet$    & $\bullet$  \\
  Feature C &           &            &              & $\bullet$  \\
  Feature D &           & $\bullet$  & $\bullet$    & $\bullet$  \\
  Feature E &           &            & $\bullet$    & $\bullet$  \\
  };
% Add emphasis on selection by the use of "fit" library
\node[fit={(m-1-4.north west) (m-6-4.south east)},
      ultra thick, inner sep=0pt, rounded corners=1mm,
      draw=cyan, label={[cyan,align=center]270:Popular\\Choice!}]{};
\end{tikzpicture}

tabl

внутренние стили назначаются в определенной очередности.

Очередность задается параметром:

inner style order

\tikzset{
  matrix/inner style order={
    every cell,
    column,
    even odd column,
    row,
    even odd row,
    cell,
  },
}
  • inner style/every cell
  • inner style/column
  • inner style/even odd column
  • inner style/row
  • inner style/even odd row
  • inner style/cell
  • inner style order

Настройки по умолчанию

Для многих матриц нужно делать однообразные настройки

node{ какой-то текст и };

поэтому определим три макроса:

  • /tikz/execute at begin cell=⟨code⟩ — перед текстом
  • /tikz/execute at end cell=⟨code⟩ — послетекста
  • /tikz/execute at empty cell=⟨code⟩ — если пусто
\begin{tikzpicture}
 [matrix of nodes/.style={
    execute at begin cell=\node\bgroup,
    execute at end cell=\egroup;%
  }]
 \matrix [matrix of nodes]
 {
   8 & 1 & 6 \\
   3 & 5 & 7 \\
   4 & 9 & 2 \\
 };
\end{tikzpicture}

или так

\begin{tikzpicture}
  [matrix of nodes/.style={
     execute at begin cell=\node\bgroup,
     execute at end cell=\egroup;,%
     execute at empty cell=\node{--};%
   }]
  \matrix [matrix of nodes]
  {
    8 & 1 &   \\
    3 &   & 7 \\
      &   & 2 \\
  };
\end{tikzpicture}

https://tikz.dev/library-matrix

Якоря Matrix

matrix anchor=⟨anchor⟩

этот параметр применяется только к самой матрице, но не применяется к ячейкам

т.е. все north, south, east, west

\matrix [matrix anchor=west] at (0,0) поместит левую сторону матрицы в координату (0,0)

отличается от параметра [anchor=west] — который выравнивает в ячейках по левому краю

anchor=⟨anchor or node.anchor⟩

относится только к ячейке

если ячейке дали имя, то можно обращаться к ее якорям node.anchor

\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \matrix[matrix anchor=inner node.south,anchor=base,row sep=3mm] at (1,1)
  {
    \node {a}; & \node             {b}; & \node {c}; & \node {d}; \\
    \node {a}; & \node(inner node) {b}; & \node {c}; & \node {d}; \\
    \node {a}; & \node             {b}; & \node {c}; & \node {d}; \\
  };
  \draw (inner node.south) circle (1pt);
\end{tikzpicture}

ancor

кратко по примеру выше:

  1. во второй строчке node дали имя inner node
  2. в опциях matrix дали команду [matrix anchor=inner node.south, ... at (1,1), т.е. сказали, что точку юга этой ноды поместить в координату (1,1)
  3. anchor=base — колонки выравнивать по центру

Замена & как разделителя колонок

ampersand replacement=⟨macro name or empty⟩

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

\matrix [ampersand replacement=\&]

Matrix Library

без нее эта тема не закончена

\usetikzlibrary{matrix}

matrix of nodes

это матрица в которой каждая ячейка это node

\usetikzlibrary {matrix}
\begin{tikzpicture}
  \matrix (magic) [matrix of nodes]
  {
    8 & 1 & 6 \\
    3 & 5 & 7 \\
    4 & 9 & 2 \\
  };

  \draw[thick,red,->] (magic-1-1) |- (magic-2-3);
\end{tikzpicture}

мы такую уже делали сами, но она объявлена в библиотеке, нужно просто сослаться в заголовке

добавить свои опции вариант 1

указать колонку и строку в заголовке и назначить свой стиль

\begin{tikzpicture}[row 2 column 3/.style=red]
\matrix [matrix of nodes]

добавить опции непосредственно ячейке вариант 2

\usetikzlibrary {matrix}
\begin{tikzpicture}
  \matrix [matrix of nodes]
  {
    8 & 1 &         6 \\
    3 & 5 & |[red]| 7 \\
    4 & 9 &         2 \\
  };
\end{tikzpicture}

для этого нужно поместить между вертикальных линий все данные |[red] (seven)|, как здесь передаем цвет и имя ноды

у & есть необязательный аргумент [3mm] — это расстояние между колонками

8 &[1cm] 1 &[3mm] |[red]| 6 \\

вариант 3 — указать полный список параметров

3 & 5 & \node[red]{7}; \draw(0,0) circle(10pt);\\

matrix of math nodes

все ячейки становятся заключены в $

nodes in empty cells=⟨true or false⟩

обязывает отображать пустые ячейки

\usetikzlibrary {matrix}
\begin{tikzpicture}
  \matrix [matrix of math nodes,nodes={circle,draw},nodes in empty cells]
  {
    a_8 &     & a_6 \\
    a_3 &     & a_7 \\
    a_4 & a_9 &     \\
  };
\end{tikzpicture}

empty

Символы конца строк и переноса строк в узлах

обычно это \\

чтобы в ячейке переносить по строкам, нужно поместить текст в {}

\usetikzlibrary {matrix}
\begin{tikzpicture}
  \matrix [matrix of nodes,nodes={text width=16mm,draw}]
  {
    row 1 & {upper line \\ lower line} \\
    row 2 & hmm \\
  };
\end{tikzpicture}

Разделители в матрицах

  • left delimiter=⟨delimiter⟩
  • right delimiter=⟨delimiter⟩
  • every delimiter
  • every left delimiter
  • every right delimiter
  • above delimiter
  • every above delimiter
  • below delimiter=⟨delimiter⟩
  • every below delimiter
\usetikzlibrary {matrix}
\begin{tikzpicture}
 \matrix [matrix of math nodes,%
          left delimiter=\|,right delimiter=\rmoustache,%
          above delimiter=(,below delimiter=\}]
 {
   a_8 & a_1 & a_6 \\
   a_3 & a_5 & a_7 \\
   a_4 & a_9 & a_2 \\
 };
\end{tikzpicture}

matr

6 - PIC маленький рисунок

PIC это маленькие рисунки в TIKZ которые можно встраивать в большие и делать свои библиотеки

Синтаксис PIC

\path … pic ⟨foreach statements⟩ [⟨options⟩] (⟨prefix⟩) at(⟨coordinate⟩) :⟨animation attribute⟩={⟨options⟩} {⟨pic type⟩} …;

  1. PIC можно объявить в \tikzset в преамбуле
  2. можно написать прямо в path в опции code
\tikzset{
  seagull/.pic={
    % Code for a "seagull". Do you see it?...
    \draw (-3mm,0) to [bend left] (0,0) to [bend left] (3mm,0);
  }
}

Вообще PIC это упрощенная запись вставки кода в path.

во втором случае напишем через pic type =:

\tikz {
  \path (0,0) pic [pic type = seagull]
        (1,0) pic                      {seagull};
}
  1. Или в третьем случае через pics/code={}:
\tikz \pic [pics/code={\draw (-3mm,0) to[bend left] (0,0)
                                      to[bend left] (3mm,0);}]
      {}; % no pic type specified

но в последнем варианте, pic не будет, а будет чистый code, который и делает сам pic

pic action

позволяет в опцияхк команде pic передать дополнительные параметры.

\tikzset{
  my pic/.pic = {
    \path [pic actions] (0,0) circle[radius=3mm];
    \draw (-3mm,-3mm) rectangle (3mm,3mm);
  }
}

\tikz \pic                      {my pic}; \space
\tikz \pic [red]                {my pic}; \space
\tikz \pic [draw]               {my pic}; \space
\tikz \pic [draw=red]           {my pic}; \space
\tikz \pic [draw, shading=ball] {my pic}; \space
\tikz \pic [fill=red!50]        {my pic};

behind path и in front of path

также как и node позволяет рисовать за основным рисунком или перед ним

foreground code=⟨code⟩ и background code=⟨code⟩

можно указать индекс слоя

foreach

принимает параметры от foreach

\tikz \pic foreach \x in {1,2,3} at (\x,0) {seagull};

every pic

настраиваем стили для pic

\begin{tikzpicture}[every pic/.style={scale=2,transform shape}]
  \pic foreach \x in {1,2,3} at (\x,0) {seagull};
\end{tikzpicture}

prefix name

я не уверен,что буду этим пользоваться, но можно добавлять префиксы к именам точек pic

pic text

будет работать как label в nodes

или его аналог в библиотеке quotes

pic [draw, "$\alpha$"] {angle};

every pic quotes — для настройки кавычек

глобальный стиль для pic

\tikzset{
  pics/my circle/.style = {
    background code = { \fill circle [radius=#1]; }
  }
}
\tikz [fill=blue!30]
  \draw (0,0) pic {my circle=2mm} -- (1,1) pic {my circle=5mm};

7 - Node TIKZ

Nodes и Edges, киты TIKZ в которых можно все писать и компоновать

Синтаксис NODE

\path … node ⟨foreach statements⟩ [⟨options⟩] (⟨name⟩) at(⟨coordinate⟩) :⟨animation attribute⟩={⟨options⟩} {⟨node contents⟩} …;

node contents

это тоже, что и в фигурных скобках.

\tikz {
  \path (0,0) node [red]                    {A}
        (1,0) node [blue]                   {B}
        (2,0) node [green, node contents=C]
        (3,0) node [node contents=D]           ;
}

at

Node размещается в последней координате path, а at указывает конкретно куда поместить node.

\node at (0,0) {сюда}

behind path

нарисует сзади текущего рисунка. \tikz \fill [fill=blue!50, draw=blue, very thick] (0,0) node [behind path, fill=red!50] {first node}

in front of path

тоже, что и выше, только нарисует спереди текущего рисунка

name

задает имя node, полезно для якорей и координат

можно задать alias и есть еще режим also, позволяет под этим же именем node разместить другой текст

coordinate

\path … coordinate[⟨options⟩](⟨name⟩)at(⟨coordinate⟩) …;

специальный синтаксис для легковесных node

это будет просто точка и все якоря будут иметь одно и тоже значение.

\coordinate — простая запись

 \path[shape=coordinate]
    (0,0) coordinate(b1) 
	(1,0) coordinate(b2)
    (1,1) coordinate(b3) 
	(0,1) coordinate(b4);

OPTIONS

Опции для node отличаются от назначений path, поэтому для node нужно давать свои назначения в опциях.

Для рисования вокруг node используем библиотеку \usetikzlibrary {shapes.geometric} https://tikz.dev/library-shapes в ней много разных shapes, которые можно указывать в options

По умолчанию без библиотек в node можно применять 3 вида shapes:

  • rectangle
  • circle
  • coordinate

foreach

в node можно вставлять несколько foreach

\tikz \node foreach \x in {1,...,4} foreach \y in {1,2,3}
            [draw] at (\x,\y) {\x,\y};

foreach

every node

устанавливает стиль для каждой ноды \begin{tikzpicture}[every node/.style={draw}]

или

\begin{tikzpicture}
  [every rectangle node/.style={draw},
   every circle node/.style={draw,double}]
  \draw (0,0) node[rectangle] {A} -- (1,1) node[circle] {B};
\end{tikzpicture}

для каждой прямоугольной node или для каждой круглой node

execute at begin node (end node)

\begin{tikzpicture}
  [execute at begin node={A},
   execute at end node={D}]
  \node[execute at begin node={B}] {C};
\end{tikzpicture}

На выходе даст ABCD

name prefix=⟨text⟩

Используется в scope и добавляет префикс к имени node

\tikz {
  \begin{scope}[name prefix = top-]
    \node (A) at (0,1) {A};
    \node (B) at (1,1) {B};
    \draw (A) -- (B);
  \end{scope}
  \begin{scope}[name prefix = bottom-]
    \node (A) at (0,0) {A};
    \node (B) at (1,0) {B};
    \draw (A) -- (B);
  \end{scope}

  \draw [red] (top-A) -- (bottom-B);
}

ее брат name suffix=⟨text⟩ добавит суффикс в конце имени

inner sep=⟨dimension⟩

внутренний отступ от текста к рамке

inner xsep=⟨dimension⟩

margin по x

inner ysep=⟨dimension⟩

margin по y

outer sep=⟨dimension or “auto”⟩

эффект этой опции позволит сместить все якоря вовне outer sep=auto

outer xsep=⟨dimension⟩

outer ysep=⟨dimension⟩

minimum height=⟨dimension⟩

минимальная высота node

если текст не вместится,то node расширится

minimum width=⟨dimension⟩

минимальная ширина node

minimum size=⟨dimension⟩

для квадратных и круглых форм

shape aspect=⟨aspect ratio⟩

пропорции сжатия

shape border uses incircle=⟨boolean⟩

проверяет,чтобы внутрь фигуры вписывалась окружность

shape border rotate=⟨angle⟩

поворачивает контур фигуры, но не поворачивает текст

\nodepart[⟨options⟩]{⟨part name⟩}

это node состоящая из нескольких частей

\usetikzlibrary {shapes.multipart}
\begin{tikzpicture}
  \node [circle split,draw,double,fill=red!20]
  {
    % No \nodepart has been used, yet. So, the following is put in the
    % ``text'' node part by default.
    $q_1$
    \nodepart{lower} % Ok, end ``text'' part, start ``output'' part
    $00$
  }; % output part ended.
\end{tikzpicture}

partnode

для ее использования нужно применить circle split и в \nodeparts указать аргументы {text,lower}.

для нее же можно настроить стиль: every ⟨part name⟩ node part

\usetikzlibrary {shapes.multipart}
\tikz [every lower node part/.style={red}]
  \node [circle split,draw] {$q_1$ \nodepart{lower} $00$};

NODE TEXT

text=color

задает цвет текста

node font=⟨font commands⟩

\draw[node font=\itshape] — задает шрифт в node

или font=⟨font commands⟩ если задать внутри node

\begin{tikzpicture}
  \node [font=\itshape] {italic};
\end{tikzpicture}

align

  • center
  • left
  • right
  • align=flush left
  • align=flush right — выравнивает без переноса слов
  • align=fkush center
  • align=justify
  • align=none \tikz[align=center] \node[draw] {This is a\\demonstration.};

text width=⟨dimension⟩

задает ширину текстового поля в node

text height=⟨dimension⟩

высоту текстового блока

text depth=⟨dimension⟩

глубина текста

badness warnings for centered text=⟨true or false⟩

система координат NODE

coordinate

south тоже есть

anchor=⟨anchor name⟩

anchor= — по умолчанию это центр node, но можно задать любую координату и относительно ее будет идти привязка

относительные надписи

  • above=⟨offset⟩
  • below=⟨offset⟩
  • left=⟨offset⟩
  • right=⟨offset⟩
  • above left
  • above right
  • below left
  • below right
  • centered

\tikz \fill (0,0) circle (2pt) node[above=2pt] {above};

библиотека positioning

\usetikzlibrary{positioning}

дает все тоже самое,но можно еще вычислять расстояния

\node at (1,1) [above=2pt+3pt,draw]

плюс у нее есть команда of

\usetikzlibrary {positioning}
\begin{tikzpicture}[every node/.style=draw]
 \draw[help lines] (0,0) grid (2,2);
 \node (somenode) at (1,1) {some node};

 \node [above=5mm of somenode.north east] {\tiny 5mm of somenode.north east};
 \node [above=1cm of somenode.north]      {\tiny 1cm of somenode.north};
\end{tikzpicture}

of укажет относительно чего смещение

on grig

смещает node по сетке, а не относительно бордюра node

\usetikzlibrary {positioning}
\begin{tikzpicture}[every node/.style=draw]
  \draw[help lines] (0,0) grid (2,3);

  % Not gridded
  \node (a1) at (0,0) {not gridded};
  \node (b1) [above=1cm of a1] {fooy};
  \node (c1) [above=1cm of b1] {a};

  % gridded
  \node (a2) at (2,0) {gridded};
  \node (b2) [on grid,above=1cm of a2] {fooy};
  \node (c2) [on grid,above=1cm of b2] {a};
\end{tikzpicture}

grid

смещает без on grid относительно бордюра node

с on grid смещает четко по сетке grid

node distance=⟨shifting part⟩

\begin{tikzpicture}[every node/.style=draw,node distance=5mm]

теперь все смещения будут на 5мм

Очень показательно как работает этот ключ

\usetikzlibrary {positioning}
\begin{tikzpicture}[every node/.style={draw,node distance=0mm}]
  \draw[help lines] (0,0) grid (2,3);

  % Not gridded
  \node (a1) at (0,0) {not gridded};
  \node (b1) [above=of a1] {fooy};
  \node (c1) [above=of b1] {a};

  % gridded
  \node (a2) at (2,0) {gridded};
  \node (b2) [on grid,above=of a2] {fooy};
  \node (c2) [on grid,above=of b2] {a};
\end{tikzpicture}

shift

node distance=0mm — показало смещение для on grid по центрам, а без grid от бордюра.

еще есть вариант [node distance=1 and 1]

К вышеперечисленной серии команд в библиотеке еще есть

  • base left=⟨specification⟩
  • base right
  • mid left
  • mid right

библиотека matrix и graphdrawing

о них отдельно

лучше позиционируют большие массивы node

fitting node

т.е. подгонка координат

\usetikzlibrary {fit,shapes.geometric}
\begin{tikzpicture}[level distance=8mm]
  \node (root) {root}
    child { node (a) {a} }
    child { node (b) {b}
      child { node (d) {d} }
      child { node (e) {e} } }
    child { node (c) {c} };

  \node[draw=red,inner sep=0pt,thick,ellipse,fit=(root) (b) (d) (e)] {};
  \node[draw=blue,inner sep=0pt,thick,ellipse,fit=(b) (c) (e)] {};
\end{tikzpicture}

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

fitting

Transformations

transform shape

\tikz[scale=3] \node[transform shape] {X}; т.е. я сначала сказал, что нужно сделать scale=3, а потом команда transform shape выполнит это действие и я получу гигантскую X.

причем сказать можно в path или draw, а команда выполнится в node

\usepgfmodule {nonlineartransformations}\usetikzlibrary {curvilinear}

модули и библиотеки для трансформаций

transform shape nonlinear=⟨true or false⟩

будет рисовать по криволинейным траекториям подробнее https://tikz.dev/tikz-shapes

pos

указывает явно координату, где разместить node в path

\tikz \draw (0,0) -- (3,1)
    node[pos=0]{0} node[pos=0.5]{1/2} node[pos=0.9]{9/10};

text

pos получает значение от 0 до 1 по длине пути

auto=⟨direction⟩

направление может быть left или right в зависимости от этого будет выбираться якорь в node для соединения

swap

если установлена опция auto то будет делать наоборот, для left будет искать right якорь

' — апостроф отработает как swap

sloped

будет писать текст вдоль кривой

можно добавить [allow upside down] или [rotate=180]

node[midway,sloped,below] {$y$};

allow upside down=⟨boolean⟩

перевернет надпись вверх ногами

midway имена точек в пути

  • midway — напишет посередине линии
  • near start — pos=0.25.
  • near end — pos=0.75.
  • very near start — pos=0.125.
  • very near end — pos=0.875.
  • at start — pos=0.
  • at end — pos=1

label

это такая надпись в надписи

\usetikzlibrary {positioning}
\tikz [circle] {
  \node [draw] (s) [label=below:$s$]  {ф};
  \node [draw] (a) [right=of s] {} edge (s);
  \node [draw] (b) [right=of a] {} edge (a);
  \node [draw] (t) [right=of b, label=$t$] {} edge (b);
}

label

направление метки словами left, right, below, above или градусы и двоеточие:

label=[⟨options⟩]⟨angle⟩:⟨text⟩ или \node [draw] (s) [label=100:$s$] {ф};

\tikz
  \node [circle, draw,
         label=default,
         label=60:$60^\circ$,
         label=below:$-90^\circ$,
         label=3:$3^\circ$,
         label=2:$2^\circ$,
         label={[below]180:$180^\circ$},
         label={[centered]135:$135^\circ$}] {my circle};

label distance=⟨distance⟩

установит дистанцию для label от меток

every label

настроит стиль для label

PIN

булавка — похожа на label, но с булавкой)

pin distance=⟨distance⟩

расстояние до текста в булавке

every pin

стиль булавки

pin position=⟨angle⟩

аналогично label position

every pin edge

настроит вид edge для pin

pin={[pin edge={blue,thick}]right:X},

Кавычки

Нужна библиотека \usetikzlibrary{quotes}

\usetikzlibrary {quotes}
\begin{tikzpicture}
  \matrix [row sep=5mm] {
    \node [draw, "label"]                  {A}; \\
    \node [draw, "label" left]             {B}; \\
    \node [draw, "label" centered]         {C}; \\
    \node [draw, "label" color=red]        {D}; \\
    \node [draw, "label" {red,draw,thick}] {E}; \\
  };
\end{tikzpicture}

текст в кавычках становится обычным label

quotes mean label

\usetikzlibrary {quotes}
\tikz
  \node ["90:$90^\circ$", "left:$180^\circ$", circle, draw] {circle};

every label quotes

задать стиль

quotes mean pin

Connecting Nodes

Соединение Nodes

\begin{tikzpicture}
  \path (0,0) node             (x) {Hello World!}
        (3,1) node[circle,draw](y) {$\int_1^2 x \mathrm d x$};

  \draw[->,blue]   (x) -- (y);
  \draw[->,red]    (x) -| node[near start,below] {label} (y);
  \draw[->,orange] (x) .. controls +(up:1cm) and +(left:1cm) .. node[above,sloped] {label} (y);
\end{tikzpicture}

При соединении nodes стрелки будут проходить от границы node

EDGES

это ребро, которое будет добавлено после того, как будет нарисован основной путь.

\path … edge[⟨options⟩] ⟨nodes⟩ (⟨coordinate⟩) …;

\begin{tikzpicture}
  \node foreach \name/\angle in {a/0,b/90,c/180,d/270}
        (\name) at (\angle:1) {$\name$};

  \path[->] (b) edge (a)
                edge (c)
                edge [-,dotted] (d)
            (c) edge (a)
                edge (d)
            (d) edge (a);
\end{tikzpicture}

edge

edge — это просто ребра между координатами.

Внутри edge можно вставлять node

every edge

назначить стиль для всех edge

quotes

для edge в библиотеке quotes также работает текст в кавычках, как label

\usetikzlibrary {quotes}
\tikz \draw (0,0) edge ["left", ->] (2,0);

every edge quotes

Стиль quotes

swap

к тексту с кавычками добавить '

расстояние между label и edge

определяется параметром inner sep=

\usetikzlibrary {quotes}
\tikz [tight/.style={inner sep=1pt}, loose/.style={inner sep=.7em}]
  \draw (0,0) edge ["left" tight,
                    "right"' loose,
                    "start" near start] (4,0);

Ссылка на узлы за пределами текущего изображения

Это означает,что можно ссылаться из одной картинки в другую картинку на странице.

remember picture=⟨boolean⟩

этот параметр нужно назначить картинкам, которые будут друг на друга ссылаться

\tikzset{every picture/.append style={remember picture}}

этот стиль для всех картинок сразу.

overlay

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

Да, я это видел и я это сделал. Все соединились стрелочками.

\tikz[remember picture] \node[circle,fill=red!50] (n1) {}; — это кружок в любом месте текста.

\tikz[remember picture] \node[fill=blue!50] (n2) {}; — это квадратик, в другом месте.

\begin{tikzpicture}[remember picture,overlay]
  \draw[->,very thick] (n1) -- (n2);
\end{tikzpicture}

а это линия,которая соединит кружок с квадратиком

overlay

все так и произошло.

\begin{tikzpicture}[remember picture]
  \node (c) [circle,draw] {Big circle};

  \draw [overlay,->,very thick,red,opacity=.5]
    (c) to[bend left] (n1) (n1) -| (n2);
\end{tikzpicture}

Это красная линия с еще более сложным маршрутом.

Абсолютные координаты страницы

на каждой странице присутствует node — current page и у нее есть полный набор ancher: west,east,north,south,center…

для размещения в любом месте страницы нужно в свойствах указать:

\begin{tikzpicture}[remember picture,overlay]

Поздний код

\path … node also[⟨late options⟩](⟨name⟩) …; — добавляет опции к узлу позже.

Обязательно нужно указать имя node и не должно быть указано текста. Только опции.

\begin{tikzpicture}
  \node      [draw,circle]       (a) {Hello};
  \node also [label=above:world] (a);
\end{tikzpicture}

\tikzlastnode

этот макрос подобен командам append after command и prefix after command

late options=⟨options⟩

это еще один аналог node also

\begin{tikzpicture}
  \node      [draw,circle]       (a) {Hello};
  \path [late options={name=a, label=above:world}];
\end{tikzpicture}

8 - Path и его особенности

Разбираю документацию TIKZ и некоторые свои добавления по PATH

Вступление с моими открытиями

\begin{tikzpicture}
\begin{scope}%делаю специальнуюзону видимости для CLIP
\fill[black!20](-6,0) circle (1.6);%немного фона вокруг кружка
\clip (-6,0) circle (1.5cm);%клипаю будущий рисунок
\node (p) at (-6,0) {\includegraphics[width=3.5cm]{lamp}%вставляю рисунок
\rule{15pt}{0pt}};%так я придумал делать отступ от рисунка невидимой rule
\end{scope}

\gridnum %это просто разметка координат в моем нехитром исполнении, покажу позже

\node[text width=12cm,anchor=north west] at (p.north east) {Для проведения теста, подайте рабочее напряжение на вход ...};%это собственно текстовый блок, который выровнялся по правому верхнему углу рисунка и левому верхнему углу текста 
%anchor=north west] at (p.north east) - это магия 
\end{tikzpicture} 

clip

Grid

Grid сделал, чтобы удобно было рисовать и не разу не пожалел.

Кидаешь рисунок в координату и дальше расставляешь свои фичи.

%%%%%%%%%%%%%%%%%%%%%%%%% GRID 
\def\gridnum {
\draw[help lines] (-8,-8) grid +(16,16);
\node foreach \x in {-8,-7,...,8} at (\x,8.5) {\x};
\node foreach \y in {-8,-7,...,8} at (8.5,\y) {\y};
\node foreach \x in {-8,-7,...,8} at (\x,-8.5) {\x};
\node foreach \y in {-8,-7,...,8} at (-8.5,\y) {\y};
\draw[red] (0,-8.5) -- (0,8.5);
\draw[red] (-8.5,0) -- (8.5,0);
}

Кружки со стрелками

\tikzset{
num/.style={draw,shape=circle,fill=black,text=white,minimum size=2em,font=\bf,general shadow={fill=gray,shadow scale=1.1}},%определяет стиль кружка для отметки на рисунках
numtext/.style={draw,shape=circle,fill=black!85,text=white,minimum size=1em,font=\bf,general shadow={fill=gray,shadow scale=1.1}},%определяет стиль кружка для отметки в тексте
arrow num/.style={line width=.1em, gray,arrows = {-Stealth[line width=0.3pt, fill=gray, length=10pt,open,fill=gray,white,quick]}},%определяет стиль стрелки для отметки на рисунках
}

А это сами кружки

\def\numar#1#2#3{
\node [num] (l#1) at (#2) {#1};
\coordinate (t#1) at (#3);
\draw[line width=.15em, white] (l#1) -- ($(l#1)!.95!(t#1)$);
\draw[arrow num] (l#1) -- (t#1);
%рисует черный кружок с цифрой #1 кружок в координате #2, а стрелочку в координату #3
}

А это результат все вместе:

\begin{tikzpicture}
\begin{scope}%это клипнутый рисунок
\fill[black!20](-6,0) circle (1.6);
\clip (-6,0) circle (1.5cm);
\node (p) at (-6,0) {\includegraphics[width=3.5cm]{lamp}\rule{15pt}{0pt}};     
\end{scope}

\gridnum % это мой грид
 \numar{2}{0,-4}{-2.2,-1.8};%это кружок с 2 и со стрелкой
 \numar{2}{0,-4}{2.2,-1.8};%из двойки вторая стрелка
\node at (-4,0){\num{1}};%это кружок без стрелки
\node at ( 4,0){\num{1}};


\end{tikzpicture} 

grid

Path

Мощная примудрость, позволит на многое открыть глаза в TIKZ

\begin{tikzpicture}
\gridnum

\begin{scope}[scale=2] %сделал, чтобы видно лучше было
\draw[thick,red] 
(0,0) coordinate (a) %назначаем координате имя (a)
-- coordinate (ab) %а это пока рисуем от (a) к (b) запоминаем середину и называем ее (ab)
(1,.5) coordinate (b) %назначаем координате имя (b)
  .. coordinate (bc) controls +(up:1.5cm) and +(left:0cm) .. %а это пока рисуем от (b) к (c) запоминаем середину и называем ее (bc)
%но считает серидину сложно с учетом контрольных точек
(3,1) coordinate (c) %назначаем координате имя (c)
(0,1) -- (2,1) -- %просто рисуем замкнутый треугольник и 
coordinate (x) (1,2) -- cycle;%x - будет точно серединой между двух вершин

\draw (a) node[below] {start part 1} %ничего интересного, просто подписать точки
(ab) node[below right] {straight segment} 
(b) node[right] {end first segment} 
(c) node[right] {end part 1} 
(x) node[above right] {part 2 (closed)};

\fill[red](a) circle (1pt); %а это просто эти точки разукрасить
\fill[blue](b) circle (1pt);
\fill[green](ab) circle (1pt);
\fill[yellow](bc) circle (1pt);
\fill[magenta](c) circle (1pt);
\fill[orange](x) circle (1pt);
\end{scope}
\end{tikzpicture} 

coordinate

[rounded corners] [sharp corners]

круглые и угловатые соединения линий rounded corners=4pt — по умолчанию, или можно поменять

\tikz \draw (0,0) -- (1,1) [rounded corners] -- (2,0) -- (3,1) [sharp corners] -- (3,0) -- (2,1);

это группировка scope для назначения стиля

\tikz \draw (0,0) -- (1,1) {[rounded corners] -- (2,0) -- (3,1)} -- (3,0) -- (2,1);

name=

задает имя пути, полезно при пересечениях

every path

задает стиль всем значениям path

\begin{tikzpicture}

[fill=yellow!80!black, % only sets the color 
every path/.style={draw}] % all paths are drawn 
\fill (0,0) rectangle +(1,1); %все будут с конуром
\shade (2,0) rectangle +(1,1);%и градиент тоже
\end{tikzpicture} 

path2

insert path

по пути основного пути вставит любой другой путь))))

\tikz [c/.style={insert path={circle[radius=2pt]}}] \draw (0,0) -- (1,1) [c] -- (3,2) [c];

append after command=

и его брат prefix after command=〈path〉

\tikz \draw node [append after command={(foo)--(1,1) (foo)--(2,1) (foo)--(3,1)},draw] (foo){foo};

Т.е. пока рисую draw, включаю node и обвожу ее [draw], а в параметрах command задаю лучики, сколько угодно.

luch

cycle & current subpath start

cycle — замыкает контур

current subpath start — возвращается в исходную координату, но контур не замыкает

\useasboundingbox (0,2.5); % увеличивает отступ в картинке

– |- -| .. controls ..

тип линии которую нужно провести

-- — прямая

|- — вертикально, потом горизонтально или cycle

.. controls .. — контрольная точка 1 или 2

circle

begin{tikzpicture} 
\draw (1,0) circle [radius=1.5]; 
\fill (1,0) circle [x radius=1cm, y radius=5mm, rotate=30]; 
\end{tikzpicture}

ellipse

\begin{tikzpicture} 
\draw [help lines] (0,0) grid (3,2); 
\draw (1,1) ellipse [x radius=1cm,y radius=.5cm]; 
\end{tikzpicture}

arc

/tikz/start angle=〈degrees〉 
/tikz/end angle=〈degrees〉 
/tikz/delta angle=〈degrees〉

grid

\tikz[rotate=30] \draw[step=1mm] (0,0) grid (2,2);

/tikz/step=〈number or dimension or coordinate〉

/tikz/xstep=〈dimension or number〉

/tikz/ystep=〈dimension or number〉

/tikz/help lines

parabola

\path ... parabola[〈options〉]bend〈bend coordinate〉〈coordinate or cycle〉 ...;

/tikz/bend=〈coordinate〉
/tikz/bend pos=〈fraction〉
/tikz/parabola height=〈dimension〉
/tikz/bend at start
/tikz/bend at end

sin & cos

\path ... sin〈coordinate or cycle〉 ...;

svg

\path ... svg[〈options〉]{〈path data〉} ...;

\usetikzlibrary {svg.path}  
\begin{tikzpicture} 
\filldraw [fill=red!20] (0,1) svg[scale=2] {h 10 v 10 h -10} node [above left] {upper left} -- cycle;  
\draw svg {M 0 0 L 20 20 h 10 a 10 10 0 0 0 -20 0}; 
\end{tikzpicture}

И кульминация!!!

\usetikzlibrary {svg.path}  
\begin{tikzpicture} 
\draw[fill=red] svg[rotate=180,scale=1pt] {m 0,0 c -7.1455,-3.0005 -14.1485,-6.184 -6.261,-17.3275 l 0.7006,-8.7994 -2.2838,-2.151 c 6.7935,-23.5259 19.2799,-46.8506 29.895,-65.918 11.1032,-15.0145 24.2647,-28.7189 28.7623,-47.9367 l 11.9841,-34.99407 c -0.1546,-13.35578 -2.0371,-27.40362 3.835,-38.34918 l 6.2318,-9.82699 c 1.5939,-28.91141 13.1608,-53.72504 12.7031,-82.211751 11.2272,-29.04903 17.5024,-22.60743 25.1668,-26.1256 4.524,-1.40654 8.693,-3.38055 10.0668,-9.827 l 4.554,2.1571 c -3.5888,-15.13669 -2.1459,-27.75767 1.9176,-39.06851 1.3477,-6.40097 7.8536,-8.21675 14.8602,-9.58722 8.592,-2.16346 14.2134,1.61359 20.3733,4.31421 3.564,5.54462 6.8227,11.17624 5.9921,17.97645 -0.088,2.44508 -1.4805,0.80239 -1.7797,2.90917 -0.6305,4.43879 2.7321,11.60579 -0.8615,12.55824 -4.4315,1.17434 -0.8057,12.46002 -5.2394,13.07901 -11.4427,1.59752 -8.2461,7.35191 -11.8607,9.9434 -2.2929,3.4139 -3.7804,7.09455 0.088,11.12472 7.8121,8.29041 7.5135,18.05557 8.6284,27.563671 5.5774,16.1437 10.1453,32.62388 26.8446,45.06055 8.8021,6.70563 14.713,14.56771 20.3734,22.53013 l 11.0253,11.26537 c 9.1625,0.81664 11.8325,3.66246 10.7858,7.6699 5.2654,7.69444 0.9194,8.78118 -3.835,9.58721 l -19.4145,0.23948 c -6.3528,-2.57118 -8.2777,-6.80263 -9.5872,-11.26507 -4.7804,-8.04729 -11.2793,-15.52136 -19.8938,-22.29065 -18.0192,-7.5638 -23.762,-19.73159 -32.1176,-30.91936 l -1.6779,37.15119 c 1.1413,7.46498 1.8943,15.70567 2.3969,24.44775 6.3573,7.86785 13.5455,15.45832 14.381,25.16679 l 14.6207,50.57336 c 5.1154,14.4625 1.2032,22.1542 -0.9588,31.1588 l -16.0588,44.3416 c -4.5409,19.7879 5.1463,25.3556 -1.6827,26.5005 1.2122,4.1548 5.7941,11.5294 10.791,15.6839 l 16.538,5.5128 c 5.8814,5.4882 4.5425,8.71988 0.2395,11.02528 -10.2823,0.03 -20.4991,0.7699 -31.3983,-5.99208 -24.5966,2.299 -20.5907,-1.8606 -27.3242,-3.5952 -6.3237,-9.1034 0.046,-19.8628 2.075,-24.194 l -6.8033,2.9522 c 2.2535,-29.9275 11.2296,-63.866 17.911,-84.9381 l 4.0747,-4.3145 c -2.5708,-2.0158 -5.4922,-2.5127 -6.2318,-12.4634 -4.9405,-15.5883 -14.1539,-28.3278 -22.7699,-41.4653 -16.0976,16.02 -27.5888,36.6464 -36.6716,59.6813 -3.0305,7.3616 -8.3362,10.1725 -13.1827,13.9017 -11.4324,16.4468 -20.5631,46.1767 -29.4813,66.3954 l -3.5952,-1.2016 c -2.918,8.9664 1.9352,10.8095 6.4716,12.9432 l 8.6284,4.7935 c 5.8839,5.6301 4.5728,8.9879 -1.6778,10.7858 -9.743,4.25658 -18.0911,2.2347 -26.6049,0.9588 -3.7097,-3.4521 -7.4534,-6.8618 -13.6619,-7.1907 z}; 
\end{tikzpicture}

man

plot

  1. –plot[〈local options〉]coordinates{〈coordinate 1〉〈coordinate 2〉…〈coordinate n〉}
  2. –plot[〈local options〉]file{〈filename〉} 342
  3. –plot[〈local options〉]〈coordinate expression〉
  4. –plot[〈local options〉]function{〈gnuplot formula〉}

строит график по координатам

\tikz \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)};

to path

(a) to (b) примерно тоже, что (a) – (b), но есть нюансы.

После to я могу передать дополнительные настройки для этого участка пути:

(a) to [out=135,in=45] (b) выйдет из точки (a) под углом 135, а войдет под 45.

или еще 3 замечательных макроса: \tikztostart, \tikztotarget, и \tikztonodes — запоминают координаты без зацикливания пути: т.е. в режиме current subpath start

\begin{tikzpicture}[to path={
    .. controls +(1,0) and +(1,0) .. (\tikztotarget) \tikztonodes}]

  \node (a) at (0,0) {a};
  \node (b) at (2,1) {b};
  \node (c) at (1,2) {c};

  \draw (a) to node {x} (b)
        (a) to          (c);
\end{tikzpicture}

Этот вариант я припас для вертикального написания шрифта


\begin{tikzpicture}
  \draw (0,0) to node [sloped,above] {x} (3,2);

  \draw (0,0) to[out=90,in=180] node [sloped,above] {x} (3,2);
\draw (0,0) to node[sloped,above] {0001000:000200} (0,5);
\end{tikzpicture}

vert

edge

EDGE умеет делать:

  • edge node={node [sloped,above] {x}} ноды
  • edge label=x ставит метки
  • edge label=x, edge label'=y ставит зеркальные метки

every to

Назначаем стили для всех to

\tikz[every to/.style={bend left}] \draw (0,0) to (3,2); назначает стиль для to

execute at begin to=⟨code⟩ (no default)

и ее брат execute at end to=⟨code⟩ выполняют код до и после начала рисования

FOREACH

Для него посвящу отдельную статью но в кратце:

\tikz \draw (0,0) foreach \x in {1,...,3} { -- (\x,1) -- (\x,0) }; Это цикл по списку.

LET IN

Сначала не хотел разбираться, но потом стало так интересно, а выяснилось, что еще и полезно.

\path … let⟨assignment⟩ ,⟨assignment⟩,⟨assignment⟩… in …;

В let … in можем использовать переменные

  • \n1 или \n5 — суть номер регистра, где можно вычислить что нибудь и потом в разделе IN подставить
  • \p1,\x1,\y1 — работает с координатами и тоже запоминает в своих регистрах
  • \p{name} — тоже, что и \p1,\p3 … только под любым именем.
\usetikzlibrary {calc}
\begin{tikzpicture}
 \draw [help lines] (0,0) grid (3,2);

 \draw let \p{foo} = (1,1), \p2 = (2,0) in
         (0,0) -- (\p2) -- (\p{foo});
\end{tikzpicture}

xshift yshift

оказалась полезная штука для смещения SCOPE и рисовать все в координатах с (0,0)

\pgfextra{⟨code⟩}

сначала хотел выбросить, но появилось время, почитал и тоже понравилось

\newdimen\mydim %назначаем переменную для измерения
\begin{tikzpicture}
  \mydim=1cm% присваиваем первое значение
  \draw (0pt,\mydim) \pgfextra{\mydim=2cm} -- (0pt,\mydim); изменяем значение и получаем новый результат
\end{tikzpicture}

я думаю использовать при настройке типовых рисунков для передачи им параметров

SOFT USE PATH

это такие ячейки памяти с сохранеными PATH, которые потом можно применять безограничений

\usetikzlibrary {intersections}
\begin{tikzpicture}
  \path[save path=\pathA,name path=A] (0,1) to [bend left] (1,0);%запоминаю путь pathA
  \path[save path=\pathB,name path=B]%запоминаю путь pathB
    (0,0) .. controls (.33,.1) and (.66,.9) .. (1,1);

  \fill[name intersections={of=A and B}] (intersection-1) circle (1pt);%нахожу пересечения пути (причем пути даже не наприсовал)

  \draw[blue][use path=\pathA];%а теперь достаю путь и рисую
  \draw[red] [use path=\pathB];
\end{tikzpicture}

действия с path

Это наверно аксиомы с которыми работает path

\draw — аналогично \path[draw]. рисует

\fill — аналогично \path[fill]. заполняет цветом

\filldraw — \path[fill,draw]. рисует и заполняет

\pattern — \path[pattern]. заполняет маленькими path из библиотеки pattern

\shade — \path[shade]. градиент

\shadedraw — \path[shade,draw]. рисует и заполняет градиентом

\clip — \path[clip]. клипит

\useasboundingbox — \path[use as bounding box] связывает до и после

опции

  • color= — покрасит в цветом
  • line width= — толщина линии
  • line cap= — round, rect, butt — завершение линии
  • line join= — тип соединения линии round, bevel, miter
  • miter limit= — определяет остроту угла соединения
  • dash pattern — чередуются on 2pt off 3pt on 4pt off 4pt и получаем свой пунктир
  • dash phase= — первоначальный сдвиг паттерна
  • dash= — совмещает pattern и phase \draw [dash=on 20pt off 10pt phase 10pt]
  • dash expand off растягивает на сколько может dash, т.е. линия будет нужной длины и без разрывов
\usetikzlibrary {decorations}
\begin{tikzpicture}[|-|, dash pattern=on 4pt off 2pt]
  \draw [dash expand off] (0pt,30pt) -- (26pt,30pt);
  \draw [dash expand off] (0pt,20pt) -- (24pt,20pt);
  \draw [dash expand off] (0pt,10pt) -- (22pt,10pt);
  \draw [dash expand off] (0pt, 0pt) -- (20pt, 0pt);
\begin{scope}[xshift=2cm]
  \draw  (0pt,30pt) -- (26pt,30pt);
  \draw  (0pt,20pt) -- (24pt,20pt);
  \draw  (0pt,10pt) -- (22pt,10pt);
  \draw  (0pt, 0pt) -- (20pt, 0pt);
\end{scope}
\end{tikzpicture}

dash

  • solid — сплошная прямая
  • dotted
  • densely dotted
  • loosely dotted
  • dashed
  • densely dashed
  • loosely dashed
  • dash dot
  • densely dash dot
  • loosely dash dot
  • dash dot dot
  • densely dash dot dot
  • loosely dash dot dot

draw opacity

работает для всего и draw и fill и svg

double

  • double=<color> — нарисует двойную линию и закрасит цветом
  • double distance=⟨dimension⟩ — расстояние между линиями
  • double distance between line centers=⟨dimension⟩ — расстояние между центрами линий
  • double equal sign distance — удвоит расстояние знака
\Huge $==>\implies$\tikz[baseline,double equal sign distance]
                   \draw[double,thick,-{Implies[]}](0,0.55ex) --++(3ex,0);

double

рисуем стрелу

\usetikzlibrary {arrows.meta,bending} — это нам пригодится

\usetikzlibrary {arrows.meta,bending}
\tikz \draw[tips, -{Latex[open,length=10pt,bend]}] (0,0) to[bend left] (1,0);

arrow

pattern

\usetikzlibrary {patterns}
\begin{tikzpicture}
  \draw[pattern=dots] (0,0) circle (1cm);
  \draw[pattern=fivepointed stars] (0,0) rectangle (3,1);
\end{tikzpicture}

star

в библиотеке их много и лучше смотреть библиотеку https://tikz.dev/library-patterns#section-library-patterns

  • pattern color — покрасит в нужный цвет

nonzero rule

исключит из пересечения фигур

\begin{tikzpicture}
  \filldraw[fill=yellow!80!black]
  % Clockwise rectangle
  (0,0) -- (0,1) -- (1,1) -- (1,0) -- cycle
  % Counter-clockwise rectangle
  (0.25,0.25) -- (0.75,0.25) -- (0.75,0.75) -- (0.25,0.75) -- cycle;

  \draw[->] (0,1) -- (.4,1);
  \draw[->] (0.75,0.75) -- (0.3,.75);

  \draw[->] (0.5,0.5) -- +(0,1) node[above] {crossings: $-1+1 = 0$};

  \begin{scope}[yshift=-3cm]
    \filldraw[fill=yellow!80!black]
    % Clockwise rectangle
    (0,0) -- (0,1) -- (1,1) -- (1,0) -- cycle
    % Clockwise rectangle
    (0.25,0.25) -- (0.25,0.75) -- (0.75,0.75) -- (0.75,0.25) -- cycle;

    \draw[->] (0,1) -- (.4,1);
    \draw[->] (0.25,0.75) -- (0.4,.75);

    \draw[->] (0.5,0.5) -- +(0,1) node[above] {crossings: $1+1 = 2$};
  \end{scope}
\end{tikzpicture}

cross

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

even odd rule

просто вырежет внутренний паттерн

pattern picture

Идея данной функции, добавить внутрь объекта другой объект, ограниченный первым.

причем родительский объект будет иметь имя box с метками по сторонам света.

\begin{tikzpicture}
  \draw [help lines] (0,0) grid (3,2);
  \filldraw [fill=blue!10,draw=blue,thick] (1.5,1) circle (1)% нарисую круг
    [path picture={
      \node at (path picture bounding box.center) {%вставлю в круг надпись в центр круга
        This is a long text.
      };}
    ];
\end{tikzpicture}

также path picture может быть \draw, \fill, \node, \pattern

Shade

Градиент

у него есть настройки

\tikz \shadedraw [shading=axis] (0,0) rectangle (1,1);
\tikz \shadedraw [shading=radial] (0,0) rectangle (1,1);
\tikz \shadedraw [shading=ball,ball color=red] (0,0) circle (.5cm);
\tikz \shadedraw [shading=ball,ball color=blue] (0,0) circle (.5cm);
\tikz \shadedraw [shading=ball,ball color=green] (0,0) circle (.5cm);

ball

bilinear interpolation

это красивые градиентные заливки объектов по 4-м углам

\usepgflibrary {shadings}
\tikz
  \shade[upper left=red,upper right=green,
         lower left=blue,lower right=yellow]
    (0,0) rectangle (3,2);
\tikz \shade[shading=color wheel] (0,0) circle (1.5);

\tikz \shade[shading=color wheel] [even odd rule]
  (0,0) circle (1.5)
  (0,0) circle (1);
  • color wheel
  • color wheel black center
  • color wheel white center
  • inner color= % радиальная заливка
  • outer color= %радиальная заливка

color

use as bounding box

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

У них есть подпараметры:

  • trim left=⟨dimension or coordinate or default⟩
  • trim right=⟨dimension or coordinate or default⟩
  • trim lowlevel=true|false

right

clip

вырезает все на скорую руку

лучше использовать внутри рисунков с применением группировки scope

\begin{tikzpicture}
  \draw (0,0) -- ( 0:1cm);
  \draw (0,0) -- (10:1cm);
  \draw (0,0) -- (20:1cm);
  \draw (0,0) -- (30:1cm);
  \begin{scope}[fill=red]
    \fill[clip] (0.2,0.2) rectangle (0.5,0.5);

    \draw (0,0) -- (40:1cm);
    \draw (0,0) -- (50:1cm);
    \draw (0,0) -- (60:1cm);
  \end{scope}
  \draw (0,0) -- (70:1cm);
  \draw (0,0) -- (80:1cm);
  \draw (0,0) -- (90:1cm);
\end{tikzpicture}

clip

preaction

Я раньше использовал подобное для рисование стрелок с подложкой белого фона.

Оказалось, что все уже придумано до нас))

\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);

  \draw
    [preaction={draw,line width=4mm,blue}]%нарисует по координатам draw прямоугольник с толщиной линии 4mm
    [line width=2mm,red] (0,0) rectangle (2,2);%нарисует сверху по этим же координатам линию 2mm
\end{tikzpicture}

preaction

удобно для выделения контраста и рисования теней

\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \draw
    [preaction={fill=black,opacity=.5,
                transform canvas={xshift=1mm,yshift=-1mm}}]
    [fill=red] (0,0) rectangle (1,2)
               (1,2) circle (5mm);
\end{tikzpicture}

preaction

preaction — может быть несколько штук в одном объекте

postaction=⟨options⟩

Это друг preaction, только делает после того как нарисовал основной рисунок

decorations

\usetikzlibrary {decorations.pathmorphing,shadows}
\begin{tikzpicture}
  \node [circular drop shadow={shadow scale=1.05},minimum size=3.13cm,
         decorate, decoration=zigzag,
         fill=blue!20,draw,thick,circle] {Hello!};
\end{tikzpicture}

Целая библиотека различных декораций и линий для рисования объектов.

decorate

9 - Вводные понятия в TIKZ

Базовые понятия TIKZ и описание системы координат. Без этого урока разбираться в TIKZ бессмысленно

Подключение TIKZ в документ.

Для подключения TIKZ нужно в преамбуле добавить:

\usepackage{tikz} %подключить пакет
\usetikzlibrary {angles,calc,quotes} %подключить нужные библиотеки

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

Чтобы вставить в текст объект TIKZ нужно использовать окружение

\begin{tikzpicture}
...
\end{tikzpicture}

или 

\tikz ...

Координаты в TIKZ

Обычные координаты

(X, Y) — разделитель запятая.

Измеряем либо в стандартных единицах TeX (cm, pt). По умолчанию PGF использует сантиметр: X -> вправо, Y -> вверх.

(30:1cm) — полярные координаты. Т.е. от текущей точки на 1см 30 градусов.

Для трехмерных объектов (1,1,1)

Якорные координаты

У каждого объекта есть свои якорные координаты,связанные со сторонами света: например: first node.north

  • north
  • south
  • east
  • west

И их возможные комбинации: node.north west

Относительные координаты

Нужно перед указанием координат поставить ++ и указать относительное смещение ++(1cm,0pt) — вправо на 1см.

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

Как выяснил, команда \node не изменяет текущую координату.

Если использовать один + перед координатами, то перемещение произойдет, но текущая координата не сменится.

(1,0) +(1,0) +(0,1) даст три точки (1,0), (2,0), (1,1).

Специальный синтаксис для PATH

PATH — водит пером по бумаге, но не оставляет следов, если его не попросить специально.

-- — прямая линия

-| — горизонтально + вертикально

|- — вертикально + горизонтально

cycle — вернуться в точку старта

PATH может:

  • draw — рисовать линию
  • fill — заполнять пространство
  • shade — градиент
  • clip — вырезать

Так же доступны комбинации с ними.

\path (0,0) rectangle (2ex,1ex); % ничего визуального не произойдет
\path[draw] (0,0) rectangle (2ex,1ex); % появится рамка
\path[fill=black] (0,0) rectangle (2ex,1ex); % появится черный прямоугольник

Для этих случаев есть сокращенные команды:

  • \path[draw]=\draw
  • \path[fill]=\fill
  • \path[fill,draw]=\filldraw
  • \path[shade]=\shade
  • \path[shade,draw]=\shadedraw
  • \path[clip]=\clip
  • \path[clip,draw]=\draw[clip]

Вставка текста

Текст добавляем с помощью команды \node прямо в синтаксис \path

\tikz \draw (1,1) node {text} -- (2,2);

У node могут быть:

(name) или [name=имя] [другие опции] {текст}

опции node:

  • rectangle
  • fill
  • circle
  • draw
  • ellipse

и т.д. это то, что будет нарисовано вокруг текста.

Рисуем деревья

Это такая умная \node с поднодиками.

\begin{tikzpicture}
  \node {root}
    child {node {left}}
    child {node {right}
      child {node {child}}
      child {node {child}}
    };
\end{tikzpicture}

Подключаем библиотеку со стрелочками и оформим стили.

FORK — это вилка, которой будем соединять вниз (down),также можно написать up, left, right и от этой стороны будет выходить стрелка.

\usetikzlibrary {arrows.meta,trees}
\begin{tikzpicture}
  [edge from parent fork down, sibling distance=15mm, level distance=15mm,
   every node/.style={fill=red!30,rounded corners},
   edge from parent/.style={red,-{Circle[open]},thick,draw}]
  \node {root}
      child {node {left}}
      child {node {right}
        child {node {child}}
        child {node {child}}
      };
\end{tikzpicture}

Tree

И еще с шариками, а grow — покажет куда расти дереву (up,down,left,right или north,south,east,west). Anchor — это куда прицепляться parent и child.

sibling — ширина плечика на одном уровне, level — это расстояние между уровнями.

every node/.style — назначает стиль глобально для всех node без указания класса.

edge — это собственно само ребро или соединение

ball — это еще одна разновидность фигуры, шарик называется.

\begin{tikzpicture}
  [parent anchor=east,child anchor=west,grow=east,
   sibling distance=15mm, level distance=15mm,
   every node/.style={ball color=red,circle,text=white},
   edge from parent/.style={draw,dashed,thick,red}]
  \node {root}
      child {node {left}}
      child {node {right}
        child {node {child}}
        child {node {child}}
      };
\end{tikzpicture}

boll

Графы

Нужна своя библиотека graphs

\usetikzlibrary {graphs}
\tikz \graph [grow down, branch left] {
  root -> { 
left,
2,3 ->{
  5,6,7,8 ->{
      11,12,13},
    9}, 
right -> {
  child, 
  child} }
};

graph

Тема с графом тоже интересна.

grow — куда растем, указать сторону

branch — в какую сторону ветви раскидать

\usetikzlibrary {graphs.standard}
\tikz \graph [clockwise] { subgraph K_n [n=9] };

Уж очень он мне понравился. Библиотеку обязательно отдельно всю опишу.

graph

SCOPE

Это внутреннее окружение для группировки настроек.

Это фактически зона видимости.

\begin{tikzpicture}
  \begin{scope}[color=red]
    \draw (0mm,10mm) -- (10mm,10mm);
    \draw (0mm, 8mm) -- (10mm, 8mm);
    \draw (0mm, 6mm) -- (10mm, 6mm);
  \end{scope}
  \begin{scope}[color=green]
    \draw             (0mm, 4mm) -- (10mm, 4mm);
    \draw             (0mm, 2mm) -- (10mm, 2mm);
    \draw[color=blue] (0mm, 0mm) -- (10mm, 0mm);
  \end{scope}
\end{tikzpicture}

line

Еще SCOPE умеет

/tikz/name=⟨scope name⟩ /tikz/every scope /tikz/execute at begin scope=⟨code⟩ /tikz/execute at end scope=⟨code⟩

И у нее есть даже библиотека \usetikzlibrary{scopes}

Когда библиотека загружена, то можно просто указать фигурные скобки, без begin/end

А еще становится доступной команда \scoped ⟨animations spec⟩[⟨options⟩]⟨path command⟩

\usetikzlibrary {scopes}
\begin{tikzpicture}
  { [ultra thick]
    { [red]
      \draw (0mm,10mm) -- (10mm,10mm);
      \draw (0mm,8mm)  -- (10mm,8mm);
    }
    \draw (0mm,6mm) -- (10mm,6mm);
  }
  { [green]
    \draw (0mm,4mm) -- (10mm,4mm);
    \draw (0mm,2mm) -- (10mm,2mm);
    \draw[blue] (0mm,0mm) -- (10mm,0mm);
  }
\end{tikzpicture}
\usetikzlibrary {backgrounds}
\begin{tikzpicture}
  \node [fill=white] at (1,1) {Hello world};
  \scoped [on background layer]
    \draw (0,0) grid (3,2);
\end{tikzpicture}

Опции

\tikzset

— установит в переменную любую команду для применения в окружении \begin{tikzpicture}

baseline

— еще можно задать с помощью координаты, тоже поймет.

\tikz[baseline=0pt]\draw(0,0)circle(.5ex); — установит смещение от базовой линии. По умолчанию строго по центру.

cir

А вот так перечеркнем слово

\usetikzlibrary {shapes.misc}
Hello
\tikz[baseline=(X.base)]
  \node [cross out,draw] (X) {world.};

cross

Назначение своего стиля

my style/.style={draw=red,fill=red!20}

Использование стилей

\begin{tikzpicture}[help lines/.style={blue!50,very thin}]
  \draw             (0,0) grid +(2,2);
  \draw[help lines] (2,0) grid +(2,2);
\end{tikzpicture}

Чтобы добавить настройки к существующему стилю /.append style вместо style

Стили с переменными

\begin{tikzpicture}[outline/.style={draw=#1,thick,fill=#1!50}]
  \node [outline=red]  at (0,1) {red};
  \node [outline=blue] at (0,0) {blue};
\end{tikzpicture}

или задать значение по умолчанию

\begin{tikzpicture}[outline/.style={draw=#1,thick,fill=#1!50},
                    outline/.default=black]
  \node [outline]      at (0,1) {default};
  \node [outline=blue] at (0,0) {blue};
\end{tikzpicture}

/tikz/execute at begin picture=⟨code⟩

Выполнит код до того как начал рисовать картину

/tikz/execute at end picture=⟨code⟩

Выполнит код после того как нарисовал картину

\usetikzlibrary {backgrounds}
\begin{tikzpicture}[execute at end picture=%
{
    \begin{pgfonlayer}{background}
      \path[fill=yellow,rounded corners]
        (current bounding box.south west) rectangle
        (current bounding box.north east);
    \end{pgfonlayer}
  }]
  \node at (0,0) {X};
  \node at (2,1) {Y};
\end{tikzpicture}

yellow

Нарисовал X и Y, а потом подрисовал фон желтого цвета.

Установка глобального стиля /tikz/every picture

В преамбуле напишем \tikzset{every picture/.style=semithick}

или если несколько значений, то \tikzset{every picture/.style={line width=1pt}}

Библиотека \usetikzlibrary{babel}

Для работы со шрифтами,рекомендуется всегда загружать эту библиотеку.

Specifying Coordinates

Или поговорим о координатах.

([⟨options⟩]⟨coordinate specification⟩)

Три вида координат:

  • декартовы
  • полярные
  • сферические

Явное указание координат и неявное указание.

Декартова система координат CANVAS

/tikz/cs/x=⟨dimension⟩

/tikz/cs/y=⟨dimension⟩

Система координат XYZ

Все тоже, только xyz

\begin{tikzpicture}[->]
  \draw (0,0) -- (xyz cs:x=1);
  \draw (0,0) -- (xyz cs:y=1);
  \draw (0,0) -- (xyz cs:z=1);
\end{tikzpicture}

xyz

Система координат canvas polar

/tikz/cs/angle=⟨градусы⟩ — Угол координаты. Угол всегда должен быть указан в градусах.

/tikz/cs/radius=⟨размер) — Расстояние от текущей точки

/tikz/cs/x radius=⟨размер⟩ /tikz/cs/y radius=⟨размер⟩

\tikz \draw    (0cm,0cm) -- (30:1cm) -- (60:1cm) -- (90:1cm)
            -- (120:1cm) -- (150:1cm) -- (180:1cm);

radius

Специальные слова для указания угла

up, down, left, right, north, south, west, east, north east, north west, south east, south west

Система координат XYZ POLAR

\begin{tikzpicture}[x=1.5cm,y=1cm]%масштаб системы координат 
  \draw[help lines] (0cm,0cm) grid (3cm,2cm);

  \draw (0,0) -- (xyz polar cs:angle=0,radius=1);
  \draw (0,0) -- (xyz polar cs:angle=30,radius=1);
  \draw (0,0) -- (xyz polar cs:angle=60,radius=1);
  \draw (0,0) -- (xyz polar cs:angle=90,radius=1);

  \draw (xyz polar cs:angle=0,radius=2)
     -- (xyz polar cs:angle=30,radius=2)
     -- (xyz polar cs:angle=60,radius=2)
     -- (xyz polar cs:angle=90,radius=2);
 \end{tikzpicture}
\begin{tikzpicture}[x={(-1cm,0cm)},y={(0cm,-1cm)}] %переворачиваю систему координат
  \draw[help lines] (0cm,0cm) grid (3cm,2cm);%рисую сетку

  \fill (canvas cs:x=1cm,y=0cm) node[right] {X}   circle (2pt);%точка в абсолютных координатах без изменений (черная)
  \fill (canvas cs:x=0cm,y=1cm)  node[left] {Y}  circle (2pt);%точка в абсолютных координатах без изменений (черная)

  \fill [color=red] (1,0)  node[left]{X'}  circle  (2pt);%точка в относительных координатах перевернутая (красная)
  \fill [color=red] (0,1)  node[right]{Y'}  circle (2pt);%точка в относительных координатах перевернутая (красная)
  \draw [color=red] (0,0) -- (30:1) -- (60:1) -- (90:1)
             -- (120:1) -- (150:1) -- (180:1);%рисунок в относительных координатах красный
\end{tikzpicture}

rotate

Барицентрические системы координат

barycentric — это координаты по сторонам света north, south, east, west и их комбинации

\begin{tikzpicture}
  \coordinate (content)   at (90:3cm);
  \coordinate (structure) at (210:3cm);
  \coordinate (form)      at (-30:3cm);

  \node [above]       at (content)   {content oriented};
  \node [below left]  at (structure) {structure oriented};
  \node [below right] at (form)      {form oriented};

  \draw [thick,gray] (content.south) -- (structure.north east) -- (form.north west) -- cycle;

  \small
  \node at (barycentric cs:content=0.5,structure=0.1 ,form=1)    {PostScript};
  \node at (barycentric cs:content=1 ,structure=0 ,form=0.4)  {DVI};
  \node at (barycentric cs:content=0.5,structure=0.5 ,form=1)    {PDF};
  \node at (barycentric cs:content=0 ,structure=0.25,form=1)    {CSS};
  \node at (barycentric cs:content=0.5,structure=1 ,form=0)    {XML};
  \node at (barycentric cs:content=0.5,structure=1 ,form=0.4)  {HTML};
  \node at (barycentric cs:content=1 ,structure=0.2 ,form=0.8)  {\TeX};
  \node at (barycentric cs:content=1 ,structure=0.6 ,form=0.8)  {\LaTeX};
  \node at (barycentric cs:content=0.8,structure=0.8 ,form=1)    {Word};
  \node at (barycentric cs:content=1 ,structure=0.05,form=0.05) {ASCII};
\end{tikzpicture}

barycentric

Для понимания процесса barycentric, каждая координата тянет к себе с определенной силой. Если я поставлю с одинаковой силой, то будет ровно посередине, относительно всех точек.

\node at (barycentric cs:content=1,structure=1 ,form=1) {PostScript}; как на рисунке ниже barycentric

Node координатная система

/tikz/cs/name=⟨node name⟩

/tikz/anchor=⟨anchor⟩

\usetikzlibrary {arrows.meta}
\begin{tikzpicture}[node font=\ttfamily]
  \node (shape)   at (0,2)  [draw] {class Shape};
  \node (rect)    at (-2,0) [draw] {class Rectangle};
  \node (circle)  at (2,0)  [draw] {class Circle};
  \node (ellipse) at (6,0)  [draw] {class Ellipse};

  \draw [color=red](node cs:name=circle,anchor=north) |- (0,1);
  \draw [blue] (node cs:name=ellipse,anchor=north) |- (0,1);
  \draw [arrows = -{Triangle[open, angle=60:3mm]}]
           (node cs:name=rect,anchor=north)
        |- (0,1) -| (node cs:name=shape,anchor=south);
\end{tikzpicture}

\usetikzlibrary {arrows.meta} — библиотека для красивых стрелочек

\begin{tikzpicture}[node font=\ttfamily] — назначаем шрифт

Присвоим имена каждой ноде

\node (shape)   at (0,2)  [draw] {class Shape};
\node (rect)    at (-2,0) [draw] {class Rectangle};
\node (circle)  at (2,0)  [draw] {class Circle};
\node (ellipse) at (6,0)  [draw] {class Ellipse};

Нарисуем первую линию красного цвета

\draw [color=red](node cs:name=circle,anchor=north) |- (0,1);

red

Нарисуем вторую линию синего цвета

\draw [blue] (node cs:name=ellipse,anchor=north) |- (0,1);

red

Нарисуем стрелку черногго цвета

\draw [arrows = -{Triangle[open, angle=60:3mm]}]
       (node cs:name=rect,anchor=north)
    |- (0,1) -| (node cs:name=shape,anchor=south);

red

А эта штука соединяет между собой две ноды по бордюру самым коротким путем: (node cs:name=a) -- (node cs:name=b), т.е. все, что в круглых скобках — это координаты.

\usetikzlibrary {shapes.geometric}
\begin{tikzpicture}
  \path (0,0)  node(a) [ellipse,rotate=10,draw] {An ellipse}
        (3,-1) node(b) [circle,draw]            {A circle};
  \draw[thick] (node cs:name=a) -- (node cs:name=b);
\end{tikzpicture}

А это легкая замена rectangle, чтобы не пересекалось

\tikz \draw (0,0) node(x) [draw] {Text}
%            rectangle (1,1)
            (node cs:name=x) -- +(0,1) -- +(1,1) -- +(1,0) -- (node cs:name=x)
            (node cs:name=x) -- +(1,1)
            (node cs:name=x) -- +(1,.5)
            (node cs:name=x) -- +(.5,1)
            ;

rext

Для те, кто в танке, чтобы не забыть: +(координаты) — не изменяет точку отсчета и указывает относительную координату; ++(координаты) — изменяет точку отсчета и указывает относительные координаты; (координаты) — изменяет точку отсчета и указывает абсолютные координаты.

\begin{tikzpicture}
  \draw[blue!20]             (0,0) grid +(2,2);
  \draw (0,0) node(x) [draw] {Text}
  (node cs:name=x) -- ++(0,1) -- ++(1,1) -- +(1,0) -- (node cs:name=x);
\end{tikzpicture}

rext

\usetikzlibrary {shapes.geometric}
\begin{tikzpicture}[fill=blue!20]
  \draw[help lines] (-1,-2) grid (6,3);
  \path (0,0)  node(a) [ellipse,rotate=10,draw,fill]    {An ellipse}
        (3,-1) node(b) [circle,draw,fill]               {A circle}
        (2,2)  node(c) [rectangle,rotate=20,draw,fill]  {A rectangle}
        (5,2)  node(d) [rectangle,rotate=-30,draw,fill] {Another rectangle};
  \draw[thick] (a.south) -- (b) -- (c) -- (d);
  \draw[thick,red,->] (a) |- +(1,3) -| (c) |- (b);
  \draw[thick,blue,<->] (b) .. controls +(right:2cm) and +(down:1cm) .. (d);
\end{tikzpicture}

rext

Что здесь примечательного?

  1. Все ноды рисуются в один присест, просто перечисляем через слово node и вначале подставляем координаты.
  2. Линии рисуем отдельными командами через \draw

Координатная система TANGENT

Работает только с загруженной библиотекой CALC

Нарисует по касательной от точки (a):

  • tangent — система координат
  • cs: — сами координаты
    • node=c — фигура
    • point={(a)} — точка, от которой пойдет касательная
    • solution=1 — номер решения, если их несколько
\usetikzlibrary {calc}
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);

  \coordinate (a) at (3,2);

  \node [circle,draw] (c) at (1,1) [minimum size=40pt] {$c$};

  \draw[red] (a)  -- (tangent cs:node=c,point={(a)},solution=1) --
       (c.center) -- (tangent cs:node=c,point={(a)},solution=2) -- cycle;
\end{tikzpicture}

rext

Создание собственной системы координат

Требует отдельного изучения, если вдруг понадобится

Или создать alias существующей системекоординат

\tikzaliascoordinatesystem{⟨new name⟩}{⟨old name⟩}

https://tikz.dev/tikz-coordinates#sec-13.2.5

Координаты точек пересечения

Библиотека \usetikzlibrary{intersections}

/tikz/name path=⟨name⟩ — задать имя path для поиска пересечения

/tikz/name path global=⟨name⟩ — задает имя path глобально,будет доступно за пределами окружения SCOPE в рисунке

/tikz/name intersections={⟨options⟩} — поиск точек пересечения путей path

Если несколько точек пересечения им будут заданы координаты intersections-1 и intersections-2 и т.д. сколько получится.

\usetikzlibrary {intersections}
\begin{tikzpicture}[every node/.style={opacity=1, black, above left}]%стиль node подписи в лево вверх
  \draw [help lines] grid (3,2);%нарисуем grid
  \draw [name path=ellipse] (2,0.5) ellipse (0.75cm and 1cm);%нарисуем элипс и имя path=ellipse
  \draw [name path=rectangle, rotate=10] (0.5,0.5) rectangle +(2,1);%нарисуем прямоугольник и имя path=rectangle
  \fill [red, opacity=0.5, name intersections={of=ellipse and rectangle}]% найдем точки пересечения двух path
  %name intersections --- это команда для поиска пересечений
  %of= --- задает path для поиска пересечений
    (intersection-1) circle (2pt) node {1}%нарисовать точку в пересечении 1
    (intersection-2) circle (2pt) node {2};%нарисовать точку в пересечении 2
\end{tikzpicture}

intersec

Ключи intersections

of=

name intersections={of=ellipse and rectangle} — задает имена path для поиска пересечений

name=

выдаст имена точек пересечения, какие заданы в name

  \fill [red, opacity=0.5, name intersections={of=ellipse and rectangle,name=insec}]
    (insec-1) circle (2pt) node {1}
    (insec-2) circle (2pt) node {2};

total=⟨macro⟩

Создает список всех точек пересечения и сохраняет его в макросе tex по номерам 1,2,3 и т.д.

[name intersections={of=curve 1 and curve 2, name=i, total=\t}] — сохранит в макросе \t

by={a,b}

присвоит каждой точке свое имя a и b

  \fill [name intersections={of=curve 1 and curve 2, by={a,b}}]
        (a) circle (2pt)
        (b) circle (2pt);

Еще можно использовать нотацию ... подставит имена автоматически

[name intersections={
          of=curve 1 and curve 2,
			  by={[label=center:a],[label=center:...],[label=center:i]}}]

Относительные и инкрементальные координаты

Это мои любимые + и ++

Дают одинаковый вариант:

++ изменяет текущую координату и премещается относительно

+ не изменяет текущую координату и перемещается относительно

\begin{tikzpicture}
  \draw (0,0)     -- ++(1,0) -- ++(0,1) -- ++(-1,0) -- cycle;
  \draw (2,0)     -- ++(1,0) -- ++(0,1) -- ++(-1,0) -- cycle;
  \draw (1.5,1.5) -- ++(1,0) -- ++(0,1) -- ++(-1,0) -- cycle;
\end{tikzpicture}

\begin{tikzpicture}
  \draw (0,0)     -- +(1,0) -- +(1,1) -- +(0,1) -- cycle;
  \draw (2,0)     -- +(1,0) -- +(1,1) -- +(0,1) -- cycle;
  \draw (1.5,1.5) -- +(1,0) -- +(1,1) -- +(0,1) -- cycle;
\end{tikzpicture}

rect

Ключевое слово TURN

\tikz \draw (0,0) -- (1,1) -- ([turn]-45:1cm) -- ([turn]-30:1cm);

Поворачивает ось координат по касательной к последней точке.

\begin{tikzpicture} [delta angle=-180, radius=1cm]
\draw [help lines] (0,0) grid (10,5);
\draw (0,3) arc [start angle=-180]  -- ([turn]60:1cm)
              arc [start angle=-180] -- ([turn]60:1cm)
              arc [start angle=180] -- ([turn]60:1cm);
\end{tikzpicture}

arc

До меня дошло, когда нарисовал сетку координат

[delta angle=-180, radius=1cm] — параметры дуги: ее угол и радиус, минус говорит, что рисуем по часовой стрелке

[start angle=-180] — собственно стартовый угол дуги, относительно системы координат — здесь -180 и +180 роли не играет, но -90 и +90 развернут дугу в разные стороны.

– ([turn]60:1cm) — эта штука нарисует отрезок из последней точки но в системе координат именно последней точки. Т.е. 60 градусов она развернет относительно мысленного продолжения arc по касательной.

[current point is local]

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

\begin{tikzpicture}
  \draw      (0,0) -- ++(1,0)   -- ++(0,1)   -- ++(-1,0);
  \draw[red] (2,0) -- ++(1,0)
     { [current point is local] -- ++(0,1) } -- ++(-1,0);
\end{tikzpicture}

Вычисляемые координаты

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

($(a) + 1/3*(1cm,0)$) — вот так берем и изменяем координаты. Не забываем поставить эту конструкцию в $.

([⟨options⟩]$⟨coordinate computation⟩$)

— синтаксис

\usetikzlibrary {calc}
\begin{tikzpicture}
  \draw [help lines] (0,0) grid (3,2);

  \fill [red] ($2*(1,1)$) circle (2pt);
  \fill [green] (${1+1}*(1,.5)$) circle (2pt);
  \fill [blue] ($cos(0)*sin(90)*(1,1)$) circle (2pt);
  \fill [black] (${3*(4-3)}*(1,0.5)$) circle (2pt);
\end{tikzpicture}

Это возможные операции над координатами. Координаты всегда имеют структуру (x,y) и умножение будет происходить над x и y по отдельности.

⟨coordinate⟩!⟨number⟩!⟨angle⟩:⟨second coordinate⟩

(1,2)!.75!(3,4) — это значит, что координата будет на .75 между точками (1,2) и (3,4)

\usetikzlibrary {calc}
\begin{tikzpicture}
  \draw [help lines] (0,0) grid (3,2);

  \draw (1,0) -- (3,2);

  \foreach \i in {0,0.2,0.5,0.9,1}
    \node at ($(1,0)!\i!(3,2)$) {\i};
\end{tikzpicture}

flow

\usetikzlibrary {calc}
\begin{tikzpicture}
  \draw [help lines] (0,0) grid (3,3);

  \coordinate (a) at (1,0);
  \coordinate (b) at (3,2);

  \draw[->] (a) -- (b);

  \coordinate (c) at ($ (a)!1! 10:(b) $); % от точки (a) длина !1! --- такая же как (ab) и повернуть на 10 градусов.

  \draw[->,red] (a) -- (c);

  \fill ($ (a)!.5! 10:(b) $) circle (2pt); % а здесь точку нарисуем
\end{tikzpicture}

Змея для примера

\usetikzlibrary {calc}
\begin{tikzpicture}
  \draw [help lines] (0,0) grid (4,4);

  \foreach \i in {0,0.125,...,2}
    \fill ($(2,2) !\i! \i*180:(3,2)$) circle (2pt);
\end{tikzpicture}

zmey

Модифаеры могут быть по нескольку штук дляг за другом

\usetikzlibrary {calc}
\begin{tikzpicture}
  \draw [help lines] (0,0) grid (3,2);

  \draw (0,0) -- (3,2);
  \draw[red] ($(0,0)!.3!(3,2)$) -- (3,0);
  \fill[red] ($(0,0)!.3!(3,2)!.7!(3,0)$) circle (2pt); %как здесь. Нашли точку на одной прямой и о нее ищем на другой.
\end{tikzpicture}

⟨coordinate⟩!⟨dimension⟩!⟨angle⟩:⟨second coordinate⟩

т.е. эта штука вычислит все в миллиметрах и расставит метки по прямой

\usetikzlibrary {calc}
\begin{tikzpicture}
  \draw [help lines] (0,0) grid (3,2);

  \draw (1,0) -- (3,2);

  \foreach \i in {0cm,1cm,15mm}
    \node at ($(1,0)!\i!(3,2)$) {\i};
\end{tikzpicture}

А эта будет ставить измерения

\usetikzlibrary {calc}
\begin{tikzpicture}
  \draw [help lines] (0,0) grid (3,2);

  \coordinate (a) at (1,0);
  \coordinate (b) at (3,1);

  \draw (a) -- (b);%нарисуем прямую ab

  \coordinate (c) at ($ (a)!.25!(b) $);%найдем точку c
  \coordinate (d) at ($ (c)!1cm!90:(b) $);%найдем точку d 90град от cb

  \draw [<->] (c) -- (d) node [sloped,midway,above] {1cm};% начертим стрелочки и напишем 1 cm
\end{tikzpicture}

dim

⟨coordinate⟩!⟨projection coordinate⟩!⟨angle⟩:⟨second coordinate⟩

модификаторы проекции

Нарисуем треугольник и опустим перпендикуляры от вершин на противоположные стороны

между !()! укажем вершину в скобках

\usetikzlibrary {calc}
\begin{tikzpicture}
  \draw [help lines] (0,0) grid (3,2);

  \coordinate (a) at (0,1);
  \coordinate (b) at (3,2);
  \coordinate (c) at (2.5,0);

  \draw (a) -- (b) -- (c) -- cycle;

  \draw[red]    (a) -- ($(b)!(a)!(c)$);%от a на сторону bc
  \draw[orange] (b) -- ($(a)!(b)!(c)$);%от b на сторону ac
  \draw[blue]   (c) -- ($(a)!(c)!(b)$);%от c на сторону ab
\end{tikzpicture}

pr

Перпендикуляры

Основные команды это:

  • /tikz/cs/horizontal line through={(⟨coordinate⟩)}
  • /tikz/cs/vertical line through={(⟨coordinate⟩)}

задают вертикальную и горизонтальные линии, но в основном используется синтаксис:

(⟨p⟩ |- ⟨q⟩) или (⟨q⟩ -| ⟨p⟩).

Для примера: (2,1 |- 3,4) и (3,4 -| 2,1) дадут точку (2,4)

\begin{tikzpicture}
  \path (30:1cm) node(p1) {$p_1$}   (75:1cm) node(p2) {$p_2$};

  \draw (-0.2,0) -- (1.2,0) node(xline)[right] {$q_1$};
  \draw (2,-0.2) -- (2,1.2) node(yline)[above] {$q_2$};

  \draw[->] (p1) -- (p1 |- xline);
  \draw[->] (p2) -- (p2 |- xline);
  \draw[->] (p1) -- (p1 -| yline);
  \draw[->] (p2) -- (p2 -| yline);
\end{tikzpicture}

perprn

или такой

\usetikzlibrary {calc}
\begin{tikzpicture}
  \node (A) at (0,1)    {A};
  \node (B) at (1,1.5)  {B};
  \node (C) at (2,0)    {C};
  \node (D) at (2.5,-2) {D};

  \draw (A) -- (B) node [midway] {x};
  \draw (C) -- (D) node [midway] {x};

  \node at ({$(A)!.5!(B)$} -| {$(C)!.5!(D)$}) {X};
\end{tikzpicture}

от одной средней точки возьмем координату X от другой Y и напишем метку X.

perprn

10 - Диаграммы в Latex библиотека TIKZ

Возможности библиотеки TIKZ для рисования графиков в Latex

Возможности библиотеки TIKZ для рисования графиков в Latex. Обзор учебника из документации.

Библиотеки для работы с диаграммами

\usetikzlibrary {
positioning,% нативные позиции node
shapes.misc, % настройка внешнего вида фигур, углы и т.д.
graphs, % работает с диаграммами и графами
calc, % считает координаты
arrows.meta % рисует наконечники стрел
}

Стилизация узлов диаграммы

Простой прямоугольник (Не-Терминал)

\usetikzlibrary {positioning}
\begin{tikzpicture}[
    nonterminal/.style={
      % The shape:
      rectangle,
      % The size:
      minimum size=6mm,
      % The border:
      very thick,
      draw=red!50!black!50,         % 50% red and 50% black,
                                    % and that mixed with 50% white
      % The filling:
      top color=white,              % a shading that is white at the top...
      bottom color=red!50!black!20, % and something else at the bottom
      % Font
      font=\itshape
    }]
  \node [nonterminal] {unsigned integer};
\end{tikzpicture}

В стиле определил:

  • rectangle
  • minimum size
  • border — красночерного цвета толстый бордюр
  • filling — градиент top и bottom
  • font

Для рисования просто пишу NODE и все готово st1

Стиль терминалов с круглыми углами

\usetikzlibrary {positioning}
\begin{tikzpicture}[node distance=5mm,
                    terminal/.style={
                      % The shape:
                      rectangle,minimum size=6mm,rounded corners=3mm,
                      % The rest
                      very thick,draw=black!50,
                      top color=white,bottom color=black!20,
                      font=\ttfamily}]
  \node (dot)   [terminal]                {.};
  \node (digit) [terminal,right=of dot]   {digit};
  \node (E)     [terminal,right=of digit] {E};
\end{tikzpicture}

Как приятно писать что-то, когда ты понимаешь, что ты это понимаешь)))

В стиле определено:

  • node distance — это значит,что расстояние между node будет, то, которое задано.
  • terminal — название стиля
  • rectangle — форма
  • minimum size
  • rounded corners — радиус закругления углов (закругляет у любой фигуры \node, \fill, \path)
  • very thick — толщина обводки
  • top, bottom — градиент заливки
  • font

Односимвольный терминал станет кругом, а многосимвольный — прямоугольником с закругленными углами.

st2

Использование библиотеки shapes.misc

Только немного изменится настройка в описании стиля

[node distance=5mm,
                    terminal/.style={
                      % The shape:
                      rounded rectangle,
                      minimum size=6mm,
                      % The rest
                      very thick,draw=black!50,
                      top color=white,bottom color=black!20,
                      font=\ttfamily}]

убрали rounded corners а поставили rounded rectangle — собственно и все. Но разметка слегка отъехала. На рисунке можно увидеть небольшую разницу.

Выравнивание текста в терминалах

Просто добавляем в стиль высоту и глубину строки [text height=1.5ex,text depth=.25ex]

Полезная библиотека позиционирования

\usetikzlibrary {positioning,shapes.misc}
\begin{tikzpicture}[node distance=5mm and 5mm]
  \node (ui1)   [nonterminal]                     {unsigned integer};
  \node (dot)   [terminal,right=of ui1]           {.};
  \node (digit) [terminal,right=of dot]           {digit};
  \node (E)     [terminal,right=of digit]         {E};
  \node (plus)  [terminal,above right=of E]       {+};
  \node (minus) [terminal,below right=of E]       {-};
  \node (ui2)   [nonterminal,below right=of plus] {unsigned integer};
\end{tikzpicture}

основные команды:

  • right=of
  • left=of
  • above=of
  • below=of
  • above right=of
  • и т.д.

Перенесем настройки стилей в преамбулу документа

\tikzset {terminal/.style={
                      % The shape:
                      rectangle,minimum size=6mm,rounded corners=3mm,
                      % The rest
                      very thick,draw=black!50,
                      top color=white,bottom color=black!20,
                      font=\ttfamily}}
\tikzset {nonterminal/.style={
      % The shape:
      rectangle,
      % The size:
      minimum size=6mm,
      % The border:
      very thick,
      draw=red!50!black!50,         % 50% red and 50% black,
                                    % and that mixed with 50% white
      % The filling:
      top color=white,              % a shading that is white at the top...
      bottom color=red!50!black!20, % and something else at the bottom
      % Font
      font=\itshape
    }}

Теперь будет действовать глобально на всех.

Рисуем стрелки

\usetikzlibrary {calc,positioning,shapes.misc}
\begin{tikzpicture}[node distance=5mm and 5mm,
    skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}]
  \node (dot)   [terminal]                        {.};
  \node (digit) [terminal,right=of dot]           {digit};
  \node (E)     [terminal,right=of digit]         {E};

  \path (dot)   edge[->]                (digit)  % simple edges
        (digit) edge[->]                (E)
        ($ (digit.east)!.5!(E.west) $)
                edge[->,skip loop=-5mm] ($ (digit.west)!.5!(dot.east) $);
\end{tikzpicture}

Разберем кривую стрелку

($ (digit.east)!.5!(E.west) $)
                edge[->,skip loop=-5mm] ($ (digit.west)!.5!(dot.east) $);

т.е. от середины между метками (digit.east)!.5!(E.west) до середины между метками (digit.west)!.5!(dot.east) рисуем кривулину типа skip loop

st4

Пока все довольны.

Но разобрать по частям стиль skip loop очень хочется: skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}

  • первая часть понятна: от текущей точке рисуем линию вертикально на заданный параметр #1, а потом
  • -| — рисует горизонтально, а потом вертикально к цели, это один из родственников -- — рисует прямую; |-— рисует вертикально и горизонтально и .. — рисует кривую
  • возвращаемся к поставленной цели (\tikztotarget) вообще таких макросов три (\tikztostart, \tikztotarget, and \tikztonodes;)

Матрицы

\usetikzlibrary {shapes.misc}
\begin{tikzpicture}
  \matrix[row sep=1mm,column sep=5mm] {
    % First row:
      & & & & \node [terminal] {+}; & \\
    % Second row:
    \node [nonterminal] {unsigned integer}; &
    \node [terminal]    {.};                &
    \node [terminal]    {digit};            &
    \node [terminal]    {E};                &
                                            &
    \node [nonterminal] {unsigned integer}; \\
    % Third row:
      & & & & \node [terminal] {-}; & \\
  };
\end{tikzpicture}

Пока \matrix представляет собой что-то вроде таблицы, со своими дополнениями.

  • row sep — расстояние между строками
  • column sep — расстояние между столбцами

Дальше обычная tabular.

st5

Промежуточная задача с узлами привязки

\usetikzlibrary {shapes.misc}
\begin{tikzpicture}[point/.style={circle,inner sep=0pt,minimum size=2pt,fill=red},
                   skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}]
  \matrix[row sep=1mm,column sep=2mm] {
    % First row:
    & & & & & & &  & & & & \node (plus) [terminal] {+};\\
    % Second row:
    \node (p1) [point]  {}; &    \node (ui1)   [nonterminal] {unsigned integer}; &
    \node (p2) [point]  {}; &    \node (dot)   [terminal]    {.};                &
    \node (p3) [point]  {}; &    \node (digit) [terminal]    {digit};            &
    \node (p4) [point]  {}; &    \node (p5)    [point]  {};                      &
    \node (p6) [point]  {}; &    \node (e)     [terminal]    {E};                &
    \node (p7) [point]  {}; &                                                    &
    \node (p8) [point]  {}; &    \node (ui2)   [nonterminal] {unsigned integer}; &
    \node (p9) [point]  {}; &    \node (p10)   [point]       {};\\
    % Third row:
    & & & & & & &  & & & & \node (minus)[terminal] {-};\\
  };

  \path (p4) edge [->,skip loop=-5mm] (p3)
        (p2) edge [->,skip loop=5mm]  (p6);
\end{tikzpicture}
  1. Описываем стиль [point/.style={circle,inner sep=0pt,minimum size=2pt,fill=red}]
  2. Расставляем точки в матрице и даем им имена: \node (p1) [point] {};
  3. Соединяем точки edge (p4) edge [->,skip loop=-5mm] (p3)

Частично задача решена. Вторым этапом убираем видимость точек и результат готов.

Команда GRAPH (библиотека graphs)

Это еще одна мощная команда, которая должна со всем этим хозяйством управиться.

\begin{tikzpicture}[skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}},
                    point/.style={circle,inner sep=0pt,minimum size=2pt,fill=red},
                    hv path/.style={to path={-| (\tikztotarget)}},
                    vh path/.style={to path={|- (\tikztotarget)}}]
  \matrix[row sep=1mm,column sep=2mm] {
    % First row:
    & & & & & & &  & & & & \node (plus) [terminal] {+};\\
    % Second row:
    \node (p1) [point]  {}; &    \node (ui1)   [nonterminal] {unsigned integer}; &
    \node (p2) [point]  {}; &    \node (dot)   [terminal]    {.};                &
    \node (p3) [point]  {}; &    \node (digit) [terminal]    {digit};            &
    \node (p4) [point]  {}; &    \node (p5)    [point]  {};                      &
    \node (p6) [point]  {}; &    \node (e)     [terminal]    {E};                &
    \node (p7) [point]  {}; &                                                    &
    \node (p8) [point]  {}; &    \node (ui2)   [nonterminal] {unsigned integer}; &
    \node (p9) [point]  {}; &    \node (p10)   [point]       {};\\
    % Third row:
    & & & & & & &  & & & & \node (minus)[terminal] {-};\\
};

  \graph {
    (p1) -> (ui1) -- (p2) -> (dot) -- (p3) -> (digit) -- (p4)
         -- (p5)  -- (p6) -> (e) -- (p7) -- (p8) -> (ui2) -- (p9) -> (p10);
    (p4) ->[skip loop=-5mm]  (p3);
    (p2) ->[skip loop=5mm]   (p5);
    (p6) ->[skip loop=-11mm] (p9);
    (p7) ->[vh path]         (plus)  -> [hv path] (p8);
    (p7) ->[vh path]         (minus) -> [hv path] (p8);
  };
\end{tikzpicture}

st6

Завершаем оформление и добавляем стрелочки

Библиотека arrows.meta: и вариант работы p7 ->[vh path] { plus, minus } -> [hv path] p8; библиотеки graphs по раздвоению стрелок. Просто перечисляем узлы в фигурных скобках.

Итоговый вариант:

\begin{tikzpicture}[skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}},
                    point/.style={circle,inner sep=0pt,minimum size=2pt,fill=red},
                    >={Stealth[round]},thick,black!50,text=black,
                    every new ->/.style={shorten >=1pt},
                    graphs/every graph/.style={edges=rounded corners},
                    hv path/.style={to path={-| (\tikztotarget)}},
                    vh path/.style={to path={|- (\tikztotarget)}}]
  \matrix[column sep=4mm] {
    % First row:
    & & & & & & &  & & & & \node (plus) [terminal] {+};\\
    % Second row:
    \node (p1) [point]  {}; &    \node (ui1)   [nonterminal] {unsigned integer}; &
    \node (p2) [point]  {}; &    \node (dot)   [terminal]    {.};                &
    \node (p3) [point]  {}; &    \node (digit) [terminal]    {digit};            &
    \node (p4) [point]  {}; &    \node (p5)    [point]  {};                      &
    \node (p6) [point]  {}; &    \node (e)     [terminal]    {E};                &
    \node (p7) [point]  {}; &                                                    &
    \node (p8) [point]  {}; &    \node (ui2)   [nonterminal] {unsigned integer}; &
    \node (p9) [point]  {}; &    \node (p10)   [point]       {};\\
    % Third row:
    & & & & & & &  & & & & \node (minus)[terminal] {-};\\
};

  \graph [use existing nodes] {
    p1 -> ui1 -- p2 -> dot -- p3 -> digit -- p4 -- p5  -- p6 -> e -- p7 -- p8 -> ui2 -- p9 -> p10;
    p4 ->[skip loop=-5mm]  p3;
    p2 ->[skip loop=5mm]   p5;
    p6 ->[skip loop=-11mm] p9;
    p7 ->[vh path] { plus, minus } -> [hv path] p8;

};
\end{tikzpicture}

st8

Более серьезное погужение в GRAPHs

\tikz \graph [grow right=2cm] { unsigned integer -> d -> digit -> E };

выдаст сразу: st9

Добавим стилей:

\tikz \graph [grow right sep] {
  unsigned integer[nonterminal] -> "."[terminal] -> digit[terminal] -> E[terminal]
};

st10

Добавим + и -:

\usetikzlibrary {graphs,shapes.misc}
\tikz \graph [grow right sep] {
  unsigned integer  [nonterminal] ->
  "."               [terminal] ->
  digit             [terminal] ->
  E                 [terminal] ->
  {
    "+"             [terminal],
    ""              [coordinate],
    "-"             [terminal]
  } ->
  ui2/unsigned integer [nonterminal]
};

st11

Окончательный вариант через Graphs

\usetikzlibrary {arrows.meta,graphs,shapes.misc}
\tikz [>={Stealth[round]}, black!50, text=black, thick,
       every new ->/.style = {shorten >=1pt},
       graphs/every graph/.style = {edges=rounded corners},
       skip loop/.style = {to path={-- ++(0,#1) -| (\tikztotarget)}},
       hv path/.style = {to path={-| (\tikztotarget)}},
       vh path/.style = {to path={|- (\tikztotarget)}},
       nonterminal/.style = {
         rectangle, minimum size=6mm, very thick, draw=red!50!black!50, top color=white,
         bottom color=red!50!black!20, font=\itshape, text height=1.5ex,text depth=.25ex},
       terminal/.style = {
         rounded rectangle,  minimum size=6mm, very thick, draw=black!50, top color=white,
         bottom color=black!20, font=\ttfamily, text height=1.5ex, text depth=.25ex},
       shape = coordinate
       ]
  \graph [grow right sep, branch down=7mm, simple] {
    / -> unsigned integer[nonterminal] -- p1 -> "." [terminal] -- p2 -> digit[terminal] --
    p3 -- p4 -- p5 -> E[terminal] -- q1 ->[vh path]
    {[nodes={yshift=7mm}]
      "+"[terminal], q2, "-"[terminal]
    } -> [hv path]
    q3 -- /unsigned integer [nonterminal] -- p6 -> /;

    p1 ->[skip loop=5mm]   p4;
    p3 ->[skip loop=-5mm]  p2;
    p5 ->[skip loop=-11mm] p6;

    q1 -- q2 -- q3;  % make these edges plain
  };
  

st12

Особенности кода:

  • использовании групп, при делении веток, группы заключаем в {}
  • анонимные координаты обозначаются /
  • simpe — свойство graph — которое определяем, что между 2-мя узлами может быть только 1 edge.
  • graphs/every graph/.style = {edges=rounded corners} — закругленные уголки у стрелок
  • >={Stealth[round]}, black!50, text=black, thick, — стиль стрелок

11 - Примеры по Эвклиду

Продолжаем осваивать библиотеку TIKZ и изучаем новые команды

Установка необходимых библиотек для работы

\documentclass{article} % say

% For LaTeX:
\usepackage{tikz}
\usetikzlibrary{calc,intersections,through,backgrounds}

\begin{tikzpicture}
  \coordinate [label=left:\textcolor{blue}{$A$}]  (A) at (0,0);
  \coordinate [label=right:\textcolor{blue}{$B$}] (B) at (1.25,0.25);

  \draw[blue] (A) -- (B);
\end{tikzpicture}

Мощь библиотеки calc

\begin{tikzpicture}
  \coordinate [label=left:\textcolor{blue}{$A$}] (A) at ($ (0,0) + .1*(rand,rand) $);
  \coordinate [label=right:\textcolor{red}{$B$}] (B) at ($ (1.25,0.25) + .1*(rand,rand) $);
 
  \draw[blue] (A) -- (B);
\end{tikzpicture}

Все вычисления происходят между двух символов $.

Особенность оператора rand, что он каждый раз будет вычисляться одинаково. Т.е. не такой он уж и случайное число.

Оператор let и команда veclen

\usetikzlibrary {calc}
\begin{tikzpicture}
  \coordinate [label=left:$A$]  (A) at (0,0);
  \coordinate [label=right:$B$] (B) at (1.25,0.25);
  \draw (A) -- (B);

  \draw (A) let
              \p1 = ($ (B) - (A) $)
            in
              circle ({veclen(\x1,\y1)});
\end{tikzpicture}

st1

  • \p1 = ($ (B) - (A) $) вычислит длину вектора и запишет в переменную 1
  • p — это команда записать точку (коорд.x, коорд.y)
  • veclen(\x1,\y1) — соответственно передать коордитаты x и y из переменной 1 и вычислить их длину для радиуса.
  • n — похожа на p, но записывает число.

т.е. let определил p1 и передал in в circle

\usetikzlibrary {calc}
\begin{tikzpicture}
 \coordinate [label=left:$A$]  (A) at (0,0);
 \coordinate [label=right:$B$] (B) at (1.25,0.25);
 \draw (A) -- (B);

 \draw let \p1 = ($ (B) - (A) $),
           \n2 = {veclen(\x1,\y1)}
       in
         (A) circle (\n2)
         (B) circle (\n2);
\end{tikzpicture}

в этом примере, как раз вычисленный радиус, записали в переменную 2. Вместо цифры в этих переменных можно использовать длинные имена в скобках n{ragius} и также их использовать circle (\n{radius})

Библиотека THROUGH

Создадим окружность через точку B относительно A, находящейся в центре координат. Т.е. точку A он всегда будет считать центром.

\usetikzlibrary {through}
\begin{tikzpicture}
  \coordinate [label=left:$A$]  (A) at (0,0);
  \coordinate [label=right:$B$] (B) at (1.25,0.25);
  \draw (A) -- (B);

  \node [draw,circle through=(B),label=left:$D$] at (A) {};
\end{tikzpicture}

st2

Библиотека INTERSECTION

\usetikzlibrary {intersections,through}
\begin{tikzpicture}
  \coordinate [label=left:$A$]  (A) at (0,0);
  \coordinate [label=right:$B$] (B) at (1.25,0.25);
  \draw (A) -- (B);

  \node (D) [name path=D,draw,circle through=(B),label=left:$D$]  at (A) {}; %нода D и путь D это разные объекты, можно называть по разному
  \node (E) [name path=E,draw,circle through=(A),label=right:$E$] at (B) {};

  % Name the coordinates, but do not draw anything:
  \path [name intersections={of=D and E}];

  \coordinate [label=above:$C$] (C) at (intersection-1);

  \draw [red] (A) -- (C);
  \draw [red] (B) -- (C);
\end{tikzpicture}

st3

  • \node (D) [name path=D,draw,circle through=(B),label=left:$D$] задаем имя \path где проходит окружность.
  • \path [name intersections={of=D and E}]; — определяем пересечение двух путей D и E и у них образуются точки пересечения как (intersection-1) и (intersection-2).
  • \coordinate [label=above:$C$] (C) at (intersection-1); — определим точку C с координатами пересечения.

но есть еще у name intersections команда by, которая все это решит автоматически: \path [name intersections={of=D and E, by={[label=above:$C$]C, [label=below:$C'$]C'}}]; т.е. поставит точки и метки в них.

Потом просто проведем линию и дадим ей тоже имя \path \draw [name path=C--C',red] (C) -- (C'); имя будет C--C'.

Новый intersection получит точку F

\path [name intersections={of=A--B and C--C',by=F}];

\begin{tikzpicture}
 \coordinate [label=left:$A$]  (A) at (0,0);
 \coordinate [label=right:$B$] (B) at (1.25,0.25);
 \draw [name path=A--B] (A) -- (B);

 \node (D) [name path=D,draw,circle through=(B),label=left:$D$]  at (A) {};
 \node (E) [name path=E,draw,circle through=(A),label=right:$E$] at (B) {};

 \path [name intersections={of=D and E, by={[label=above:$C$]C, [label=below:$C'$]C'}}];

 \draw [name path=C--C',red] (C) -- (C');

 \path [name intersections={of=A--B and C--C',by=F}];
 \node [fill=red,inner sep=2pt,label=-45:$F$] at (F) {};
\end{tikzpicture}

это полная картина, где из нового inner sep=2pt — это толщина точки пересечения, а на самом деле просто размер node в виде точки

st5

если бы я написал \node [fill=red,circle, inner sep=2pt,label=-45:$F$] at (F) {}; то получилось бы:

st6

Разукрашки и определение макросов

\begin{tikzpicture}[
  thick,% толстые линии
  help lines/.style={thin,draw=black!50}]%вспомогательные линии
  \def\A{\textcolor{input}{$A$}} % макросы ABCDE со стилями меток
  \def\B{\textcolor{input}{$B$}} 
  \def\C{\textcolor{output}{$C$}}    
  \def\D{$D$}
  \def\E{$E$}

  \colorlet{input}{blue!80!black} % input и output цвета, которые подставятся в макросы
  \colorlet{output}{red!70!black}
  \colorlet{triangle}{orange}

Наарисуем треугольник

\draw [output] (A) -- (C) -- (B);

Поставим в вершинах точки

\foreach \point in {A,B,C}
    \fill [black,opacity=.5] (\point) circle (2pt);

Закрасим треугольник

  \begin{pgfonlayer}{background}
    \fill[triangle!80] (A) -- (C) -- (B) -- cycle;
  \end{pgfonlayer}

Итоговый код

\usetikzlibrary {backgrounds,calc,intersections,through}
\begin{tikzpicture}[thick,help lines/.style={thin,draw=black!50}]
  \def\A{\textcolor{input}{$A$}}     \def\B{\textcolor{input}{$B$}}
  \def\C{\textcolor{output}{$C$}}    \def\D{$D$}
  \def\E{$E$}

  \colorlet{input}{blue!80!black}    \colorlet{output}{red!70!black}
  \colorlet{triangle}{orange}

  \coordinate [label=left:\A]  (A) at ($ (0,0) + .1*(rand,rand) $);
  \coordinate [label=right:\B] (B) at ($ (1.25,0.25) + .1*(rand,rand) $);

  \draw [input] (A) -- (B);

  \node [name path=D,help lines,draw,label=left:\D]   (D) at (A) [circle through=(B)] {};
  \node [name path=E,help lines,draw,label=right:\E]  (E) at (B) [circle through=(A)] {};

  \path [name intersections={of=D and E,by={[label=above:\C]C}}];

  \draw [output] (A) -- (C) -- (B);

  \foreach \point in {A,B,C}
    \fill [black,opacity=.5] (\point) circle (2pt);

  \begin{pgfonlayer}{background}
    \fill[triangle!80] (A) -- (C) -- (B) -- cycle;
  \end{pgfonlayer}

  \node [below right, text width=10cm,align=justify] at (4,3) {
    \small\textbf{Proposition I}\par
    \emph{To construct an \textcolor{triangle}{equilateral triangle}
      on a given \textcolor{input}{finite straight line}.}
    \par\vskip1em
    Let \A\B\ be the given \textcolor{input}{finite straight line}.  \dots
  };
\end{tikzpicture}

st6

Мой первый прямоугольник с почти умными координатами

\begin{tikzpicture}
  \coordinate (NW) at (0,5); \coordinate (nw) at ($ (NW) + (1,-1) $);
  \coordinate (NE) at (7,5); \coordinate (ne) at ($ (NE) + (-1,-1) $);
  \coordinate (SE) at (7,0); \coordinate (se) at ($ (SE) + (-1,1) $);
  \coordinate (SW) at (0,0); \coordinate (sw) at ($ (SW) + (1,1) $);
\draw[black!10] (NW) -- (NE) -- (SE) -- (SW) -- cycle;
\draw[black!30, thick, fill=black!25] ($ (NW) + (1,-1) $) -- (ne) -- (se) -- (sw) -- cycle;
\fill[black!25] (nw) -- (ne) -- (se) -- (sw) -- cycle;
\end{tikzpicture}

st7

Немного неказист, но многообещающь.

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

Продолжение сериала по Эвклиду.

Найдем точку между координатами

Это будет ровно посередине между A и B.

\usetikzlibrary {calc}
\begin{tikzpicture}
  \coordinate [label=left:$A$]  (A) at (0,0);
  \coordinate [label=right:$B$] (B) at (1.25,0.25);
  \draw (A) -- (B);
  \node [fill=red,inner sep=1pt,label=below:$X$] (X) at ($ (A)!.5!(B) $) {};
\end{tikzpicture}

Это для убедительности: st8

Или за пределами точек и даже сложные вычисления: \coordinate [label=above:$D$] (D) at ($ (A) ! .5 ! (B) ! {sin(60)*2} ! 90:(B) $) {};

И еще пример, чисто как памятка, потому-что очень сложные вычисления, мне точно не нужны.

\draw (D) -- ($ (D) ! 2.5 ! (A) $) coordinate [label=below:$E$] (E); — начертит прямую и установит новую точку E

12 - Сети PETRI

Сети петри для ознакомления с возможностями NODE и настройки своих стилей.

Установка необходимых библиотек для работы

\documentclass{article} % say

\usepackage{tikz}
\usetikzlibrary{arrows.meta,decorations.pathmorphing,backgrounds,positioning,fit,petri}

\begin{document}
\begin{tikzpicture}
  \draw (0,0) -- (1,1);
\end{tikzpicture}
\end{document}

Просто нарисуем в системе координат 5 node

\begin{tikzpicture}
  \path ( 0,2) node [shape=circle,draw] {}
        ( 0,1) node [shape=circle,draw] {}
        ( 0,0) node [shape=circle,draw] {}
        ( 1,1) node [shape=rectangle,draw] {}
        (-1,1) node [shape=rectangle,draw] {};
\end{tikzpicture}

Но, выяснилось, что вариант выше не очень умен по своей сути. \path задает координату откуда начинается какое-то действие, в нашем случае размещаем node, а можно draw, но node с параметром draw обернет текст рамкой.

Синтаксис at т.е. поместить в…

step1

\begin{tikzpicture}
  \path node at ( 0,2) [shape=circle,draw] {}
        node at ( 0,1) [shape=circle,draw] {}
        node at ( 0,0) [shape=circle,draw] {}
        node at ( 1,1) [shape=rectangle,draw] {}
        node at (-1,1) [shape=rectangle,draw] {};
\end{tikzpicture}

Получаем тотже эффект, но говорят умнее.

Дальше больше:

\begin{tikzpicture}
  \path node at ( 0,2) [circle,draw] {}
        node at ( 0,1) [circle,draw] {}
        node at ( 0,0) [circle,draw] {}
        node at ( 1,1) [rectangle,draw] {}
        node at (-1,1) [rectangle,draw] {};
\end{tikzpicture}

Прикручиваем стили

\begin{tikzpicture}[thick]
  \path  node at ( 0,2) [circle,draw=blue,fill=red] {}
         node at ( 0,1) [circle,draw=blue,fill=yellow] {}
         node at ( 0,0) [circle,draw=blue,fill=green] {}
         node at ( 1,1) [rectangle,draw=black!50,fill=black!20] {}
         node at (-1,1) [rectangle,draw=black!50,fill=black!20] {};
\end{tikzpicture}

step2 Причем [draw=blue] — рисует такого цвета обводку, а fill — заполняет пространство

А теперь сделаем стиль универсальным на блок

\begin{tikzpicture}
  [place/.style={circle,draw=blue!50,fill=blue!20,thick},
   transition/.style={rectangle,draw=black!50,fill=black!20,thick}]
  \node at ( 0,2) [place] {};
  \node at ( 0,1) [place] {};
  \node at ( 0,0) [place] {};
  \node at ( 1,1) [transition] {};
  \node at (-1,1) [transition] {};
\end{tikzpicture}

просто один будет называться place а второй transition и теперь название этихстилей ставим в описании node.

Размеры SHAPE

Можно задать переменную inner sep=2mm в блоке — и это сделает отступ вокруг текста 2mm. Или:

[place/.style={circle,draw=blue!50,fill=blue!20,thick,
                 inner sep=0pt,minimum size=6mm},

т.е прямо в стиль и это даст эффект, что размер будет не меньше 4мм, пока в него влезает текст.

step3

Имена SHAPEs

Очень пригодятся имена SHAPEs для того,чтобы иметь привязки и потом на них ссылаться.

\begin{tikzpicture}
  \node (waiting 1)      at ( 0,2) [place] {};
  \node (critical 1)     at ( 0,1) [place] {};
  \node (semaphore)      at ( 0,0) [place] {};
  \node (leave critical) at ( 1,1) [transition] {};
  \node (enter critical) at (-1,1) [transition] {};
\end{tikzpicture}

имена будут в круглых скобочках, причем порядок написания не имеет значения. Это все определения одного \path

Нативное размещение SHAPEs

Вместо указания координат, можно указывать влево, вправо, ниже, выше. Такого ума можно набраться в библиотеке: \usetikzlibrary {positioning}

\usetikzlibrary {positioning}
\begin{tikzpicture}
  \node[place]      (waiting)                            {};
  \node[place]      (critical)       [below=of waiting]  {}; % ниже waitinig
  \node[place]      (semaphore)      [below=of critical] {}; % ниже critical
  \node[transition] (leave critical) [right=of critical] {}; % справа от critical
  \node[transition] (enter critical) [left=of critical]  {}; % слева от critical
\end{tikzpicture}

Объекты размещаются по координатной сетке.

Метки объектов по сторонам света

Все объекты TIKZ получают метки по сторонам света:

  • north
  • south
  • west
  • east
  • north east
  • north west
  • south east
  • south west
 \node [red,above] at (semaphore.north) {$s\le 3$};
\end{tikzpicture}

напишет node красного цвета red над above северной меткой объекта semaphore.

но в библиотеке есть вариант с label, который сделает тоже самое.

  \node[place] (semaphore) [below=of critical, 
                             label=above:$s\le3$] {};

Памятка, как label работает:

\tikz
  \node [circle,draw,label=60:$60^\circ$,label=below:$-90^\circ$] {my circle};

step4

И немного подольем красочки: label={[red]below:$-90^\circ$} и будет метка красная, но чтобы небыло конфлика поставим все это дело в {}.

Коннекторы это просто

  \draw [->] (enter critical.east) -- (critical.west);
  \draw [->] (waiting.west) .. controls +(left:5mm) and +(up:5mm)
                            .. (enter critical.north);

т.е. \draw [в какую сторону стрелу] (координата откуда) -- (координата куда);

Краткий комментарий к .. CONTROLS ..

Это вставка вместо оператора рисования - -, которая позволяет поставить несколько контрольных точек относительно некоторого центра вращения и сказать куда они сдвигаются и насколько:

\draw[->](waiting.west) ..controls +(left:15mm) and +(up:15mm) .. (enter critical.north);

step5

Умность библиотеки tirz

Можно не указывать стороны света в метках, от сделает это автоматически

  \draw [->] (enter critical) -- (critical);
  \draw [->] (waiting) .. controls +(left:5mm) and +(up:5mm)
                            .. (enter critical);

будет тоже самое.

Совершенствуем стрелочки до предела (to [in out])

Замечательный оператор to, который укажет под каким углом выйти и под каким углом войти стрелке.

Схема такая же, только вместо наших - - и .. controls .. появляется еще один оператор to [out=,in=]

in=220 — выглядит еще причудлевее.

\draw[->](waiting) to [out=0, in=180] (leave critical)

step6

Команда bend right left

изгиб кривой.

\draw[->](leave critical) to [bend left=150] (semaphore)

step7

но лучше загибать bend left=45, правда лучше.

Теперь еще один элемент EDGE

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

 \node[transition] (enter critical) [left=of critical]  {}
    edge [->]               (critical)
    edge [<-,bend left=45]  (waiting)
    edge [->,bend right=45] (semaphore);

буквально: там где нарисовал node от неё начинаю рисовать edges.

  • не завершая node точкой с запятой пишем edge
  • [здесь команды куда стрела, как гнуть]
  • (куда соединяем)
  • теперь текущая точка опять в пункте node
  • продолжаем рисовать дальше от той же точки

Вот такой казус может получиться:

\begin{tikzpicture}
  \node (c) at (0,0) {};
  \node (n) at (0,1) {}
  edge [bend right=45] (w);
  \node (s) at (0,-1) {}
  edge [bend right=45] (e);
  \node (w) at (-1,0) {}
  edge [bend right=45] (s);
  \node (e) at (1,0) {}
   edge [->,bend right=45] (n);
\end{tikzpicture}

step8

Но если рисовать по задумке:

\begin{tikzpicture}
  \node (c) at (0,0) {};
  \node (n) at (0,1) {};
  \node (w) at (-1,0) {}
  edge [bend left=45] (n);
  \node (s) at (0,-1) {}
  edge [bend left=45] (w);
  \node (e) at (1,0) {}
   edge [bend left=45] (s)
   edge [bend right=45] (n);
\end{tikzpicture}

то получим -> step9

И все это упакуем в стили

  [bend angle=45,
   pre/.style={<-,shorten <=1pt,>={Stealth[round]},semithick},
   post/.style={->,shorten >=1pt,>={Stealth[round]},semithick}]

вот такая штука позволит дальше в коде писать просто:

edge [pre] (critical) и edge [post,bend right] (waiting) и TIKZ все поймет.

Метки на линиях

\begin{tikzpicture}[auto,bend right]
  \node (a) at (0:1) {$0^\circ$};
  \node (b) at (120:1) {$120^\circ$};
  \node (c) at (240:1) {$240^\circ$};

  \draw (a) to node {1} node [swap] {1'} (b)
        (b) to node {2} node [swap] {2'} (c)
        (c) to node {3} node [swap] {3'} (a);
\end{tikzpicture}

step10

  • NODE — нарисовали метки в узлах через оператор at, т.е. поместить в … конкретную точку
  • DRAW — рисует через оператор to, т.е. от одной точки к другой, а на пути его рисования мы размещаем другие NODE и говорим с какой стороны их рисовать относительно линии.
  • SWAP — это нарисовать зеркально
  • на пути DRAW, NODEs может быть сколько угодно, главное их всех разместить правильно, а то все в одну точку вляпаются.

Декоративные линии (\usetikzlibrary {decorations.pathmorphing})

Собственно любую линию можно нарисовать, просто отдельно нужно изучить особенности этой библиотеки.

\usetikzlibrary {decorations.pathmorphing}
\begin{tikzpicture}
  \draw [->,decorate,
     decoration={snake,amplitude=.4mm,segment length=2mm,post length=1mm}]
    (0,0) -- (3,0);
\end{tikzpicture}

получится вот такая кривулина: step11

И продолжая тему кривулины или любой другой линии, если мне нужно разместить текст, то делаю в разрыве DRAW вставку NODE:

node [above,text width=3cm,align=center,midway]
    {
      replacement of the \textcolor{red}{capacity} by
      \textcolor{red}{two places}
    }
  • above — выше над линией
  • text width=3cm — ширина текста 3см
  • align-center — текст выравнять по центру
  • midway — в центре линии (у него еще есть братья:
    • near start — pos=0.25.
    • near end — pos=0.75.
    • very near start — pos=0.125.
    • very near end — pos=0.875.
    • at start — pos=0.
    • at end — pos=1

BACKGROUND или слои и фон под картинкой

Нам поможет библиотека fit и background

fit — дает координаты всех узлов background — размещает на разных слоях рисунки

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

\begin{tikzpicture}[ultra thick]
  \begin{scope}[red]
    \draw (0mm,10mm) -- (10mm,10mm);
    \draw (0mm,8mm) -- (10mm,8mm);
  \end{scope}
  \draw (0mm,6mm) -- (10mm,6mm);
  \begin{scope}[green]
    \draw (0mm,4mm) -- (10mm,4mm);
    \draw (0mm,2mm) -- (10mm,2mm);
    \draw[blue] (0mm,0mm) -- (10mm,0mm);
  \end{scope}
\end{tikzpicture}

этот пример на линиях все показал step12

а про background мы просто добавим в конце такой код:

 \begin{scope}[on background layer]
    \node [fill=black!30,fit=(waiting) (critical) (semaphore)
             (leave critical) (enter critical)] {};
  \end{scope}
  • on background layer — на каком слое разместить, т.е. под рисунком
  • \node — рисуем node
  • fill — заполняем ее цветом
  • fit — перечисляем все внутренние node по которым определяем координаты

Настройки стандартных библиотек для рисования сетей PETRI

\begin{tikzpicture}
  [node distance=1.3cm,on grid,>={Stealth[round]},bend angle=45,auto,
   every place/.style= {minimum size=6mm,thick,draw=blue!75,fill=blue!20},
   every transition/.style={thick,draw=black!75,fill=black!20},
   red place/.style= {place,draw=red!75,fill=red!20},
   every label/.style= {red}]

т.е. там уже все определено, поэтому нарисуем все, что уже пытались с использованием библиотеки:

\usetikzlibrary {arrows.meta,petri,positioning}
   \node [place,tokens=1] (w1)                                    {};
   \node [place]          (c1) [below=of w1]                      {};
   \node [place]          (s)  [below=of c1,label=above:$s\le 3$] {};
   \node [place]          (c2) [below=of s]                       {};
   \node [place,tokens=1] (w2) [below=of c2]                      {};

   \node [transition] (e1) [left=of c1] {}
     edge [pre,bend left]                  (w1)
     edge [post,bend right]                (s)
     edge [post]                           (c1);
   \node [transition] (e2) [left=of c2] {}
     edge [pre,bend right]                 (w2)
     edge [post,bend left]                 (s)
     edge [post]                           (c2);
   \node [transition] (l1) [right=of c1] {}
     edge [pre]                            (c1)
     edge [pre,bend left]                  (s)
     edge [post,bend right] node[swap] {2} (w1);
   \node [transition] (l2) [right=of c2] {}
     edge [pre]                            (c2)
     edge [pre,bend right]                 (s)
     edge [post,bend left]  node {2}       (w2);

а это ее более кудрявый друг:

\usetikzlibrary {arrows.meta,petri,positioning}
 \begin{scope}[xshift=6cm]
   \node [place,tokens=1]     (w1')                            {};
   \node [place]              (c1') [below=of w1']             {};
   \node [red place]          (s1') [below=of c1',xshift=-5mm]
           [label=left:$s$]                                    {};
   \node [red place,tokens=3] (s2') [below=of c1',xshift=5mm]
           [label=right:$\bar s$]                              {};
   \node [place]              (c2') [below=of s1',xshift=5mm]  {};
   \node [place,tokens=1]     (w2') [below=of c2']             {};

   \node [transition] (e1') [left=of c1'] {}
     edge [pre,bend left]                  (w1')
     edge [post]                           (s1')
     edge [pre]                            (s2')
     edge [post]                           (c1');
   \node [transition] (e2') [left=of c2'] {}
     edge [pre,bend right]                 (w2')
     edge [post]                           (s1')
     edge [pre]                            (s2')
     edge [post]                           (c2');
   \node [transition] (l1') [right=of c1'] {}
     edge [pre]                            (c1')
     edge [pre]                            (s1')
     edge [post]                           (s2')
     edge [post,bend right] node[swap] {2} (w1');
   \node [transition] (l2') [right=of c2'] {}
     edge [pre]                            (c2')
     edge [pre]                            (s1')
     edge [post]                           (s2')
     edge [post,bend left]  node {2}       (w2');
 \end{scope}

и на финише фон:

  \begin{scope}[on background layer]
    \node (r1) [fill=black!10,rounded corners,fit=(w1)(w2)(e1)(e2)(l1)(l2)] {};
    \node (r2) [fill=black!10,rounded corners,fit=(w1')(w2')(e1')(e2')(l1')(l2')] {};
  \end{scope}

  \draw [shorten >=1mm,->,thick,decorate,
         decoration={snake,amplitude=.4mm,segment length=2mm,
                     pre=moveto,pre length=1mm,post length=2mm}]
    (r1) -- (r2) node [above=1mm,midway,text width=3cm,align=center]
      {replacement of the \textcolor{red}{capacity} by \textcolor{red}{two places}};
\end{tikzpicture}

получим такую красоту:

step13

13 - Графики в TIKZ для Latex

Дружелюбный функционал для полной графики в Latex. Картинки, иконки, графики и пр.

Дружелюбный функционал для полной графики в Latex. Картинки, иконки, графики и пр. Очень мощный пакет в котором можно нарисовать все.

Установка пакета

\usepackage{tikz}

Использование пакета

Окружение {tikzpicture} или команды \tikzpicture и \endtikzpicture

coordinate

\documentclass{article} % say
\usepackage{tikz}
\begin{document}
We are working on
\begin{tikzpicture}
  \draw (-1.5,0) -- (1.5,0);
  \draw (0,-1.5) -- (0,1.5);
\end{tikzpicture}.
\end{document}

Нарисует точки в координатах и проведет через них кривую

curve

\begin{tikzpicture}
  \filldraw [gray] (0,0) circle [radius=2pt]
                   (1,1) circle [radius=2pt]
                   (2,1) circle [radius=2pt]
                   (2,0) circle [radius=2pt];
  \draw (0,0) .. controls (1,1) and (2,1) .. (2,0);
\end{tikzpicture}

Цвет

filldraw [gray] — зальет фигуру серым цветом

Кривые

.. controls — укажет контрольные точки для кривой Безье.

Окружность

circle [radius=10pt] — нарисует окружность

нарисуем эллипс

\tikz \draw (0,0) ellipse [x radius=20pt, y radius=10pt];

Поворот рисунка

\draw[rotate=30] — развернет рисунок на 30гр.

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

 \draw (0,0) rectangle (0.5,0.5);
 \draw (-0.5,-0.5) rectangle (-1,-1);

Нарисуем сетку

\tikz \draw[step=2pt] (0,0) grid (10pt,10pt);

нарисует сетку козявочку coz

circle

\begin{tikzpicture}
  \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
  \draw (-1.5,0) -- (1.5,0);
  \draw (0,-1.5) -- (0,1.5);
  \draw (0,0) circle [radius=1cm];
\end{tikzpicture}

в draw — определим шаг, цвет и толщину линий

Установим настройку стилей по умолчанию

Глобально в переменной Ra grid

\tikzset{Ra grid/.style={help lines,color=blue!50}}

или локально в переменной Karl's grid karlgrid

\begin{tikzpicture}
  [Karl's grid/.style ={help lines,color=#1!50},
   Karl's grid/.default=blue]

  \draw[Karl's grid]     (0,0) grid (1.5,2);
  \draw[Karl's grid=red] (2,0) grid (3.5,2);
\end{tikzpicture}

Толщина линий

  • ultra thin
  • very thin
  • thin
  • semithick
  • thick
  • very thick
  • ultra thick
 \draw[ultra thin] (-1.5,1.1) -- (1.5,1.1);
\draw[very thin] (-1.5,1.6) -- (1.5,1.6);
\draw[thin] (-1.5,2.1) -- (1.5,2.1);
\draw[semithick] (-1.5,2.6) -- (1.5,2.6);
\draw[very thick] (-1.5,3.1) -- (1.5,3.1);
\draw[ultra thick] (-1.5,3.6) -- (1.5,3.6);

lines

\begin{tikzpicture}[line width=5pt] — любая толщина

Стиль линии

  • loosely dashed,
  • densely dashed,
  • loosely dotted,
  • densely dotted
 \draw[loosely dashed, ultra thick] (-1.5,-3.6) -- (1.5,-3.6);
\draw[densely dashed, ultra thick] (-1.5,-3.1) -- (1.5,-3.1);
\draw[loosely dotted, ultra thick] (-1.5,-2.6) -- (1.5,-2.6);
\draw[densely dotted, ultra thick] (-1.5,-2.1) -- (1.5,-2.1);

lines

dash pattern — можно определить сложный паттерн

Нарисуем дугу

arc[start angle=10, end angle=80, radius=10pt]

Элипсоидная дуга

\tikz \draw (0,0)
    arc [start angle=0, end angle=315,
         x radius=1.75cm, y radius=1cm];

Масштабирование

\begin{tikzpicture}[scale=3]
  \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
  \draw (-1.5,0) -- (1.5,0);
  \draw (0,-1.5) -- (0,1.5);
  \draw (0,0) circle [radius=1cm];
  \draw (3mm,0mm) arc [start angle=0, end angle=30, radius=3mm];
\end{tikzpicture}

после определения окружения, ставим [scale=3]

Клиппинг

или обрезание рисунка

\clip (-0.1,-0.2) rectangle (1.1,0.75);

две точки на рисунке для обрезки прямоугольником, обрезать можно любой фигурой

\begin{tikzpicture}[scale=3]
  \clip (-0.1,-0.2) rectangle (1.1,0.75);
  \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
  \draw (-1.5,0) -- (1.5,0);
  \draw (0,-1.5) -- (0,1.5);
  \draw (0,0) circle [radius=1cm];
  \draw (3mm,0mm) arc [start angle=0, end angle=30, radius=3mm];
\end{tikzpicture}

clip

Основные команды рисования

\path[draw, clip] или \path[clip] или \path[draw] — братья по смыслу и к ним же \draw[clip]

Параболы, синусы и изгибы

% чертит параболу в квадрате
\tikz \draw (0,0) rectangle (1,1)  (0,0) parabola (1,1);
% чертит параболу и изгиб, по дороге поменяем размерность координат x и y
\tikz \draw[x=1pt,y=1pt] (0,0) parabola bend (4,16) (6,12);

A sine \tikz \draw[x=1ex,y=1ex] (0,0) sin (1.57,1); curve.

Нарисует прямо в тексте кривулину. A sine (-tikz- diagram) curve.

А вот эта штука покажет, что такое sin и cos на самом деле:

\tikz \draw[x=3.57ex,y=1ex] (0,0) sin (4,1) cos (6,-14) sin (8,12) 

sin

да,именно так — sin поднимаемся, cos — опускаемся

Закрасить пространство

\fill[green!20!white] (0,0) -- (3mm,0mm)
    arc [start angle=0, end angle=30, radius=3mm] -- (0,0);
	
% или сразу рисуем и красим
\filldraw[fill=green!20!white, draw=green!50!black] (0,0) -- (3mm,0mm)
    arc [start angle=0, end angle=30, radius=3mm] -- cycle;

Замыкание контуров

\begin{tikzpicture}[line width=5pt]
  \draw (0,0) -- (1,0) -- (1,1) -- (0,0);
  \draw (2,0) -- (3,0) -- (3,1) -- cycle;
  \useasboundingbox (0,1.5); % make bounding box higher
\end{tikzpicture}

cycle — плавно замкнет контур, похожа на последнюю команду -- (0,0) но работает лучше

Градиент

Команды shade и shadedraw

\begin{tikzpicture}[rounded corners,ultra thick]
  \shade[top color=yellow,bottom color=black] (0,0) rectangle +(2,1);
  \shade[left color=yellow,right color=black] (3,0) rectangle +(2,1);
  \shadedraw[inner color=yellow,outer color=black,draw=yellow] (6,0) rectangle +(2,1);
  \shade[ball color=green] (9,.5) circle (.5cm);
\end{tikzpicture}

shade

Координаты точек

(x,y) — с указанием размерности или по умолчанию в см.

(30:1cm) — полярные координаты 30 градусов и 1 см.

Относительные перемещения

+(x,y) — переместиться относительно последней точки на x и y

++(x,y) — переместить указатель, но ничего не чертить, чертит только команда --.

\begin{tikzpicture}[scale=3]
  \clip (-0.1,-0.2) rectangle (1.1,0.75);
  \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
  \draw (-1.5,0) -- (1.5,0);
  \draw (0,-1.5) -- (0,1.5);
  \draw (0,0) circle [radius=1cm];
  \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm)
      arc [start angle=0, end angle=30, radius=3mm] -- cycle;
  \draw[red,very thick]  (30:1cm) -- +(0,-0.5);
  \draw[blue,very thick] (30:1cm) ++(0,-0.5) -- (0,0);
\end{tikzpicture}

sine

Определяем свои команды

\begin{tikzpicture}
  \def\rectanglepath{-- ++(1cm,0cm)  -- ++(0cm,1cm)  -- ++(-1cm,0cm) -- cycle}
  \draw (0,0) \rectanglepath;
  \draw (1.5,0) \rectanglepath;
\end{tikzpicture}

нарисует два квадратика

или идентично:

\tikz \draw (0,0) rectangle +(1,1)  (1.5,0) rectangle +(1,1);

1,{tan(30)}) — так тоже умеет. Любую функцию для расчета координат.

Координаты по пересекающимся линиям

\path [name path=upward line] (1,0) -- (1,1);
\path [name path=sloped line] (0,0) -- (30:1.5cm);
% Рисуем невидимые пути. \path без атрибутов, просто перемещает указатель
% (добавить библиотеку `\usetikzlibrary{intersections}' после загрузки tikz)
\draw [name intersections={of=upward line and sloped line, by=x}] % нашли точку пересечения и назвали ее x
  [very thick,orange] (1,0) -- (x); % нарисовали линию от (1,0) до точки пересечения

Стрелки

\draw[->] (-1.5,0) -- (1.5,0);
\draw[->] (0,-1.5) -- (0,1.5);

->, <-, <->, <<-, ->>

или использовать специальную библиотеку Documentation arrow

\usetikzlibrary {arrows.meta}
\begin{tikzpicture}[>=Stealth]

Облать видимости

\begin{tikzpicture}[ultra thick]
  \draw (0,0) -- (0,1);
  \begin{scope}[thin]
    \draw (1,0) -- (1,1);
    \draw (2,0) -- (2,1);
  \end{scope}
  \draw (3,0) -- (3,1);
\end{tikzpicture}

Окружение {scope}

Преобразования

xshift=2pt — смещает все точки на 2pt по x

\begin{tikzpicture}[even odd rule,rounded corners=2pt,x=10pt,y=10pt]
  \filldraw[fill=yellow!80!black] (0,0)   rectangle (1,1)
        [xshift=5pt,yshift=5pt]   (0,0)   rectangle (1,1)
                    [rotate=30]   (-1,-1) rectangle (2,2);
\end{tikzpicture}

Самое интересное во всем этом процессе, что когда ты пишешь эти строки и видишь, как все это происходит по настоящему в твоем Latex документе — приходишь в восторг!

xshift и yshift смещают по осям, shift={(1,0)} смещает в точку shift={+(0,0)} или относительную точку.

rotate или rotate around вращают объект относительно точки

scale, xscale, yscale — масштабирует xscale=-1 схлопывает фигуру

xslant, yslant — наклоняет

cm — опция для произвольных преобразований по матрице

Повторения и циклы

Можно использовать независимый пакет для \foreach или он автоматически подключен в Tikz

Синтаксис команды: \foreach ⟨variable⟩ in {⟨list of values⟩} ⟨commands⟩

Пример:

\foreach \x in {1,2,3} {$x =\x$, }

x=1, x=2, x=3,
\begin{tikzpicture}[scale=3]
  \clip (-0.1,-0.2) rectangle (1.1,1.51);
  \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
  \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm)
      arc [start angle=0, end angle=30, radius=3mm] -- cycle;
  \draw[->] (-1.5,0) -- (1.5,0);
  \draw[->] (0,-1.5) -- (0,1.5);
  \draw (0,0) circle [radius=1cm];

  \foreach \x in {-1cm,-0.5cm,0.5cm,1cm}
    \draw [red](\x,-1pt) -- (\x,1pt);
  \foreach \y in {-1cm,-0.5cm,0.5cm,1cm}
    \draw [blue](-1pt,\y) -- (1pt,\y);
\end{tikzpicture}

Поставил меточки на осях координат foreach

\tikz \foreach \x in {1,...,10}
        \draw (\x,0) circle (0.4cm);

еще вариант для диапазона значений: цикл в цикле

\begin{tikzpicture}
  \foreach \x in {1,2,...,5,7,8,...,12}
    \foreach \y in {1,...,5}
    {
      \draw (\x,\y) +(-.5,-.5) rectangle ++(.5,.5);
      \draw (\x,\y) node{\x,\y};
    }
\end{tikzpicture}

node

Nodes

\begin{tikzpicture}
  \draw (0,0) rectangle (2,2);
  \draw (0.5,0.5) node [fill=yellow!80!black]
                       {Text at \texttt{node 1}}
     -- (1.5,1.5) node {Text at \texttt{node 2}};
\end{tikzpicture}

любой текст или все что нам нужно можно вставить в Node и поместить в нужную точку координат рисунка

Фон можно закрасить [fill=white] node2

Якоря по сторонам света

На всех рисунках есть якоря со сторонами света:

  • north
  • south
  • east
  • west

и их комбинации anchor=south west и т.д.

above rigth тоже, что south west

below=1pt — можно задавать смещение

\usetikzlibrary {intersections}
\begin{tikzpicture}[scale=3]
  \clip (-2,-0.2) rectangle (2,0.8);
  \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4);
  \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm)
    arc [start angle=0, end angle=30, radius=3mm] -- cycle;
  \draw[->] (-1.5,0) -- (1.5,0) coordinate (x axis);
  \draw[->] (0,-1.5) -- (0,1.5) coordinate (y axis);
  \draw (0,0) circle [radius=1cm];

  \draw[very thick,red]
    (30:1cm) -- node[left=1pt,fill=white] {$\sin \alpha$} (30:1cm |- x axis);
  \draw[very thick,blue]
    (30:1cm |- x axis) -- node[below=2pt,fill=white] {$\cos \alpha$} (0,0);
  \path [name path=upward line] (1,0) -- (1,1);
  \path [name path=sloped line] (0,0) -- (30:1.5cm);
  \draw [name intersections={of=upward line and sloped line, by=t}]
    [very thick,orange] (1,0) -- node [right=1pt,fill=white]
    {$\displaystyle \tan \alpha \color{black}=
      \frac{{\color{red}\sin \alpha}}{\color{blue}\cos \alpha}$} (t);

  \draw (0,0) -- (t);

  \foreach \x/\xtext in {-1, -0.5/-\frac{1}{2}, 1}
    \draw (\x cm,1pt) -- (\x cm,-1pt) node[anchor=north,fill=red!20] {$\xtext$};
  \foreach \y/\ytext in {-1, -0.5/-\frac{1}{2}, 0.5/\frac{1}{2}, 1}
    \draw (1pt,\y cm) -- (-1pt,\y cm) node[anchor=east,fill=red!20] {$\ytext$};
\end{tikzpicture}

node3

Текст по контуру

\begin{tikzpicture}
  \draw (0,0) .. controls (6,1) and (9,1) ..
    node[near start,sloped,above] {near start}
    node {midway}
    node[very near end,sloped,below] {very near end} (12,0);
\end{tikzpicture}

text

Полностью пример

\begin{tikzpicture}
  [scale=3,line cap=round,
  % Styles
  axes/.style=,
  important line/.style={very thick},
  information text/.style={rounded corners,fill=red!10,inner sep=1ex}]

  % Colors
  \colorlet{anglecolor}{green!50!black}
  \colorlet{sincolor}{red}
  \colorlet{tancolor}{orange!80!black}
  \colorlet{coscolor}{blue}

  % The graphic
  \draw[help lines,step=0.5cm] (-1.4,-1.4) grid (1.4,1.4);

  \draw (0,0) circle [radius=1cm];

  \begin{scope}[axes]
    \draw[->] (-1.5,0) -- (1.5,0) node[right] {$x$} coordinate(x axis);
    \draw[->] (0,-1.5) -- (0,1.5) node[above] {$y$} coordinate(y axis);

    \foreach \x/\xtext in {-1, -.5/-\frac{1}{2}, 1}
      \draw[xshift=\x cm] (0pt,1pt) -- (0pt,-1pt) node[below,fill=white] {$\xtext$};

    \foreach \y/\ytext in {-1, -.5/-\frac{1}{2}, .5/\frac{1}{2}, 1}
      \draw[yshift=\y cm] (1pt,0pt) -- (-1pt,0pt) node[left,fill=white] {$\ytext$};
  \end{scope}

  \filldraw[fill=green!20,draw=anglecolor] (0,0) -- (3mm,0pt)
    arc [start angle=0, end angle=30, radius=3mm];
  \draw (15:2mm) node[anglecolor] {$\alpha$};

  \draw[important line,sincolor]
    (30:1cm) -- node[left=1pt,fill=white] {$\sin \alpha$} (30:1cm |- x axis);

  \draw[important line,coscolor]
    (30:1cm |- x axis) -- node[below=2pt,fill=white] {$\cos \alpha$} (0,0);

  \path [name path=upward line] (1,0) -- (1,1);
  \path [name path=sloped line] (0,0) -- (30:1.5cm);
  \draw [name intersections={of=upward line and sloped line, by=t}]
    [very thick,orange] (1,0) -- node [right=1pt,fill=white]
    {$\displaystyle \tan \alpha \color{black}=
      \frac{{\color{red}\sin \alpha}}{\color{blue}\cos \alpha}$} (t);

  \draw (0,0) -- (t);

  \draw[xshift=1.85cm]
    node[right,text width=6cm,information text]
    {
      The {\color{anglecolor} angle $\alpha$} is $30^\circ$ in the
      example ($\pi/6$ in radians). The {\color{sincolor}sine of
        $\alpha$}, which is the height of the red line, is
      \[
      {\color{sincolor} \sin \alpha} = 1/2.
      \]
      By the Theorem of Pythagoras ...
    };
\end{tikzpicture}

Для node задали ширину текста text width=6cm

Макросы

\usetikzlibrary {angles,quotes}
\begin{tikzpicture}[scale=3]
  \coordinate (A) at (1,0);
  \coordinate (B) at (0,0);
  \coordinate (C) at (30:1cm);

  \draw (A) -- (B) -- (C)
        pic [draw=green!50!black, fill=green!20, angle radius=9mm,
             "$\alpha$"] {angle = A--B--C};
\end{tikzpicture}

Команда pic создает макрос для последующего использования кода.