~tex-sx/tex-sx/development

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: