tg-sys 0.1.1

unsafe low-level bindings to the `tg` geometry library
Documentation
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
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
#include "tests.h"

void test_segment_raycast() {
    // This is full coverage raycast test. It uses a 7x7 grid where the each
    // point is checked for a total of 49 tests per segment. There are 16
    // segments at 0º,30º,45º,90º,180º in both directions for a total of 784
    // tests.
    // The '-' character is OUT
    // The '+' character is IN
    // The '*' character is ON
    void *segs[] = {
        SA(1, 1, 5, 5), "A",
        SA(5, 5, 1, 1), "B",
            "-------",
            "-----*-",
            "++++*--",
            "+++*---",
            "++*----",
            "+*-----",
            "-------",
        SA(1, 5, 5, 1), "C",
        SA(5, 1, 1, 5), "D",
            "-------",
            "-*-----",
            "++*----",
            "+++*---",
            "++++*--",
            "+++++*-",
            "-------",
        SA(1, 3, 5, 3), "E",
        SA(5, 3, 1, 3), "F",
            "-------",
            "-------",
            "-------",
            "-*****-",
            "-------",
            "-------",
            "-------",
        SA(3, 5, 3, 1), "G",
        SA(3, 1, 3, 5), "H",
            "-------",
            "---*---",
            "+++*---",
            "+++*---",
            "+++*---",
            "+++*---",
            "-------",
        SA(1, 2, 5, 4), "I",
        SA(5, 4, 1, 2), "J",
            "-------",
            "-------",
            "-----*-",
            "+++*---",
            "+*-----",
            "-------",
            "-------",
        SA(1, 4, 5, 2), "K",
        SA(5, 2, 1, 4), "L",
            "-------",
            "-------",
            "-*-----",
            "+++*---",
            "+++++*-",
            "-------",
            "-------",
        SA(2, 1, 4, 5), "M",
        SA(4, 5, 2, 1), "N",
            "-------",
            "----*--",
            "++++---",
            "+++*---",
            "+++----",
            "++*----",
            "-------",
        SA(2, 5, 4, 1), "O",
        SA(4, 1, 2, 5), "P",
            "-------",
            "--*----",
            "+++----",
            "+++*---",
            "++++---",
            "++++*--",
            "-------",
        SA(3, 3, 3, 3), "Q",
        SA(3, 3, 3, 3), "R",
            "-------",
            "-------",
            "-------",
            "---*---",
            "-------",
            "-------",
            "-------",
    };
    bool ok = true;
    for (size_t i = 0; i < sizeof(segs)/sizeof(void*); i += 11) {
        void *segs2[] = {
            segs[i], segs[i+1], &segs[i+4],
            segs[i+2], segs[i+3], &segs[i+4],
        };
        for (size_t j = 0; j < sizeof(segs2)/sizeof(void*); j += 3) {
            double *seg = segs2[j];
            char *label = segs2[j+1];
            char **grid = segs2[j+2];
            char *ngrid[7];
            int y = 0;
            int sy = 6;
            for (;y < 7;) {
                char *nline = malloc(8);
                assert(nline);
                for (int x = 0; x < 7; x++) {
                    struct tg_segment lseg = { 
                        {seg[0], seg[1]},
                        {seg[2], seg[3]},
                    };
                    struct tg_point lpt = { x, y };
                    enum tg_raycast_result res = tg_raycast(lseg, lpt);
                    if (res == TG_IN) {
                        nline[x] = '+';
                    } else if (res == TG_ON) {
                        nline[x] = '*';
                    } else {
                        nline[x] = '-';
                    }
                }
                nline[7] = '\0';
                ngrid[sy] = nline;
                y++;
                sy--;
            }
            for (int k = 0; k < 7; k++) {
                if (strcmp(grid[k], ngrid[k]) != 0) {
                    fprintf(stderr, 
                        "MISMATCH (%s) SEGMENT: (%.0f, %.0f, %.0f, %.0f)\n", 
                        label, seg[0], seg[1], seg[2], seg[3]);
                    fprintf(stderr, "EXPECTED\n");
                    for (int k = 0; k < 7; k++) {
                        fprintf(stderr, "%s\n", grid[k]);
                    }
                    fprintf(stderr, "GOT\n");
                    for (int k = 0; k < 7; k++) {
                        fprintf(stderr, "%s\n", ngrid[k]);
                    }
                    ok = false;
                    break;
                }
            }
            for (int k = 0; k < 7; k++) {
                free(ngrid[k]);
            }
        }
    }
    if (!ok) {
        fprintf(stderr, "raycast test failed\n");
        exit(1);
    }
}

static struct tg_segment flip(struct tg_segment seg){
    return (struct tg_segment){ .a = seg.b, .b = seg.a };
}

