1include<../std.scad>
2
3
4module test_is_path() {
5 assert(is_path([[1,2,3],[4,5,6]]));
6 assert(is_path([[1,2,3],[4,5,6],[7,8,9]]));
7 assert(!is_path(123));
8 assert(!is_path("foo"));
9 assert(!is_path(true));
10 assert(!is_path([]));
11 assert(!is_path([[]]));
12 assert(!is_path([["foo","bar","baz"]]));
13 assert(!is_path([[1,2,3]]));
14 assert(!is_path([["foo","bar","baz"],["qux","quux","quuux"]]));
15}
16test_is_path();
17
18
19module test_is_1region() {
20 assert(!is_1region([[3,4],[5,6],[7,8]]));
21 assert(is_1region([[[3,4],[5,6],[7,8]]]));
22}
23test_is_1region();
24
25
26module force_path() {
27 assert_equal(force_path([[3,4],[5,6],[7,8]]), [[3,4],[5,6],[7,8]]);
28 assert_equal(force_path([[[3,4],[5,6],[7,8]]]), [[3,4],[5,6],[7,8]]);
29 assert_equal(force_path("abc"), "abc");
30 assert_equal(force_path(13), 13);
31}
32test_is_1region();
33
34
35module test_path_merge_collinear() {
36 path = [[-20,-20], [-10,-20], [0,-10], [10,0], [20,10], [20,20], [15,30]];
37 assert(path_merge_collinear(path) == [[-20,-20], [-10,-20], [20,10], [20,20], [15,30]]);
38 assert(path_merge_collinear([path]) == [[-20,-20], [-10,-20], [20,10], [20,20], [15,30]]);
39 sq=square(10);
40 assert_equal(path_merge_collinear(subdivide_path(square(10), refine=25),closed=true), sq);
41}
42test_path_merge_collinear();
43
44
45module test_path_length(){
46 sq = square(10);
47 assert_equal(path_length(sq),30);
48 assert_equal(path_length(sq,true),40);
49 c = circle($fn=1000, r=1);
50 assert(approx(path_length(c,closed=true), 2*PI,eps=.0001));
51}
52test_path_length();
53
54
55module test_path_segment_lengths(){
56 sq = square(10);
57 assert_equal(path_segment_lengths(sq), [10,10,10]);
58 assert_equal(path_segment_lengths(sq,true), [10,10,10,10]);
59 c = circle($fn=1000, r=1);
60 assert(approx(path_segment_lengths(c,closed=true), repeat(2*PI/1000,1000),eps=1e-7));
61}
62test_path_segment_lengths();
63
64
65module test_path_length_fractions(){
66 sq = square(10);
67 assert_approx(path_length_fractions(sq), [0,1/3, 2/3, 1]);
68 assert_approx(path_length_fractions(sq,true), [0,1/4, 2/4,3/4, 1]);
69}
70test_path_length_fractions();
71
72
73
74module test_subdivide_path(){
75 assert(approx(subdivide_path(square([2,2],center=true), 12), [[1, -1], [1/3, -1], [-1/3, -1], [-1, -1], [-1, -1/3], [-1, 1/3], [-1, 1], [-1/3, 1], [1/3, 1], [1, 1], [1, 1/3], [1, -1/3]]));
76 assert_equal(subdivide_path(square([8,2],center=true), 12), [[4, -1], [2, -1], [0, -1], [-2, -1], [-4, -1], [-4, 0], [-4, 1], [-2, 1], [0, 1], [2, 1], [4, 1], [4, 0]]);
77 assert_approx(subdivide_path(square([8,2],center=true), 12, method="segment"), [[4, -1], [4/3, -1], [-4/3, -1], [-4, -1], [-4, -1/3], [-4, 1/3], [-4, 1], [-4/3, 1], [4/3, 1], [4, 1], [4, 1/3], [4, -1/3]]);
78 assert_approx(subdivide_path(square([2,2],center=true), 17, closed=false), [[1, -1], [0.6, -1], [0.2, -1], [-0.2, -1], [-0.6, -1], [-1, -1], [-1, -2/3], [-1, -1/3], [-1, 0], [-1, 1/3], [-1, 2/3], [-1, 1], [-0.6, 1], [-0.2, 1], [0.2, 1], [0.6, 1], [1, 1]]);
79 assert_approx(subdivide_path(hexagon(side=2), [2,3,4,5,6,7], method="segment"),
80 [[2, 0], [1.5, -0.866025403784], [1, -1.73205080757],
81 [0.333333333333, -1.73205080757], [-0.333333333333,
82 -1.73205080757], [-1, -1.73205080757], [-1.25,
83 -1.29903810568], [-1.5, -0.866025403784], [-1.75,
84 -0.433012701892], [-2, 0], [-1.8, 0.346410161514],
85 [-1.6, 0.692820323028], [-1.4, 1.03923048454], [-1.2,
86 1.38564064606], [-1, 1.73205080757], [-0.666666666667,
87 1.73205080757], [-0.333333333333, 1.73205080757], [0,
88 1.73205080757], [0.333333333333, 1.73205080757],
89 [0.666666666667, 1.73205080757], [1, 1.73205080757],
90 [1.14285714286, 1.48461497792], [1.28571428571,
91 1.23717914826], [1.42857142857, 0.989743318611],
92 [1.57142857143, 0.742307488958], [1.71428571429,
93 0.494871659305], [1.85714285714, 0.247435829653]]);
94 assert_approx(subdivide_path(pentagon(side=2), [3,4,3,4], method="segment", closed=false),
95 [[1.7013016167, 0], [1.30944478184, -0.539344662917],
96 [0.917587946981, -1.07868932583], [0.525731112119,
97 -1.61803398875], [0.0502028539716, -1.46352549156],
98 [-0.425325404176, -1.30901699437], [-0.900853662324,
99 -1.15450849719], [-1.37638192047, -1], [-1.37638192047,
100 -0.333333333333], [-1.37638192047, 0.333333333333],
101 [-1.37638192047, 1], [-0.900853662324, 1.15450849719],
102 [-0.425325404176, 1.30901699437], [0.0502028539716,
103 1.46352549156], [0.525731112119, 1.61803398875]]);
104 assert_approx(subdivide_path(pentagon(side=2), 17),
105 [[1.7013016167, 0], [1.30944478184,
106 -0.539344662917], [0.917587946981, -1.07868932583],
107 [0.525731112119, -1.61803398875], [0.0502028539716,
108 -1.46352549156], [-0.425325404176, -1.30901699437],
109 [-0.900853662324, -1.15450849719], [-1.37638192047,
110 -1], [-1.37638192047, -0.333333333333],
111 [-1.37638192047, 0.333333333333], [-1.37638192047,
112 1], [-0.900853662324, 1.15450849719],
113 [-0.425325404176, 1.30901699437], [0.0502028539716,
114 1.46352549156], [0.525731112119, 1.61803398875],
115 [0.917587946981, 1.07868932583], [1.30944478184,
116 0.539344662917]]);
117 assert_approx(subdivide_path(pentagon(side=2), 17, exact=false),
118 [[1.7013016167, 0], [1.30944478184,
119 -0.539344662917], [0.917587946981, -1.07868932583],
120 [0.525731112119, -1.61803398875], [-0.108306565411,
121 -1.41202265917], [-0.742344242941, -1.20601132958],
122 [-1.37638192047, -1], [-1.37638192047,
123 -0.333333333333], [-1.37638192047, 0.333333333333],
124 [-1.37638192047, 1], [-0.742344242941,
125 1.20601132958], [-0.108306565411, 1.41202265917],
126 [0.525731112119, 1.61803398875], [0.917587946981,
127 1.07868932583], [1.30944478184, 0.539344662917]]);
128 assert_approx(subdivide_path(pentagon(side=2), 18, exact=false),
129 [[1.7013016167, 0], [1.40740899056,
130 -0.404508497187], [1.11351636441,
131 -0.809016994375], [0.819623738265,
132 -1.21352549156], [0.525731112119, -1.61803398875],
133 [0.0502028539716, -1.46352549156],
134 [-0.425325404176, -1.30901699437],
135 [-0.900853662324, -1.15450849719],
136 [-1.37638192047, -1], [-1.37638192047, -0.5],
137 [-1.37638192047, 0], [-1.37638192047, 0.5],
138 [-1.37638192047, 1], [-0.900853662324,
139 1.15450849719], [-0.425325404176, 1.30901699437],
140 [0.0502028539716, 1.46352549156], [0.525731112119,
141 1.61803398875], [0.819623738265, 1.21352549156],
142 [1.11351636441, 0.809016994375], [1.40740899056,
143 0.404508497187]]);
144 assert_approx(subdivide_path([[0,0,0],[2,0,1],[2,3,2]], 12),
145 [[0, 0, 0], [2/3, 0, 1/3], [4/3, 0, 2/3], [2, 0, 1], [2, 0.75, 1.25], [2, 1.5, 1.5], [2, 2.25, 1.75], [2, 3, 2], [1.6, 2.4, 1.6], [1.2, 1.8, 1.2], [0.8, 1.2, 0.8], [0.4, 0.6, 0.4]]);
146
147 path = pentagon(d=100);
148 spath = subdivide_path(path, maxlen=10, closed=true);
149 assert_approx(spath,
150 [[50, 0], [44.2418082865, -7.92547096913], [38.4836165729,
151 -15.8509419383], [32.7254248594, -23.7764129074], [26.9672331458,
152 -31.7018838765], [21.2090414323, -39.6273548456], [15.4508497187,
153 -47.5528258148], [6.1338998125, -44.5255652814], [-3.18305009375,
154 -41.498304748], [-12.5, -38.4710442147], [-21.8169499062,
155 -35.4437836813], [-31.1338998125, -32.416523148], [-40.4508497187,
156 -29.3892626146], [-40.4508497187, -19.5928417431], [-40.4508497187,
157 -9.79642087154], [-40.4508497187, 0], [-40.4508497187, 9.79642087154],
158 [-40.4508497187, 19.5928417431], [-40.4508497187, 29.3892626146],
159 [-31.1338998125, 32.416523148], [-21.8169499062, 35.4437836813],
160 [-12.5, 38.4710442147], [-3.18305009375, 41.498304748], [6.1338998125,
161 44.5255652814], [15.4508497187, 47.5528258148], [21.2090414323,
162 39.6273548456], [26.9672331458, 31.7018838765], [32.7254248594,
163 23.7764129074], [38.4836165729, 15.8509419383], [44.2418082865,
164 7.92547096913]]);
165}
166test_subdivide_path();
167
168
169module test_subdivide_long_segments(){
170}
171test_subdivide_long_segments();
172
173
174module test_resample_path(){
175 path = xscale(2,circle($fn=250, r=10));
176 assert_approx(
177 resample_path(path, 16), [
178 [20, 0],
179 [17.1657142861, -5.13020769642],
180 [11.8890531315, -8.04075246881],
181 [6.03095737128, -9.53380030092],
182 [1.72917236085e-14, -9.99921044204],
183 [-6.03095737128, -9.53380030092],
184 [-11.8890531315, -8.04075246881],
185 [-17.1657142861, -5.13020769642],
186 [-20, -3.19176120946e-14],
187 [-17.1657142861, 5.13020769642],
188 [-11.8890531315, 8.04075246881],
189 [-6.03095737128, 9.53380030092],
190 [-4.20219414821e-14, 9.99921044204],
191 [6.03095737128, 9.53380030092],
192 [11.8890531315, 8.04075246881],
193 [17.1657142861, 5.13020769642]
194 ]
195 );
196 path2 = square(20);
197 assert_approx(
198 resample_path(path2, spacing=6), [
199 [20, 0], [13.8461538462, 0], [7.69230769231, 0],
200 [1.53846153846, 0], [0, 4.61538461538],
201 [0, 10.7692307692], [0, 16.9230769231],
202 [3.07692307692, 20], [9.23076923077, 20],
203 [15.3846153846, 20], [20, 18.4615384615],
204 [20, 12.3076923077], [20, 6.15384615385]
205 ]
206 );
207 assert_equal(
208 resample_path(path2, spacing=6,closed=false), [
209 [20, 0], [14, 0], [ 8, 0], [ 2, 0],
210 [ 0, 4], [ 0,10], [ 0,16], [ 2,20],
211 [ 8,20], [14,20], [20,20]
212 ]
213 );
214 assert_equal(
215 resample_path(path2, n=7, keep_corners=90, closed=true), [
216 [20,0],[10,0],[0,0],[0,10],[0,20],[20,20],[20,10]
217 ]
218 );
219 assert_equal(
220 resample_path(path2, n=7, keep_corners=90, closed=false), [
221 [20,0],[10,0],[0,0],[0,10],[0,20],[10,20],[20,20]
222 ]
223 );
224 assert_approx(
225 resample_path(path2, spacing=6, keep_corners=90, closed=false), [
226 [20, 0], [13.3333333333, 0], [6.66666666667,0],
227 [ 0, 0], [ 0,6.66666666667], [0,13.3333333333],
228 [ 0,20], [ 6.66666666667,20], [13.3333333333,20],
229 [20,20]
230 ]
231 );
232 assert_approx(
233 resample_path(path2, spacing=6, keep_corners=90), [
234 [20, 0], [13.3333333333, 0], [ 6.66666666667, 0],
235 [ 0, 0], [ 0, 6.66666666667], [ 0,13.3333333333],
236 [ 0,20], [ 6.66666666667,20], [13.3333333333,20],
237 [20,20], [20,13.3333333333], [20, 6.66666666667]
238 ]
239 );
240 assert_approx(
241 resample_path(path, spacing=17), [
242 [20, 0], [8.01443073309, -9.16170407964],
243 [-8.01443073309, -9.16170407964], [-20, -1.59309060367e-14],
244 [-8.01443073309, 9.16170407964], [8.01443073309, 9.16170407964]
245 ]
246 );
247}
248test_resample_path();
249
250
251module test_path_closest_point(){
252 path = circle(d=100,$fn=6);
253 pt = [20,10];
254 closest = path_closest_point(path, pt);
255 assert_approx(closest, [5, [38.1698729811, 20.4903810568]]);
256}
257test_path_closest_point();
258
259
260
261module test_path_tangents(){
262 path = circle(r=1, $fn=200);
263 path_t = path_tangents(path,closed=true);
264 assert_approx(path_t, hstack(column(path,1), -column(path,0)));
265 rect = square([10,3]);
266 tr1 = path_tangents(rect,closed=true);
267 tr2 = path_tangents(rect,closed=true,uniform=false);
268 tr3 = path_tangents(rect,closed=false);
269 tr4 = path_tangents(rect,closed=false,uniform=false);
270 assert_approx(tr1, [[-0.957826285221, -0.287347885566], [-0.957826285221, 0.287347885566], [0.957826285221, 0.287347885566], [0.957826285221, -0.287347885566]]);
271 assert_approx(tr2, [[-0.707106781187, -0.707106781187], [-0.707106781187, 0.707106781187], [0.707106781187, 0.707106781187], [0.707106781187, -0.707106781187]]);
272 assert_approx(tr3, [[-0.99503719021, -0.099503719021], [-0.957826285221, 0.287347885566], [0.957826285221, 0.287347885566], [0.99503719021, -0.099503719021]]);
273 assert_approx(tr4, [[-1, 0], [-0.707106781187, 0.707106781187], [0.707106781187, 0.707106781187], [1, 0]]);
274}
275test_path_tangents();
276
277
278
279module test_path_curvature(){
280 c8 = path3d(circle(r=8, $fn=100));
281 c28 = path3d(circle(r=28, $fn=100));
282 assert(approx(path_curvature(c8,closed=true), repeat(1/8, 100), 4e-4));
283 assert(approx(path_curvature(c28,closed=true), repeat(1/28, 100), 4e-4));
284}
285test_path_curvature();
286
287
288module test_path_torsion(){
289 c = path3d(circle(r=1, $fn=100));
290 tc = path_torsion(c, closed=true);
291 assert(all_zero(tc));
292 a=3;b=7;
293 helix = [for(t=[0:1:20]) [a*cos(t), a*sin(t), b*t*PI/180]];
294 th = path_torsion(helix, closed=false);
295 assert(approx(th[5], b/(a*a+b*b), 1e-5));
296}
297test_path_torsion();
298
299
300
301module test_is_path_simple(){
302 assert(is_path_simple([[0,0],[1,1],[1,1],[2,1]]));
303 assert(is_path_simple([[0,0],[10,0],[0,20],[10,20]],closed=false));
304 assert(!is_path_simple([[0,0],[10,0],[0,20],[10,20]],closed=true));
305 assert(is_path_simple(circle($fn=20, r=10)));
306}
307
308