125
by Andrew Stacey (Thargelion)
Added test file for hobby |
1 |
\immediate\write18{tex hobby.dtx} |
126
by Andrew Stacey
Added "edge case" section to hobby code |
2 |
\documentclass{article} |
158.1.2
by Andrew Stacey
prg_stepwise replaced by int_step |
3 |
\usepackage{amsmath} |
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
4 |
\usepackage{pgfplots} |
158.1.3
by Andrew Stacey
Added externalisation method to hobby, other code clean-ups and bug fixes |
5 |
\usetikzlibrary{hobby,decorations.pathreplacing} |
161.2.2
by Andrew Stacey
Hobby: Added date and version information, and check for loading twice |
6 |
\input{hobby.code.tex} |
158.1.2
by Andrew Stacey
prg_stepwise replaced by int_step |
7 |
\usepackage[silent]{trace-pgfkeys} |
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
8 |
|
161.2.15
by Andrew Stacey
Fixed Hobby code to deal with changes to l3fp |
9 |
\ExplSyntaxOn
|
10 |
\fp_new:N \l__test_fp |
|
11 |
\fp_set_eq:NN \l__test_fp \c_inf_fp |
|
12 |
\fp_show:N\l__test_fp |
|
13 |
%\fp_set:Nn \l__test_fp {20}
|
|
14 |
\fp_compare:nTF { \l__test_fp == \c_inf_fp } |
|
15 |
{
|
|
16 |
\message{Not~a~number} |
|
17 |
}
|
|
18 |
{
|
|
19 |
\message{Number} |
|
20 |
}
|
|
21 |
\ExplSyntaxOff
|
|
22 |
||
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
23 |
\newif\ifhobbyinpath
|
24 |
\tikzset{ |
|
25 |
tangent/.style={% |
|
26 |
called={tangent #1}, |
|
27 |
in angle={(180+#1)}, |
|
28 |
Hobby finish, |
|
29 |
Hobby action={\message{breaking path}}, |
|
30 |
designated Hobby path=next, |
|
31 |
out angle=#1, |
|
32 |
},
|
|
33 |
called/.code={\message{#1 got called}}, |
|
34 |
every path/.append style={clear next Hobby path options,clear this Hobby path options}, |
|
158.1.3
by Andrew Stacey
Added externalisation method to hobby, other code clean-ups and bug fixes |
35 |
show curve controls/.style={
|
36 |
decoration={
|
|
37 |
show path construction, |
|
38 |
curveto code={
|
|
39 |
\draw [blue, dashed]
|
|
40 |
(\tikzinputsegmentfirst) -- (\tikzinputsegmentsupporta) |
|
41 |
node [at end, draw, solid, red, inner sep=2pt]{};
|
|
42 |
\draw [blue, dashed]
|
|
43 |
(\tikzinputsegmentsupportb) -- (\tikzinputsegmentlast) |
|
44 |
node [at start, draw, solid, red, inner sep=2pt]{};
|
|
45 |
}
|
|
46 |
},decorate
|
|
47 |
},
|
|
48 |
Hobby externalise |
|
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
49 |
}
|
158.1.15
by Andrew Stacey
Added wrapper for PGF atan2 to be robust against interchange of arguments, so hobby should work with current PGF and old PGF. |
50 |
|
51 |
\pgfmathparse{atan2(0,1)} |
|
52 |
\show\pgfmathresult
|
|
53 |
\pgfmathparse{hobbyatan2(0,1)} |
|
54 |
\show\pgfmathresult
|
|
55 |
||
158.1.13
by Andrew Stacey
Added annotations to calligraphy and fixed atan2 call for hobby (due to fix in PGF cvs) |
56 |
\HobbyDisableAux
|
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
57 |
|
58 |
\begin{document} |
|
161.2.15
by Andrew Stacey
Fixed Hobby code to deal with changes to l3fp |
59 |
|
161.2.7
by Andrew Stacey
New version of the TQFT code using the new pic syntax of TikZ3.0 |
60 |
\begin{tikzpicture}[use Hobby shortcut] |
161.2.16
by Andrew Stacey
Updated version and email for hobby submission to CTAN and removed some unused commands; also updated documentation. |
61 |
%\draw[ultra thick,red] (-0.6,-1) .. (0,-0.9) .. (2,0.6);
|
62 |
\node (star) at (-0.6,-1) {}; |
|
63 |
\draw (star.center) .. (0,-0.9) .. (2,0.6);
|
|
64 |
\draw (0,0) -- (star) -- (2,0);
|
|
65 |
\end{tikzpicture} |
|
66 |
\end{document} |
|
67 |
||
68 |
\begin{tikzpicture}[use Hobby shortcut] |
|
161.2.7
by Andrew Stacey
New version of the TQFT code using the new pic syntax of TikZ3.0 |
69 |
% filled points
|
70 |
\fill (0,0) circle (1pt);
|
|
71 |
\fill (2,0) circle (1pt);
|
|
72 |
% middle crossing loop
|
|
73 |
\draw[save Hobby path=fish,thick, red] (3,-1) .. ([blank=soft]2,0) .. (0,0.93) .. (-0.93,0) .. (0,-0.93) .. (2,0) .. ([blank=soft]3,1); |
|
74 |
\tikzset{show Hobby path=fish} |
|
75 |
\draw[restore and use Hobby path={fish}{invert soft blanks,disjoint=true},thick, blue]; |
|
76 |
\end{tikzpicture} |
|
161.2.3
by Andrew Stacey
Added low-level interface for hobby |
77 |
|
78 |
\begin{tikzpicture} |
|
79 |
\pgfpathmoveto{\pgfpoint{0}{0}} |
|
80 |
\pgfpathlineto{\pgfpoint{1cm}{0}} |
|
161.2.5
by Andrew Stacey
Modified syntax of low-level pgf interface to hobby |
81 |
\pgfpathhobby{closed=true} |
82 |
\pgfpathhobbypt{\pgfpoint{1cm}{2cm}}{tension in=2} |
|
83 |
\pgfpathhobbypt{\pgfpoint{2cm}{1cm}} |
|
84 |
\pgfpathhobbypt{\pgfpoint{3cm}{0cm}} |
|
85 |
\pgfpathhobbyend
|
|
161.2.3
by Andrew Stacey
Added low-level interface for hobby |
86 |
\pgfusepath{stroke} |
87 |
\end{tikzpicture} |
|
88 |
||
89 |
\begin{tikzpicture}[use Hobby shortcut] |
|
90 |
\draw (0,0) -- (1,0) .. (1,2) .. (2,1) .. (3,0);
|
|
91 |
\end{tikzpicture} |
|
92 |
||
93 |
||
161.2.1
by Andrew Stacey
Converted hobby to l3fp atan function; other small bug fixes; updated documentation, (hopefully) ready for CTAN upload |
94 |
\begin{tikzpicture}[scale=.5] |
95 |
\draw[red,line width=5pt] (0,0) to[curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); |
|
96 |
\draw[ultra thick,blue] plot[smooth] coordinates {(0,0) (6,4) (4,9) (1,7) (3,5)}; |
|
97 |
\draw[green,line width=2pt] (0,0) to[quick curve through={(6,4) (4,9) (1,7)}] (3,5); |
|
98 |
\end{tikzpicture} |
|
99 |
||
100 |
\begin{tikzpicture}%[use quick Hobby shortcut] |
|
101 |
\draw[use Hobby shortcut] (0,0) .. (1,1) .. (2,0); |
|
102 |
\draw[use quick Hobby shortcut] (0,0) .. (1,1) .. (2,0); |
|
103 |
\end{tikzpicture} |
|
104 |
||
105 |
\begin{tikzpicture} |
|
106 |
\begin{axis} |
|
107 |
\addplot +[smooth] {rnd}; |
|
108 |
\addplot +[hobby] {rnd}; |
|
109 |
\end{axis} |
|
110 |
\end{tikzpicture} |
|
111 |
||
158.1.13
by Andrew Stacey
Added annotations to calligraphy and fixed atan2 call for hobby (due to fix in PGF cvs) |
112 |
|
113 |
\begin{tikzpicture}[use Hobby shortcut] |
|
114 |
\draw[save Hobby path=temp] (0,0) .. (1,1) .. (2,0); |
|
115 |
\tikzset{show Hobby path=temp} |
|
116 |
\end{tikzpicture} |
|
117 |
||
118 |
\begin{tikzpicture} |
|
119 |
\draw (0,0) .. controls (0,.5) and (.5,1) .. (1,1) .. controls (1.5,1) and (2,.5) .. (2,0);
|
|
120 |
\end{tikzpicture} |
|
121 |
||
122 |
\begin{tikzpicture} |
|
123 |
\draw (0,0) to[curve through={(1,1)}] (2,0); |
|
124 |
\end{tikzpicture} |
|
125 |
||
126 |
\begin{tikzpicture}[use Hobby shortcut,baseline=0pt] |
|
127 |
\filldraw[fill=yellow] ([closed]1,0.1) .. (.4,.6) .. (0.1,1) .. (-.5,.5) .. (-1,-0.1) .. (-.4,-.6) .. (-.1,-1) .. (.6,-.4) .. (1,0.1); |
|
128 |
\draw[->] (0,0) -- (0,.5); |
|
129 |
\draw[->] (0,0) -- (.5,0); |
|
130 |
\fill (0,0) circle[radius=2pt] node[below] {\(p\)}; |
|
131 |
\end{tikzpicture} |
|
132 |
||
158.1.4
by Andrew Stacey
Refactored spath code into LaTeX3, including calligraphy and knot libraries |
133 |
%\pgfmathsetseed{2}
|
158.1.12
by Andrew Stacey
Fixed nodes along paths for hobby |
134 |
\begin{tikzpicture} |
135 |
\draw[use Hobby shortcut] ([closed]0,0) .. (1,1) .. (2,0); |
|
136 |
\end{tikzpicture} |
|
137 |
||
138 |
\begin{tikzpicture} |
|
139 |
\draw[use Hobby shortcut] (0:rnd+2) \foreach \ang in {0,20,...,350} { .. (\ang:rnd+2) }; |
|
140 |
\end{tikzpicture} |
|
141 |
||
142 |
\begin{tikzpicture} |
|
143 |
\draw[use Hobby shortcut] ([closed]0:rnd+2) \foreach \ang in {0,20,...,350} { .. (\ang:rnd+2) }; |
|
144 |
\end{tikzpicture} |
|
145 |
||
146 |
\begin{tikzpicture}[use Hobby shortcut] |
|
147 |
\draw[save Hobby path={first}] |
|
148 |
(1,0) .. coordinate (a) ([blank=soft]2,1) .. coordinate (b) ([blank=soft]3,0) .. (4,1) .. coordinate (e) (5,0); |
|
149 |
\draw[ultra thick,blue,restore and use Hobby path={first}{disjoint,invert soft blanks}]; |
|
150 |
\draw[red,<-] (a) -- +(0,3) node[above] {a}; |
|
151 |
\draw[green,<-] (b) -- +(0,3) node[above] {b}; |
|
152 |
\draw[blue,<-] (e) -- +(0,3) node[above] {e}; |
|
153 |
\begin{scope}[xshift=4cm] |
|
154 |
\draw (1,0) -- coordinate (c) (2,1) -- coordinate (d) (3,0);
|
|
155 |
\draw[red,<-] (c) -- +(0,3) node[above] {c}; |
|
156 |
\draw[green,<-] (d) -- +(0,3) node[above] {d}; |
|
157 |
\end{scope} |
|
158 |
\end{tikzpicture} |
|
159 |
||
158.1.4
by Andrew Stacey
Refactored spath code into LaTeX3, including calligraphy and knot libraries |
160 |
|
161 |
\begin{tikzpicture} |
|
162 |
\draw[use Hobby shortcut] ([closed]0:rnd+2) \foreach \ang in {0,20,...,350} { .. (\ang:rnd+2) }; |
|
163 |
\end{tikzpicture} |
|
164 |
||
165 |
||
158.1.3
by Andrew Stacey
Added externalisation method to hobby, other code clean-ups and bug fixes |
166 |
\begin{tikzpicture} |
167 |
\draw[line width=3mm,red,use Hobby shortcut,save Hobby path={saved}] (0,0) .. ([blank=soft]1,1) .. (2,0); |
|
168 |
\draw[ultra thick,yellow,restore and use Hobby path={saved}{disjoint,invert soft blanks}]; |
|
169 |
\end{tikzpicture} |
|
170 |
||
171 |
\begin{tikzpicture}[use Hobby shortcut] |
|
172 |
\draw[ultra thick,green,postaction=show curve controls] |
|
173 |
(0,0) to[save Hobby path={curve},in curl=.1,out curl=3,curve through={(1,.5) .. (2,0) .. (3,.5)}] (4,0); |
|
174 |
\begin{scope}%[yshift=-1cm] |
|
175 |
\draw[postaction=show curve controls] |
|
176 |
(0,0) .. ([in curl=.1,out curl=3]1,.5) .. (2,0) .. (3,.5) .. (4,0); |
|
177 |
\end{scope} |
|
178 |
\end{tikzpicture} |
|
179 |
||
180 |
\tikz[hobby] \draw[save Hobby path={plot}] plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; |
|
181 |
||
182 |
||
158.1.2
by Andrew Stacey
prg_stepwise replaced by int_step |
183 |
\begin{tikzpicture}[use Hobby shortcut] |
184 |
\draw[scale=-2,inner color=white,outer color=gray!5] ([closed]0.5,0.1) .. (0.7,0.28) .. (0.5,1) .. (0.3,0.28) .. (0.5,0.1); |
|
185 |
\end{tikzpicture} |
|
186 |
||
187 |
\newpage
|
|
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
188 |
|
189 |
\begin{tikzpicture}[use Hobby shortcut] |
|
190 |
\draw[help lines] (-5,-5) grid (5,5); |
|
191 |
\draw (-5,0) -- (5,0) (0,-5) -- (0,5);
|
|
192 |
\draw[thick] ([tangent=150]-5,2) .. ([tangent=0]-3,3) .. (-1,1) .. (0,-1.3) .. ([tangent=0]1,-2) .. ([tangent=45]2,-1.5) .. ([tangent=0]3,-2) .. ([tangent=-45]5,-4); |
|
193 |
\end{tikzpicture} |
|
194 |
||
195 |
\begin{tikzpicture}[use Hobby shortcut] |
|
196 |
\draw[help lines] (-5,-5) grid (5,5); |
|
197 |
\draw (-5,0) -- (5,0) (0,-5) -- (0,5);
|
|
198 |
\draw[thick] (-5,2) .. ([tangent=0]-3,3) .. (-1,1) .. (0,-1.3) .. % |
|
199 |
([tangent=0]1,-2) .. ([tangent=45]2,-1.5) .. ([tangent=0]3,-2) .. (5,-4); |
|
200 |
\end{tikzpicture} |
|
201 |
||
202 |
\begin{tikzpicture}[use Hobby shortcut] |
|
203 |
\draw[help lines] (-5,-5) grid (5,5); |
|
204 |
\draw (-5,0) -- (5,0) (0,-5) -- (0,5);
|
|
205 |
\draw[thick] (-5,2) .. (-3,3) .. (-1,1) .. (0,-1.3) .. % |
|
206 |
([tangent=0]1,-2) .. ([tangent=45]2,-1.5) .. (3,-2) .. (5,-4); |
|
207 |
\end{tikzpicture} |
|
158.1.2
by Andrew Stacey
prg_stepwise replaced by int_step |
208 |
|
209 |
\newpage
|
|
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
210 |
|
211 |
\begin{tikzpicture} |
|
212 |
\draw[use Hobby shortcut] (0,0) .. ([tangent=45]1,1) .. (2,0) .. (3,1) .. (4,0); |
|
213 |
\end{tikzpicture} |
|
214 |
||
158.1.3
by Andrew Stacey
Added externalisation method to hobby, other code clean-ups and bug fixes |
215 |
\begin{tikzpicture}[use Hobby shortcut] |
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
216 |
\draw[blue,save Hobby path={left}] ([out angle=90,in angle=-90]1,0) .. (1,1) .. ([blank=soft]0,2) .. (1,3) .. (1,4); |
217 |
\draw[show Hobby path={left},red] ([out angle=90,in angle=-90]0,0) .. (0,1) .. (1,2) .. (0,3) .. (0,4); |
|
218 |
\tikzset{show Hobby path={left}} |
|
219 |
\draw[blue,show Hobby path={left},restore and use Hobby path={left}{disjoint,invert soft blanks}]; |
|
220 |
\end{tikzpicture} |
|
221 |
||
158.1.13
by Andrew Stacey
Added annotations to calligraphy and fixed atan2 call for hobby (due to fix in PGF cvs) |
222 |
\begin{tikzpicture}[use Hobby shortcut] |
223 |
\draw[blue,save Hobby path={upper}] ([out angle=0,in angle=-180]0,1) .. (1,1) .. ([blank=soft]2,0) .. (3,1) .. (4,1); |
|
224 |
\draw[show Hobby path={upper},red] ([out angle=0,in angle=-180]0,0) .. (1,0) .. (2,1) .. (3,0) .. (4,0); |
|
225 |
\tikzset{show Hobby path={upper}} |
|
226 |
\draw[blue,show Hobby path={upper},restore and use Hobby path={upper}{disjoint,invert soft blanks}]; |
|
227 |
\end{tikzpicture} |
|
228 |
||
229 |
\begin{tikzpicture}[use Hobby shortcut] |
|
230 |
\draw ([out angle=0]0,0) .. (0,2);
|
|
231 |
\draw ([out angle=0]0,0) .. (2,0);
|
|
232 |
\begin{scope}[xshift=3cm] |
|
233 |
\draw ([out angle=90]0,0) .. (0,2);
|
|
234 |
\draw ([out angle=90]0,0) .. (2,0);
|
|
235 |
\begin{scope}[xshift=3cm] |
|
236 |
\draw ([out angle=180]0,0) .. (0,2);
|
|
237 |
%\draw ([out angle=180]0,0) .. (2,0);
|
|
238 |
\end{scope} |
|
239 |
\end{scope} |
|
240 |
\end{tikzpicture} |
|
241 |
||
242 |
||
158.1.2
by Andrew Stacey
prg_stepwise replaced by int_step |
243 |
\newpage
|
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
244 |
\begin{tikzpicture} |
245 |
\begin{axis} |
|
161.2.1
by Andrew Stacey
Converted hobby to l3fp atan function; other small bug fixes; updated documentation, (hopefully) ready for CTAN upload |
246 |
%\addplot +[smooth] {rnd};
|
247 |
%\addplot +[hobby] {rnd};
|
|
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
248 |
\end{axis} |
249 |
\end{tikzpicture} |
|
158.1.2
by Andrew Stacey
prg_stepwise replaced by int_step |
250 |
|
251 |
\newpage
|
|
252 |
||
253 |
||
137
by Andrew Stacey
Bug fix in hobby code, quick code is in hobby_test.tex for the moment |
254 |
|
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
255 |
%\tikzset{use quick Hobby shortcut}
|
126
by Andrew Stacey
Added "edge case" section to hobby code |
256 |
|
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
257 |
\begin{tikzpicture} |
258 |
\draw[use Hobby shortcut] (0,0) .. (1,1) .. (2,1); |
|
259 |
\end{tikzpicture} |
|
158.1.2
by Andrew Stacey
prg_stepwise replaced by int_step |
260 |
|
261 |
\newpage
|
|
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
262 |
|
263 |
\tikz[smooth] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; |
|
264 |
||
265 |
\tikz[hobby] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; |
|
266 |
||
267 |
\tikz[closed hobby] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; |
|
268 |
||
269 |
\tikz[quick hobby] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; |
|
158.1.2
by Andrew Stacey
prg_stepwise replaced by int_step |
270 |
|
271 |
\newpage
|
|
150.1.17
by Andrew Stacey
Subnode command added to tikzmark, some tweaks in option processing for hobby (not stable yet) |
272 |
|
150.1.10
by Andrew Stacey
Added foreach fix to spath so it works when TikZ foreach command is used |
273 |
\begin{tikzpicture}[use Hobby shortcut] |
150.1.16
by Andrew Stacey
Added tikzmark code inspired by listings question; hobby code can deal with 2-pt paths and the auto method can be split |
274 |
\draw ([out angle=10]0,0) .. ([in angle=90]1,1);
|
275 |
\end{tikzpicture} |
|
276 |
||
277 |
\begin{tikzpicture}[use Hobby shortcut] |
|
278 |
\draw ([out angle=10]0,0) .. ([in angle=90]1,1);
|
|
279 |
\end{tikzpicture} |
|
280 |
||
281 |
\begin{tikzpicture}[use Hobby shortcut] |
|
150.1.10
by Andrew Stacey
Added foreach fix to spath so it works when TikZ foreach command is used |
282 |
\draw[scale=-2,inner color=white,outer color=gray!5] ([closed]0.5,0.1) .. (0.7,0.28) .. (0.5,1) .. (0.3,0.28) .. (0.5,0.1); |
283 |
\end{tikzpicture} |
|
284 |
||
150.1.16
by Andrew Stacey
Added tikzmark code inspired by listings question; hobby code can deal with 2-pt paths and the auto method can be split |
285 |
|
158.1.3
by Andrew Stacey
Added externalisation method to hobby, other code clean-ups and bug fixes |
286 |
\begin{tikzpicture}[use Hobby shortcut] |
150.1.9
by Andrew Stacey
Quick shortcut version now works with foreach loops and similar |
287 |
\draw (0,0) .. (1,1) .. (2,0);
|
288 |
\draw (0,0) \foreach \k in {1} { .. (\k^2, \k)}; |
|
150.1.7
by Andrew Stacey
Cleaned up hobby auto path considerably so it now works with foreach (still to do: nodes on the path); introduced an invert-blank key (should also have a no-really-this-should-be-blank key as well now); needs a bit more cleaning up, though. |
289 |
\end{tikzpicture} |
290 |
||
150.1.4
by Andrew Stacey
Added break and blanking to the main algorithm as well. Made the key handling a little more robust between pgf and l3 |
291 |
\tikz[hobby] \draw plot coordinates {(0,0) ([blank=true]1,1) (2,0) (3,1) (2,1) (10:2cm)}; |
292 |
||
158.1.3
by Andrew Stacey
Added externalisation method to hobby, other code clean-ups and bug fixes |
293 |
\tikz[use Hobby shortcut] \draw (0,0) .. (1,1) .. ([blank=true]2,0) .. (3,1) .. ([blank=true]2,1) .. (10:2cm); |
150.1.4
by Andrew Stacey
Added break and blanking to the main algorithm as well. Made the key handling a little more robust between pgf and l3 |
294 |
|
295 |
\tikz \draw (0,0) to[quick curve through={(1,1) (2,0) ([quick hobby/blank curve=once]3,1) (2,1)}] (10:2cm); |
|
296 |
||
150.1.2
by Andrew Stacey
Added plot handling routines to main code, separated quick algorithm implementation into PGF and TikZ parts |
297 |
\tikz \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; |
298 |
||
299 |
\tikz[smooth] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; |
|
300 |
||
301 |
\tikz[hobby] \draw (1,0) -- plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; |
|
302 |
||
303 |
\tikz[closed hobby] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; |
|
304 |
||
305 |
\tikz[quick hobby] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; |
|
306 |
||
137.1.2
by Andrew Stacey
Modified hobby code to use latest fp syntax |
307 |
\begin{tikzpicture}[scale=.5] |
308 |
\draw[scale=.1,line width=1mm,red] (0,0) |
|
309 |
.. controls (26.76463,-1.84543) and (51.4094,14.58441) .. (60,40) |
|
310 |
.. controls (67.09875,61.00188) and (59.76253,84.57518) .. (40,90) |
|
311 |
.. controls (25.35715,94.01947) and (10.48064,84.5022) .. (10,70) |
|
312 |
.. controls (9.62895,58.80421) and (18.80421,49.62895) .. (30,50); |
|
313 |
\fill[green] (0,0) circle[radius=2pt] |
|
314 |
(6,4) circle[radius=2pt] |
|
315 |
(4,9) circle[radius=2pt] |
|
316 |
(1,7) circle[radius=2pt] |
|
317 |
(3,5) circle[radius=2pt]; |
|
318 |
\draw[thick] (0,0) to[curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); |
|
319 |
\begin{scope}[xshift=10cm] |
|
320 |
\draw[scale=.1,line width=1mm,red] (0,0) |
|
321 |
.. controls (5.18756,-26.8353) and (60.36073,-18.40036) .. (60,40) |
|
322 |
.. controls (59.87714,59.889) and (57.33896,81.64203) .. (40,90) |
|
323 |
.. controls (22.39987,98.48387) and (4.72404,84.46368) .. (10,70) |
|
324 |
.. controls (13.38637,60.7165) and (26.35591,59.1351) .. (30,50) |
|
325 |
.. controls (39.19409,26.95198) and (-4.10555,21.23804) .. (0,0); %
|
|
326 |
\fill[green] (0,0) circle[radius=2pt] |
|
327 |
(6,4) circle[radius=2pt] |
|
328 |
(4,9) circle[radius=2pt] |
|
329 |
(1,7) circle[radius=2pt] |
|
330 |
(3,5) circle[radius=2pt]; |
|
331 |
\draw[thick] (0,0) to[closed,curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); |
|
332 |
\end{scope} |
|
333 |
\end{tikzpicture} |
|
334 |
||
335 |
||
137
by Andrew Stacey
Bug fix in hobby code, quick code is in hobby_test.tex for the moment |
336 |
\begin{tikzpicture} |
337 |
\draw[red,line width=5pt] (0,0) to[curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); |
|
338 |
\draw[ultra thick,blue] plot[smooth] coordinates {(0,0) (6,4) (4,9) (1,7) (3,5)}; |
|
339 |
\draw[green,line width=2pt] (0,0) to[quick curve through={(6,4) (4,9) (1,7)}] (3,5); |
|
340 |
\end{tikzpicture} |
|
341 |
||
158.1.3
by Andrew Stacey
Added externalisation method to hobby, other code clean-ups and bug fixes |
342 |
\begin{tikzpicture}[use Hobby shortcut] |
137
by Andrew Stacey
Bug fix in hobby code, quick code is in hobby_test.tex for the moment |
343 |
\draw[ultra thick,blue] (0,0) .. (1,1) .. (2,0) .. (3,0) .. (2,2) .. (2,4); |
344 |
\draw[red] (0,0) to[quick curve through={(1,1) (2,0) (3,0) (2,2)}] (2,4); |
|
345 |
\end{tikzpicture} |
|
346 |
||
347 |
\section{A Piecewise Version of Hobby's Algorithm} |
|
348 |
||
349 |
Here we present a variant of Hobby's algorithm. |
|
350 |
One difficulty with Hobby's algorithm is that it works with the path as a whole. |
|
351 |
It is therefore not possible to build up a path piecewise. |
|
352 |
We therefore modify it to correct for this. |
|
353 |
Obviously, the resulting path will be less ``ideal'', but will have the property that adding new points will not affect earlier segments. |
|
354 |
||
355 |
The method we use is to employ Hobby's algorithm on the two-{}segment subpaths.
|
|
356 |
This provides two cubic Bezier curves: one from the \(k\)th point to the \(k+1\)st point and the second from the \(k+1\)st to the \(k+2\)nd. |
|
357 |
Of this data, we keep the first segment and use that for the path between the \(k\)th and \(k+1\)st points. |
|
358 |
We also remember the outgoing angle of the first segment and use that as the incoming angle on the next computation (which will involve the \(k+1\)st, \(k+2\)nd, and \(k+3\)rd) points. |
|
359 |
||
360 |
The two ends are slightly different to the middle segments. |
|
361 |
On the first segment, we might have no incoming angle. |
|
362 |
On the last segment, we render both pieces. |
|
363 |
||
364 |
This means that for the initial segment, we have a \(2 \times 2\) linear system: |
|
365 |
%
|
|
366 |
\[
|
|
367 |
\begin{bmatrix} |
|
368 |
B_0 & C_0 \\ |
|
369 |
A_1 & B_1 |
|
370 |
\end{bmatrix} |
|
371 |
\Theta = \begin{bmatrix} |
|
372 |
D_0 \\ D_1 |
|
373 |
\end{bmatrix} |
|
374 |
\]
|
|
375 |
%
|
|
376 |
This has solution: |
|
377 |
%
|
|
378 |
\[
|
|
379 |
\Theta = \frac{1}{B_0 B_1 - C_0 A_1} \begin{bmatrix} B_1 & - C_0 \\ -A_1 & B_0 \end{bmatrix} \begin{bmatrix} D_0 \\ D_1 \end{bmatrix} = \frac{1}{B_0 B_1 - C_0 A_1} \begin{bmatrix} B_1 D_0 - C_0 D_1 \\ B_0 D_1 - A_1 D_0 \end{bmatrix} |
|
380 |
\]
|
|
381 |
||
382 |
Now we have the following values for the constants: |
|
383 |
%
|
|
384 |
\begin{align*} |
|
385 |
A_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 \\ |
|
386 |
%
|
|
387 |
B_0 &= \tau_0^3 (3 \overline{\tau}_1 - 1) + \chi_0 \overline{\tau}_1^3 \\ |
|
388 |
%
|
|
389 |
B_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) + d_0 \tau_0 \tau_1^2(3 \overline{\tau}_2 - 1) - d_0 \tau_0 \tau_1^2 \frac{\overline{\tau}_2^3 + \chi_2 \tau_1^3 (3 \overline{\tau}_2 - 1)}{\overline{\tau}_2^3 (3 \tau_1 - 1) + \chi_2 \tau_1^3} \\ |
|
390 |
%
|
|
391 |
C_0 &= \tau_0^3 + \chi_0 \overline{\tau}_1^3 (3 \tau_0 - 1) \\ |
|
392 |
%
|
|
393 |
D_0 &= - (\tau_0^3 + \chi_0 \overline{\tau}_1^3 ( 3 \tau_0 - 1)) \psi_1 \\ |
|
394 |
%
|
|
395 |
D_1 &= - d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) \psi_1 |
|
396 |
\end{align*} |
|
397 |
%
|
|
398 |
||
399 |
Let us, for simplicity at the start, assume that the tensions and curls are all \(1\). |
|
400 |
Then we have \(A_1 = d_1\), \(B_0 = 3\), \(B_1 = 2 d_1 + 2 d_0 - d_0 = 2 d_1 + d_0\), \(C_0 = 3\), \(D_0 = - 3 \psi_1\), \(D_1 = - 2 d_1 \psi_1\). |
|
401 |
Thus the linear system is: |
|
402 |
%
|
|
403 |
\[
|
|
404 |
\begin{bmatrix} |
|
405 |
3 & 3 \\ |
|
406 |
d_1 & 2 d_1 + d_0 |
|
407 |
\end{bmatrix} |
|
408 |
\Theta = - \psi_1 \begin{bmatrix} |
|
409 |
3 \\ 2 d_1 |
|
410 |
\end{bmatrix} |
|
411 |
\]
|
|
412 |
%
|
|
413 |
which we can row reduce to: |
|
414 |
%
|
|
415 |
\[
|
|
416 |
\begin{bmatrix} |
|
417 |
1 & 1 \\ |
|
418 |
0 & d_1 + d_0 |
|
419 |
\end{bmatrix} |
|
420 |
\Theta = -\psi_1 \begin{bmatrix} |
|
421 |
1 \\ d_1 |
|
422 |
\end{bmatrix} |
|
423 |
\]
|
|
424 |
%
|
|
425 |
whence \(\theta_1 = -\psi_1 \frac{d_1}{d_0 + d_1}\) and \(\theta_0 = -\psi_1 - \theta_1 = -\psi_1\frac{d_0 }{d_0 + d_1}\). |
|
426 |
We also compute \(\phi_1 = -\psi_1 - \theta_1 = \theta_0\) and \(\phi_2 = \theta_1\) (in the simple version). |
|
427 |
We use \(\theta_0\) and \(\phi_1\) to compute the bezier curve of the first segment, make a note of \(\theta_1\), and -- assuming there are more segments -- throw away \(\phi_2\). |
|
428 |
||
429 |
For the inner segments, we have the system: |
|
430 |
%
|
|
431 |
\[
|
|
432 |
\begin{bmatrix} |
|
433 |
1 & 0 \\ |
|
434 |
A_1 & B_1 |
|
435 |
\end{bmatrix} |
|
436 |
\Theta = \begin{bmatrix} |
|
437 |
\theta_0 \\ |
|
438 |
D_1 |
|
439 |
\end{bmatrix} |
|
440 |
\]
|
|
441 |
%
|
|
442 |
which has the solution \(\theta_1 = (D_1 - A_1 \theta_0)/B_1\). |
|
443 |
The values of the constants in this case are: |
|
444 |
%
|
|
445 |
\begin{align*} |
|
446 |
A_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 \\ |
|
447 |
%
|
|
448 |
B_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) + d_0 \tau_0 \tau_1^2(3 \overline{\tau}_2 - 1) - d_0 \tau_0 \tau_1^2 \frac{\overline{\tau}_2^3 + \chi_2 \tau_1^3 (3 \overline{\tau}_2 - 1)}{\overline{\tau}_2^3 (3 \tau_1 - 1) + \chi_2 \tau_1^3} \\ |
|
449 |
%
|
|
450 |
D_1 &= - d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) \psi_1 |
|
451 |
\end{align*} |
|
452 |
||
453 |
Again, let us consider the simpler case. |
|
454 |
Then \(A_1 = d_1\), \(B_1 = 2 d_1 + d_0\), and \(D_1 = - 2 d_1 \psi_1\). |
|
455 |
Thus \(\theta_1 = (-2 d_1 \psi_1 - d_1 \theta_0)/(2 d_1 + d_0) = - (2 \psi_1 + \theta_0) \frac{d_1}{2 d_1 + d_0}\). |
|
456 |
We compute \(\phi_1 = -\psi_1 - \theta_1 = \frac{- \psi_1 d_0 + \theta_0 d_1}{2 d_1 + d_0}\) and \(\phi_2 = \theta_1\). |
|
457 |
||
458 |
\begin{tikzpicture} |
|
459 |
\draw[red,line width=5pt] (0,0) to[curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); |
|
460 |
\draw[ultra thick,blue] plot[smooth] coordinates {(0,0) (6,4) (4,9) (1,7) (3,5)}; |
|
461 |
\draw[green,line width=2pt] (0,0) to[quick curve through={(6,4) (4,9) (1,7)}] (3,5); |
|
462 |
\end{tikzpicture} |
|
463 |
||
464 |
||
158.1.3
by Andrew Stacey
Added externalisation method to hobby, other code clean-ups and bug fixes |
465 |
\begin{tikzpicture}[use Hobby shortcut, c/.style={insert path={circle[radius=2pt]}}] |
125
by Andrew Stacey (Thargelion)
Added test file for hobby |
466 |
\fill[green] (0,0) [c] (1,.5) [c] (0,0) [c] (3,.5) [c] (4,0) [c]; |
127
by Andrew Stacey
Defining array-like functions |
467 |
\draw (0,0) .. (1,.5) .. (-0.2,0) .. (3,.5) .. (4,0);
|
126
by Andrew Stacey
Added "edge case" section to hobby code |
468 |
\end{tikzpicture} |
469 |
||
470 |
\begin{tikzpicture} |
|
471 |
\draw (0.0000, 0.0000) .. controls (-1.85420, 0.83131) and (1.44747, 2.48215)..(1.0000, 0.5000) .. controls (0.90917, 0.09765) and (0.31923, 0.27721)..(0.1000, 0.0000) .. controls (-1.10155, -1.51937) and (1.46789, -0.02595)..(3.0000, 0.5000) .. controls (3.41450, 0.64229) and (3.86513, 0.41698)..(4.0000, 0.0000);
|
|
472 |
\end{tikzpicture} |
|
473 |
||
474 |
\begin{tikzpicture} |
|
475 |
\draw (0.0000, 0.0000) .. controls (0.30056, -0.75821) and (1.42623, -0.19537)..(1.0000, 0.5000) .. controls (0.69595, 0.99605) and (-0.14029, 0.67496)..(0.0000, 0.0000) .. controls (0.31344, -1.50803) and (1.85232, 0.35331)..(3.0000, 0.5000) .. controls (3.40390, 0.55162) and (3.79896, 0.35409)..(4.0000, 0.0000);
|
|
476 |
\end{tikzpicture} |
|
477 |
||
478 |
\begin{tikzpicture} |
|
479 |
\draw (0,0) to[curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); |
|
480 |
\end{tikzpicture} |
|
481 |
||
482 |
\begin{tikzpicture} |
|
483 |
\draw (0,0) to[closed,curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); |
|
125
by Andrew Stacey (Thargelion)
Added test file for hobby |
484 |
\end{tikzpicture} |
485 |
\end{document} |
|
486 |
||
487 |
||
488 |
% Local Variables:
|
|
489 |
% tex-output-type: "pdf18"
|
|
161.2.15
by Andrew Stacey
Fixed Hobby code to deal with changes to l3fp |
490 |
% End:
|