void test_segment_intersects_segment() {
    #define V0 (void*)0
    #define V1 (void*)1
    void *vals[] = {
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "----A----", V1,
        "----A----", "----A----", V1, "----A----", "----*----", V1,
        "----*----", "----*----", V1, "----*----", "----B----", V1,
        "----B----", "----B----", V1, "----B----", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,

        "---------", "---------", V1, "---------", "----A----", V0,
        "---------", "----A----", V1, "---------", "----*----", V0,
        "---------", "----*----", V1, "---------", "----B----", V0,
        "----A----", "----B----", V1, "----A----", "---------", V0,
        "----*----", "---------", V1, "----*----", "---------", V0,
        "----B----", "---------", V1, "----B----", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,

        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "----A----", "---------", V1, "----A----", "---------", V1,
        "----*----", "----A----", V1, "----*----", "---------", V1,
        "----B----", "----*----", V1, "----B----", "----A----", V1,
        "---------", "----B----", V1, "---------", "----*----", V1,
        "---------", "---------", V1, "---------", "----B----", V1,
        "---------", "---------", V1, "---------", "---------", V1,

        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "----A----", "---------", V1, "----A----", "---------", V0,
        "----*----", "---------", V1, "----*----", "---------", V0,
        "----B----", "----A----", V1, "----B----", "---------", V0,
        "---------", "----*----", V1, "---------", "----A----", V0,
        "---------", "----B----", V1, "---------", "----*----", V0,
        "---------", "---------", V1, "---------", "----B----", V0,

        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "----A----", "-----A---", V0, "----A----", "---A-----", V0,
        "----*----", "-----*---", V0, "----*----", "---*-----", V0,
        "----B----", "-----B---", V0, "----B----", "---B-----", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,

        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---A*B---", "---A*B---", V1, "---A*B---", "----A*B--", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,

        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---A*B---", "-----A*B-", V1, "---A*B---", "------A*B", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,

        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---A*B---", "--A*B----", V1, "---A*B---", "-A*B-----", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,

        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---A*B---", "--A*B----", V1, "---A*B---", "A*B------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,

        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---A*B---", V0, "---------", "---------", V0,
        "---A*B---", "---------", V0, "---A*B---", "---------", V0,
        "---------", "---------", V0, "---------", "---A*B---", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,

        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "------A--", V1,
        "-----A---", "-----A---", V1, "-----A---", "-----*---", V1,
        "----*----", "----*----", V1, "----*----", "----B----", V1,
        "---B-----", "---B-----", V1, "---B-----", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,

        "---------", "---------", V1, "---------", "--------A", V0,
        "---------", "-------A-", V1, "---------", "-------*-", V0,
        "---------", "------*--", V1, "---------", "------B--", V0,
        "-----A---", "-----B---", V1, "-----A---", "---------", V0,
        "----*----", "---------", V1, "----*----", "---------", V0,
        "---B-----", "---------", V1, "---B-----", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,

        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "-----A---", "---------", V1, "-----A---", "---------", V1,
        "----*----", "----A----", V1, "----*----", "---------", V1,
        "---B-----", "---*-----", V1, "---B-----", "---A-----", V1,
        "---------", "--B------", V1, "---------", "--*------", V1,
        "---------", "---------", V1, "---------", "-B-------", V1,
        "---------", "---------", V1, "---------", "---------", V1,

        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "-----A---", "---------", V0, "-----A---", "------A--", V0,
        "----*----", "---------", V0, "----*----", "-----*---", V0,
        "---B-----", "---------", V0, "---B-----", "----B----", V0,
        "---------", "--A------", V0, "---------", "---------", V0,
        "---------", "-*-------", V0, "---------", "---------", V0,
        "---------", "B--------", V0, "---------", "---------", V0,

        "---------", "---------", V0, "---------", "---------", V1,
        "---------", "---------", V0, "---------", "---------", V1,
        "---------", "---------", V0, "---------", "---------", V1,
        "-----A---", "----A----", V0, "---A-----", "---A-----", V1,
        "----*----", "---*-----", V0, "----*----", "----*----", V1,
        "---B-----", "--B------", V0, "-----B---", "-----B---", V1,
        "---------", "---------", V0, "---------", "---------", V1,
        "---------", "---------", V0, "---------", "---------", V1,
        "---------", "---------", V0, "---------", "---------", V1,

        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "-A-------", V1,
        "---------", "--A------", V1, "---------", "--*------", V1,
        "---A-----", "---*-----", V1, "---A-----", "---B-----", V1,
        "----*----", "----B----", V1, "----*----", "---------", V1,
        "-----B---", "---------", V1, "-----B---", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,

        "---------", "A--------", V0, "---------", "---------", V1,
        "---------", "-*-------", V0, "---------", "---------", V1,
        "---------", "--B------", V0, "---------", "---------", V1,
        "---A-----", "---------", V0, "---A-----", "---------", V1,
        "----*----", "---------", V0, "----*----", "----A----", V1,
        "-----B---", "---------", V0, "-----B---", "-----*---", V1,
        "---------", "---------", V0, "---------", "------B--", V1,
        "---------", "---------", V0, "---------", "---------", V1,
        "---------", "---------", V0, "---------", "---------", V1,

        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---A-----", "---------", V1, "---A-----", "---------", V0,
        "----*----", "---------", V1, "----*----", "---------", V0,
        "-----B---", "-----A---", V1, "-----B---", "---------", V0,
        "---------", "------*--", V1, "---------", "------A--", V0,
        "---------", "-------B-", V1, "---------", "-------*-", V0,
        "---------", "---------", V1, "---------", "--------B", V0,

        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---A-----", "----A----", V0, "---A-----", "--A------", V0,
        "----*----", "-----*---", V0, "----*----", "---*-----", V0,
        "-----B---", "------B--", V0, "-----B---", "----B----", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,

        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---A-----", "-----A---", V1, "---A-----", "------A--", V1,
        "----*----", "----*----", V1, "----*----", "-----*---", V1,
        "-----B---", "---B-----", V1, "-----B---", "----B----", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,

        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---A-----", "-------A-", V1, "---A-----", "--------A", V0,
        "----*----", "------*--", V1, "----*----", "-------*-", V0,
        "-----B---", "-----B---", V1, "-----B---", "------B--", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,

        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---A-----", "-----A---", V1, "---A-----", "----A----", V1,
        "----*----", "----*----", V1, "----*----", "---*-----", V1,
        "-----B---", "---B-----", V1, "-----B---", "--B------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,

        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---A-----", "---A-----", V1, "---A-----", "--A------", V0,
        "----*----", "--*------", V1, "----*----", "-*-------", V0,
        "-----B---", "-B-------", V1, "-----B---", "B--------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,
        "---------", "---------", V1, "---------", "---------", V0,

        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "-----A---", V1,
        "---------", "-----A---", V1, "---------", "----*----", V1,
        "---A-----", "----*----", V1, "---A-----", "---B-----", V1,
        "----*----", "---B-----", V1, "----*----", "---------", V1,
        "-----B---", "---------", V1, "-----B---", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,
        "---------", "---------", V1, "---------", "---------", V1,

        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "-------A-", V0, "---------", "---------", V0,
        "---A-----", "------*--", V0, "---A-----", "---------", V0,
        "----*----", "-----B---", V0, "----*----", "---A-----", V0,
        "-----B---", "---------", V0, "-----B---", "--*------", V0,
        "---------", "---------", V0, "---------", "-B-------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
        "---------", "---------", V0, "---------", "---------", V0,
    };

    bool ok = true;
    int ncol = 3;
    size_t i = 0;
    size_t k = 0;
    for (; i < sizeof(vals)/sizeof(void*); k++) {
        char *grids[2][9];
        for (int j = 0; j < 9; j++) {
            grids[0][j] = vals[i+ncol*2*j];
        }
        for (int j = 0; j < 9; j++) {
            grids[1][j] = vals[i+1+ncol*2*j];
        }
        //label := "?" //vals[i+2].(string)
        bool expect = vals[i+2] != 0;

        struct tg_segment segs[2];
        for (int j = 0; j < 2; j++) {
            for (int y = 0; y < 9; y++) {
                for (int x = 0; x < 9; x++) {
                    char ch = grids[j][8-y][x];
                    if (ch == 'A') {
                        segs[j].a.x = x;
                        segs[j].a.y = y;
                    } else if (ch == 'B') {
                        segs[j].b.x = x;
                        segs[j].b.y = y;
                    }
                }
            }
        }
        struct tg_segment tests[][2] = {
            {segs[0], segs[1]},
            {flip(segs[0]), segs[1]},
            {segs[0], flip(segs[1])},
            {flip(segs[0]), flip(segs[1])},
        };
        for (int j = 0; j < 4; j++) {
            if (tg_segment_intersects_segment(tests[j][0], tests[j][1]) != 
                expect) 
            {
                ok = false;
                fprintf(stderr, "MISMATCH SEGMENTS: "
                    "[(%.0f, %.0f, %.0f, %.0f), (%.0f, %.0f, %.0f, %.0f)] "
                    "(TEST %d)\n", 
                    segs[0].a.x, segs[0].a.y, segs[0].b.x, segs[0].b.y,
                    segs[1].a.x, segs[1].a.y, segs[1].b.x, segs[1].b.y,
                    j);
                fprintf(stderr, "EXPECTED: %s, GOT: %s\n", 
                    expect?"true":"false", expect?"false":"true");
                fprintf(stderr, "GRID 1\n");
                for (int i = 0; i < 9; i++) {
                    fprintf(stderr, "%s\n", grids[0][i]);
                }
                fprintf(stderr, "GRID 2\n");
                for (int i = 0; i < 9; i++) {
                    fprintf(stderr, "%s\n", grids[1][i]);
                }
            }
        }
        // move to next block
        if (k%2 == 1) {
            i += ncol*2*9 - ncol;
        } else {
            i += ncol;
        }
    }
    if (!ok) {
        fprintf(stderr, "segment intersects test failed\n");
        exit(1);
    }
}

void test_segment_covers_rect() {
    assert(tg_segment_covers_rect(S(10,10,20,20), R(15,15,15,15)));
    assert(!tg_segment_covers_rect(S(10,10,20,20), R(15,16,15,16)));
    assert(tg_segment_covers_rect(S(10,15,20,15), R(15,15,16,15)));
}

int main(int argc, char **argv) {
    do_test(test_segment_raycast);
    do_test(test_segment_intersects_segment);
    do_test(test_segment_covers_rect);
    return 0;
}