-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathBSplineSurface.html
executable file
·380 lines (295 loc) · 21.3 KB
/
BSplineSurface.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
<!DOCTYPE html><html xmlns:dc="http://purl.org/dc/terms/"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width"><link rel=stylesheet type="text/css" href="/style.css">
<script type="text/x-mathjax-config"> MathJax.Hub.Config({"HTML-CSS": { availableFonts: ["STIX","TeX"], linebreaks: { automatic:true }, preferredFont: "TeX" },
tex2jax: { displayMath: [ ["$$","$$"], ["\\[", "\\]"] ], inlineMath: [ ["$", "$"], ["\\\\(","\\\\)"] ], processEscapes: true } });
</script><script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_HTML-full"></script></head><body> <div class="header">
<nav><p><a href="#navigation">Menu</a> - <a href="#top">Top</a> - <a href="/">Home</a></nav></div>
<div class="mainarea" id="top">
<h1 id="bsplinesurface">BSplineSurface</h1>
<p><a href="index.html">Back to documentation index.</a></p>
<p><a name="BSplineSurface"></a>
### new BSplineSurface(controlPoints, knotsU, knotsV, [bits])</p>
<p><strong>Augments:</strong> <a href="Surface.html">Surface</a></p>
<p>A <a href="Surface.html">surface evaluator object</a> for a B-spline (basis spline) surface,
whose edges are made up of B-spline curves. For more on B-spline curves, see the constructor
for <a href="BSplineCurve.html">BSplineCurve</a>.</p>
<h4 id="parameters">Parameters</h4>
<ul>
<li><code>controlPoints</code> (Type: Array.<Array.<Array.<number»>)<br />An array of control point arrays, which in turn contain a number of control points. Each control point is an array with the same length as the other control points. It is assumed that:<ul> <li>The length of this parameter is the number of control points in each row of the v-axis. <li>The length of the first control point array is the number of control points in each column of the u-axis. <li>The first control point’s length represents the size of all the control points. </ul></li>
<li><code>knotsU</code> (Type: Array.<number>)<br />Knot vector of the surface, along the u-axis. For more information, see <a href="BSplineCurve.html">BSplineCurve</a>.</li>
<li><code>knotsV</code> (Type: Array.<number>)<br />Knot vector of the surface, along the v-axis.</li>
<li><code>bits</code> (Type: number) (optional)<br />Bits for defining input and controlling output. Zero or more of <a href="BSplineCurve.html#BSplineCurve.DIVIDE_BIT">BSplineCurve.DIVIDE_BIT</a>. If null, undefined, or omitted, no bits are set.</li>
</ul>
<h4 id="examples">Examples</h4>
<p>Together with ‘convertToHomogen’ given in the <a href="BSplineCurve.html">BSplineCurve</a> documentation, the following function can be used
to convert an array of arrays of control points, each consisting of conventional
coordinates and a weight, to homogeneous coordinates.
For example, the single-control point array
‘[[[2, 3, 4, 0.1]]]’ becomes ‘[[[0.2, 0.3, 0.4, 0.1]]]’; the
return value can then be used in the BSplineSurface constructor
to create a rational B-Spline surface.</p>
<pre>function convertSurfaceToHomogen(cp) {
var ret = [];
for(var i = 0; i < cp.length; i++) {
ret.push(convertToHomogen(cp[i]));
}
return ret;
};
</pre>
<h3 id="methods">Methods</h3>
<ul>
<li><a href="#BSplineSurface_bitangent">bitangent</a><br />Finds the <a href="Surface.html">bitangent vector</a> at the specified point on the surface.</li>
<li><a href="#BSplineSurface.clamped">clamped</a><br />Creates a B-spline surface with uniform knots, except that
the surface’s edges lie on the edges of the control point array.</li>
<li><a href="#BSplineSurface_endPoints">endPoints</a><br />Returns the starting and ending u- and v-coordinates of this surface.</li>
<li><a href="#BSplineSurface_evaluate">evaluate</a><br />Evaluates the surface function based on a point
in a B-spline surface.</li>
<li><a href="#BSplineSurface.fromBezierSurface">fromBezierSurface</a><br />Creates a B-spline surface from the control points of a Bézier surface.</li>
<li><a href="#BSplineSurface_getControlPoints">getControlPoints</a><br />Gets a reference to the array of control point arrays used
in this surface object.</li>
<li><a href="#BSplineSurface_getKnots">getKnots</a><br />Gets a reference to the array of knot vectors used
in this curve object.</li>
<li><a href="#BSplineSurface_gradient">gradient</a><br />Finds an approximate gradient vector of this surface at the specified u- and v-coordinates.</li>
<li><a href="#BSplineSurface_normal">normal</a><br />Convenience method for finding an approximate normal vector of this surface at the specified u- and v-coordinates.</li>
<li><a href="#BSplineSurface_tangent">tangent</a><br />Finds the <a href="Surface.html">tangent vector</a> at the specified point on the surface.</li>
<li><a href="#BSplineSurface.uniform">uniform</a><br />Creates a B-spline surface with uniform knots.</li>
</ul>
<p><a name="BSplineSurface_bitangent"></a>
### BSplineSurface#bitangent(u, v)</p>
<p>Finds the <a href="Surface.html">bitangent vector</a> at the specified point on the surface.</p>
<h4 id="parameters-1">Parameters</h4>
<ul>
<li><code>u</code> (Type: number)<br />The u-coordinate of the surface to evaluate.</li>
<li><code>v</code> (Type: number)<br />The v-coordinate of the surface to evaluate.</li>
</ul>
<h4 id="return-value">Return Value</h4>
<p>An array giving the bitangent vector.
It will have as many elements as a control point (or one fewer
if DIVIDE_BIT is set), as specified in the constructor. (Type: Array.<number>)</p>
<p><a name="BSplineSurface.clamped"></a>
### (static) BSplineSurface.clamped(controlPoints, [degreeU], [degreeV], [bits])</p>
<p>Creates a B-spline surface with uniform knots, except that
the surface’s edges lie on the edges of the control point array.</p>
<h4 id="parameters-2">Parameters</h4>
<ul>
<li><code>controlPoints</code> (Type: Array.<Array.<Array.<number»>)<br />Array of control point arrays as specified in the <a href="BSplineSurface.html">BSplineSurface</a> constructor.</li>
<li><code>degreeU</code> (Type: number) (optional)<br />Degree of the B-spline surface along the u-axis. For example, 3 means a degree-3 (cubic) curve. If null, undefined, or omitted, the default is 3.</li>
<li><code>degreeV</code> (Type: number) (optional)<br />Degree of the B-spline surface along the v-axis If null, undefined, or omitted, the default is 3.</li>
<li><code>bits</code> (Type: number) (optional)<br />Bits as specified in the <a href="BSplineSurface.html">BSplineSurface</a> constructor.</li>
</ul>
<h4 id="return-value-1">Return Value</h4>
<p>Return value. The first
knot of the curve will be 0 and the last knot will be 1. (Type: <a href="BSplineSurface.html">BSplineSurface</a>)</p>
<p><a name="BSplineSurface_endPoints"></a>
### BSplineSurface#endPoints()</p>
<p>Returns the starting and ending u- and v-coordinates of this surface.
This method calls the evaluator’s <code>endPoints</code>
method if it implements it; otherwise, returns <code>[0, 1, 0, 1]</code></p>
<h4 id="return-value-2">Return Value</h4>
<p>A four-element array. The first and second
elements are the starting and ending u-coordinates, respectively, of the surface, and the third
and fourth elements are its starting and ending v-coordinates.
Returns <code>[0, 1, 0, 1]</code> if the evaluator doesn’t implement an <code>endPoints</code>
method.</p>
<p><a name="BSplineSurface_evaluate"></a>
### BSplineSurface#evaluate(u, v)</p>
<p>Evaluates the surface function based on a point
in a B-spline surface.</p>
<h4 id="parameters-3">Parameters</h4>
<ul>
<li><code>u</code> (Type: number)<br />The u-coordinate of the surface to evaluate.</li>
<li><code>v</code> (Type: number)<br />The v-coordinate of the surface to evaluate.</li>
</ul>
<h4 id="return-value-3">Return Value</h4>
<p>An array of the result of
the evaluation. It will have as many elements as a control point (or one fewer
if DIVIDE_BIT is set), as specified in the constructor. (Type: Array.<number>)</p>
<p><a name="BSplineSurface.fromBezierSurface"></a>
### (static) BSplineSurface.fromBezierSurface(controlPoints, [bits])</p>
<p>Creates a B-spline surface from the control points of a Bézier surface.</p>
<h4 id="parameters-4">Parameters</h4>
<ul>
<li><code>controlPoints</code> (Type: Array.<Array.<Array.<number»>)<br />An array of control point arrays, which in turn contain a number of control points. Each control point is an array with the same length as the other control points. It is assumed that:<ul> <li>The length of this parameter minus 1 represents the degree of the Bézier surface along the v-axis. For example, a degree-3 (cubic) surface along the v-axis contains 4 control points, one in each control point array. A degree of 1 on both the u- and v-axes results in a flat surface. <li>The length of the first control point array minus 1 represents the degree of the Bézier surface along the u-axis. <li>The number of elements in the first control point represents the number of elements in all the control points. </ul></li>
<li><code>bits</code> (Type: number) (optional)<br />Bits as specified in the <a href="BSplineSurface.html">BSplineSurface</a> constructor.</li>
</ul>
<h4 id="return-value-4">Return Value</h4>
<p>Return value. (Type: <a href="BSplineSurface.html">BSplineSurface</a>)</p>
<p><a name="BSplineSurface_getControlPoints"></a>
### BSplineSurface#getControlPoints()</p>
<p>Gets a reference to the array of control point arrays used
in this surface object.</p>
<h4 id="return-value-5">Return Value</h4>
<p>An object described in the constructor to <a href="BSplineCurve.html">BSplineCurve</a>. (Type: Array.<Array.<number»)</p>
<p><a name="BSplineSurface_getKnots"></a>
### BSplineSurface#getKnots()</p>
<p>Gets a reference to the array of knot vectors used
in this curve object.</p>
<h4 id="return-value-6">Return Value</h4>
<p>An object described in the constructor to <a href="BSplineSurface.html">BSplineSurface</a>. (Type: Array.<Array.<number»)</p>
<p><a name="BSplineSurface_gradient"></a>
### BSplineSurface#gradient(u, v)</p>
<p>Finds an approximate gradient vector of this surface at the specified u- and v-coordinates.</p>
<p>The implementation in <a href="Surface.html">Surface</a> calls the evaluator’s <code>gradient</code>
method if it implements it; otherwise uses the surface’s tangent and bitangent vectors to implement the gradient
(however, this approach is generally only meaningful for a surface in three-dimensional space).</p>
<p>The <b>gradient</b> is a vector pointing up and away from the surface.
If the evaluator describes a regular three-dimensional surface (usually
a continuous, unbroken surface such as a sphere, an open
cylinder, or a disk rotated in three dimensions), this can be the cross product
of the <a href="Surface.html#Surface_tangent">tangent vector</a>
and <a href="Surface.html#Surface_bitangent">bitangent vector</a>,
in that order. The gradient returned by this method <i>should not</i> be “normalized” to a unit vector.</p>
<h4 id="parameters-5">Parameters</h4>
<ul>
<li><code>u</code> (Type: number)<br />The u-coordinate of a point on the surface.</li>
<li><code>v</code> (Type: number)<br />The v-coordinate of a point on the surface.</li>
</ul>
<h4 id="return-value-7">Return Value</h4>
<p>An array describing a gradient vector. It should have at least as many
elements as the number of dimensions of the underlying surface. (Type: Array.<number>)</p>
<h4 id="examples-1">Examples</h4>
<p>The following example is a surface evaluator
object for a parametric surface with a gradient method. To illustrate how the gradient method is derived
from the vector calculation method, that method is also given later. To
derive the normal calculation, first look at the vector function:</p>
<p><b>F</b>(u, v) = (cos(u), sin(u), sin(u)*cos(v))</p>
<p>Then, find the partial derivatives with respect to <i>u</i> and to <i>v</i>:</p>
<p>∂<b>F</b>/∂<i>u</i> = (-sin(u), cos(u), cos(u)*cos(v))<br />
∂<b>F</b>/∂<i>v</i> = (0, 0, -sin(v)*sin(u))</p>
<p>Next, take their cross product:</p>
<p><b>&Del;F</b>(u, v) = (-sin(v)*cos(u)*sin(u), -sin(v)*sin(u)*sin(u), 0)<br /></p>
<p>The result is the gradient, which will point up and away from the surface.</p>
<pre>var surface=new Surface({"evaluate":function(u,v) {
"use strict";
return [Math.cos(u),Math.sin(u),Math.sin(u)*Math.cos(v)];
},
"gradient":function(u,v) {
"use strict";
return [
Math.cos(u)*-Math.sin(v)*Math.sin(u),
Math.sin(u)*-Math.sin(v)*Math.sin(u),
0];
}})
</pre>
<p><a name="BSplineSurface_normal"></a>
### BSplineSurface#normal(u, v)</p>
<p>Convenience method for finding an approximate normal vector of this surface at the specified u- and v-coordinates.
The <b>normal vector</b> is the same as the gradient vector, but “normalized” to a unit vector.</p>
<h4 id="parameters-6">Parameters</h4>
<ul>
<li><code>u</code> (Type: number)<br />The u-coordinate of a point on the surface.</li>
<li><code>v</code> (Type: number)<br />The v-coordinate of a point on the surface.</li>
</ul>
<h4 id="return-value-8">Return Value</h4>
<p>An array describing a normal vector. It should have at least as many
elements as the number of dimensions of the underlying surface. (Type: Array.<number>)</p>
<p><a name="BSplineSurface_tangent"></a>
### BSplineSurface#tangent(u, v)</p>
<p>Finds the <a href="Surface.html">tangent vector</a> at the specified point on the surface.</p>
<h4 id="parameters-7">Parameters</h4>
<ul>
<li><code>u</code> (Type: number)<br />The u-coordinate of the surface to evaluate.</li>
<li><code>v</code> (Type: number)<br />The v-coordinate of the surface to evaluate.</li>
</ul>
<h4 id="return-value-9">Return Value</h4>
<p>An array giving the tangent vector.
It will have as many elements as a control point (or one fewer
if DIVIDE_BIT is set), as specified in the constructor. (Type: Array.<number>)</p>
<p><a name="BSplineSurface.uniform"></a>
### (static) BSplineSurface.uniform(controlPoints, [degreeU], [degreeV], [bits])</p>
<p>Creates a B-spline surface with uniform knots.</p>
<h4 id="parameters-8">Parameters</h4>
<ul>
<li><code>controlPoints</code> (Type: Array.<Array.<Array.<number»>)<br />Array of control point arrays as specified in the <a href="BSplineSurface.html">BSplineSurface</a> constructor.</li>
<li><code>degreeU</code> (Type: number) (optional)<br />Degree of the B-spline surface along the u-axis. For example, 3 means a degree-3 (cubic) curve. If null, undefined, or omitted, the default is 3.</li>
<li><code>degreeV</code> (Type: number) (optional)<br />Degree of the B-spline surface along the v-axis If null, undefined, or omitted, the default is 3.</li>
<li><code>bits</code> (Type: number) (optional)<br />Bits as specified in the <a href="BSplineSurface.html">BSplineSurface</a> constructor.</li>
</ul>
<h4 id="return-value-10">Return Value</h4>
<p>Return value. The first
knot of the curve will be 0 and the last knot will be 1. (Type: <a href="BSplineSurface.html">BSplineSurface</a>)</p>
<p><a href="index.html">Back to documentation index.</a></p>
</div><nav id="navigation"><ul>
<li><a href="/">Back to start site.</a>
<li><a href="https://github.com/peteroupc/peteroupc.github.io">This site's repository (source code)</a>
<li><a href="https://github.com/peteroupc/peteroupc.github.io/issues">Post an issue or comment</a></ul>
<div class="noprint">
<p>
<a href="//twitter.com/intent/tweet">Share via Twitter</a>, <a href="//www.facebook.com/sharer/sharer.php" id="sharer">Share via Facebook</a>
</p>
</div>
<h3 id="navigation">Navigation</h3>
<ul>
<li><a href="BSplineCurve.html">BSplineCurve</a></li>
<li><a href="BSplineSurface.html">BSplineSurface</a></li>
<li><a href="Curve.html">Curve</a></li>
<li><a href="CurveBuilder.html">CurveBuilder</a></li>
<li><a href="GraphicsPath.html">GraphicsPath</a></li>
<li><a href="H3DU.html">H3DU</a></li>
<li><a href="MathUtil.html">MathUtil</a></li>
<li><a href="MeshBuffer.html">MeshBuffer</a></li>
<li><a href="Meshes.html">Meshes</a></li>
<li><a href="PiecewiseCurve.html">PiecewiseCurve</a></li>
<li><a href="Surface.html">Surface</a></li>
<li><a href="SurfaceBuilder.html">SurfaceBuilder</a></li>
<li><a href="Transform.html">Transform</a></li>
<li><a href="extras_camera.html">module:extras/camera</a></li>
<li><a href="extras_camera.Camera.html">module:extras/camera.Camera</a></li>
<li><a href="extras_camera.InputTracker.html">module:extras/camera.InputTracker</a></li>
<li><a href="extras_createwasher.html">module:extras/createwasher</a></li>
<li><a href="extras_curvetube.html">module:extras/curvetube</a></li>
<li><a href="extras_curvetube.CurveTube.html">module:extras/curvetube.CurveTube</a></li>
<li><a href="extras_derivedcurves.html">module:extras/derivedcurves</a></li>
<li><a href="extras_evaluators.html">module:extras/evaluators</a></li>
<li><a href="extras_evaluators.Roulette.html">module:extras/evaluators.Roulette</a></li>
<li><a href="extras_evaluators.SurfaceOfRevolution.html">module:extras/evaluators.SurfaceOfRevolution</a></li>
<li><a href="extras_fourierknot.html">module:extras/fourierknot</a></li>
<li><a href="extras_gradients.html">module:extras/gradients</a></li>
<li><a href="extras_matrixstack.html">module:extras/matrixstack</a></li>
<li><a href="extras_matrixstack.MatrixStack.html">module:extras/matrixstack.MatrixStack</a></li>
<li><a href="extras_meshes_arrow.html">module:extras/meshes/arrow</a></li>
<li><a href="extras_meshes_contourlines.html">module:extras/meshes/contourlines</a></li>
<li><a href="extras_meshes_convex.html">module:extras/meshes/convex</a></li>
<li><a href="extras_meshes_createfloor.html">module:extras/meshes/createfloor</a></li>
<li><a href="extras_meshes_drawingtoy.html">module:extras/meshes/drawingtoy</a></li>
<li><a href="extras_meshes_drawingtoy.DrawingToy.html">module:extras/meshes/drawingtoy.DrawingToy</a></li>
<li><a href="extras_meshes_gearmesh.html">module:extras/meshes/gearmesh</a></li>
<li><a href="extras_meshes_pathtomesh.html">module:extras/meshes/pathtomesh</a></li>
<li><a href="extras_meshes_polyhedra.html">module:extras/meshes/polyhedra</a></li>
<li><a href="extras_meshes_polyhedra.Polyhedra.html">module:extras/meshes/polyhedra.Polyhedra</a></li>
<li><a href="extras_meshes_raypick.html">module:extras/meshes/raypick</a></li>
<li><a href="extras_meshes_starfield.html">module:extras/meshes/starfield</a></li>
<li><a href="extras_meshes_starfield.StarField.html">module:extras/meshes/starfield.StarField</a></li>
<li><a href="extras_meshes_stl.html">module:extras/meshes/stl</a></li>
<li><a href="extras_meshes_text.html">module:extras/meshes/text</a></li>
<li><a href="extras_meshes_text.TextFont.html">module:extras/meshes/text.TextFont</a></li>
<li><a href="extras_moresurfaces.html">module:extras/moresurfaces</a></li>
<li><a href="extras_moresurfaces.KleinBottle.html">module:extras/moresurfaces.KleinBottle</a></li>
<li><a href="extras_moresurfaces.MoebiusStrip.html">module:extras/moresurfaces.MoebiusStrip</a></li>
<li><a href="extras_pathutil.html">module:extras/pathutil</a></li>
<li><a href="extras_randompolygon.html">module:extras/randompolygon</a></li>
<li><a href="extras_shaders_checkerboardshader.html">module:extras/shaders/checkerboardshader</a></li>
<li><a href="extras_shaders_colormatrixshader.html">module:extras/shaders/colormatrixshader</a></li>
<li><a href="extras_shaders_fragmentshaderlib.html">module:extras/shaders/fragmentshaderlib</a></li>
<li><a href="extras_shaders_horgradshader.html">module:extras/shaders/horgradshader</a></li>
<li><a href="extras_shaders_kernelmatrixshader.html">module:extras/shaders/kernelmatrixshader</a></li>
<li><a href="extras_shaders_marbleshader.html">module:extras/shaders/marbleshader</a></li>
<li><a href="extras_shaders_marbleshader2.html">module:extras/shaders/marbleshader2</a></li>
<li><a href="extras_shaders_mirrorshader.html">module:extras/shaders/mirrorshader</a></li>
<li><a href="extras_shaders_pixelateshader.html">module:extras/shaders/pixelateshader</a></li>
<li><a href="extras_shaders_radgradshader.html">module:extras/shaders/radgradshader</a></li>
<li><a href="extras_shaders_skysphereshader.html">module:extras/shaders/skysphereshader</a></li>
<li><a href="extras_shaders_stripesbackshader.html">module:extras/shaders/stripesbackshader</a></li>
<li><a href="extras_shaders_sunburstbackshader.html">module:extras/shaders/sunburstbackshader</a></li>
<li><a href="extras_shaders_vignetteshader.html">module:extras/shaders/vignetteshader</a></li>
<li><a href="extras_shaders_warpshader.html">module:extras/shaders/warpshader</a></li>
<li><a href="extras_shaders_waterpaintshader.html">module:extras/shaders/waterpaintshader</a></li>
<li><a href="extras_shaders_waveshader.html">module:extras/shaders/waveshader</a></li>
<li><a href="extras_shaders_woodshader.html">module:extras/shaders/woodshader</a></li>
<li><a href="extras_starpolygon.html">module:extras/starpolygon</a></li>
<li><a href="extras_superellipsoid.html">module:extras/superellipsoid</a></li>
<li><a href="extras_superellipsoid.Supershape.html">module:extras/superellipsoid.Supershape</a></li>
<li><a href="extras_superellipsoid.Supertoroid.html">module:extras/superellipsoid.Supertoroid</a></li>
<li><a href="extras_torusknot.html">module:extras/torusknot</a></li>
<li><a href="extras_torusknot.TorusKnot.html">module:extras/torusknot.TorusKnot</a></li>
</ul>
</nav></body></html>