diff options
author | pacien | 2017-12-22 01:57:03 +0100 |
---|---|---|
committer | pacien | 2017-12-22 01:57:25 +0100 |
commit | 553dc4a5b272a1828940e72a07b1c9a7210be464 (patch) | |
tree | 0dfaf1b2e3229e064258e4dc5c117a1250f40f87 /src | |
parent | a767c658cb603de9ec9f0577627b9b32cbf82b2b (diff) | |
download | morpher-553dc4a5b272a1828940e72a07b1c9a7210be464.tar.gz |
Add triangle map and quadrilateral representation and common operations
Signed-off-by: pacien <pacien.trangirard@pacien.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/morpher/quadrilateral.c | 58 | ||||
-rw-r--r-- | src/morpher/trianglemap.c | 64 |
2 files changed, 122 insertions, 0 deletions
diff --git a/src/morpher/quadrilateral.c b/src/morpher/quadrilateral.c new file mode 100644 index 0000000..b9e740b --- /dev/null +++ b/src/morpher/quadrilateral.c | |||
@@ -0,0 +1,58 @@ | |||
1 | #include "morpher/quadrilateral.h" | ||
2 | #include "common/geom.h" | ||
3 | #include "morpher/matrix.h" | ||
4 | |||
5 | static inline IntVector p2(IntVector n) { | ||
6 | return n * n; | ||
7 | } | ||
8 | |||
9 | static inline bool in_circumcircle(TriangleMap *t, CartesianVector v) { | ||
10 | CartesianVector a = t->vertices[0].origin, b = t->vertices[1].origin, c = t->vertices[2].origin; | ||
11 | IntVector v2 = p2(v.x) + p2(v.y); | ||
12 | return matrix_int_det3(a.x - v.x, a.y - v.y, p2(a.x) + p2(a.y) - v2, | ||
13 | b.x - v.x, b.y - v.y, p2(b.x) + p2(b.y) - v2, | ||
14 | c.x - v.x, c.y - v.y, p2(c.x) + p2(c.y) - v2) > 0; | ||
15 | } | ||
16 | |||
17 | static inline void rotate_vertices(TriangleMap *t1, TriangleMap *t2, int e1, int e2) { | ||
18 | CartesianMapping quad[] = { | ||
19 | t1->vertices[(e1 + 1) % 3], | ||
20 | t1->vertices[(e1 + 2) % 3], | ||
21 | t2->vertices[(e2 + 1) % 3], | ||
22 | t2->vertices[(e2 + 2) % 3] | ||
23 | }; | ||
24 | |||
25 | t1->vertices[(e1 + 1) % 3] = quad[1]; | ||
26 | t1->vertices[(e1 + 2) % 3] = quad[2]; | ||
27 | t1->vertices[(e1 + 3) % 3] = quad[3]; | ||
28 | t2->vertices[(e2 + 1) % 3] = quad[3]; | ||
29 | t2->vertices[(e2 + 2) % 3] = quad[0]; | ||
30 | t2->vertices[(e2 + 3) % 3] = quad[1]; | ||
31 | } | ||
32 | |||
33 | static inline void rotate_neighbors(TriangleMap *t1, TriangleMap *t2, int e1, int e2) { | ||
34 | TriangleMap *neighbors[] = { | ||
35 | t1->neighbors[(e1 + 1) % 3], | ||
36 | t1->neighbors[(e1 + 2) % 3], | ||
37 | t2->neighbors[(e2 + 1) % 3], | ||
38 | t2->neighbors[(e2 + 2) % 3] | ||
39 | }; | ||
40 | |||
41 | t1->neighbors[(e1 + 1) % 3] = neighbors[1]; | ||
42 | t1->neighbors[(e1 + 2) % 3] = neighbors[2]; | ||
43 | t2->neighbors[(e2 + 1) % 3] = neighbors[3]; | ||
44 | t2->neighbors[(e2 + 2) % 3] = neighbors[0]; | ||
45 | trianglemap_replace_neighbor(t1->neighbors[(e1 + 2) % 3], t2, t1); | ||
46 | trianglemap_replace_neighbor(t2->neighbors[(e2 + 2) % 3], t1, t2); | ||
47 | } | ||
48 | |||
49 | void quadrilateral_flip_diagonal(TriangleMap *t1, TriangleMap *t2) { | ||
50 | int e1 = trianglemap_find_common_edge(t1, t2), e2 = trianglemap_find_common_edge(t2, t1); | ||
51 | rotate_vertices(t1, t2, e1, e2); | ||
52 | rotate_neighbors(t1, t2, e1, e2); | ||
53 | } | ||
54 | |||
55 | bool quadrilateral_is_delaunay(TriangleMap *t1, TriangleMap *t2) { | ||
56 | return in_circumcircle(t1, t2->vertices[(trianglemap_find_common_edge(t2, t1) + 2) % 3].origin) && | ||
57 | in_circumcircle(t2, t1->vertices[(trianglemap_find_common_edge(t1, t2) + 2) % 3].origin); | ||
58 | } | ||
diff --git a/src/morpher/trianglemap.c b/src/morpher/trianglemap.c new file mode 100644 index 0000000..45f4ade --- /dev/null +++ b/src/morpher/trianglemap.c | |||
@@ -0,0 +1,64 @@ | |||
1 | #include "morpher/trianglemap.h" | ||
2 | #include <stdlib.h> | ||
3 | #include <assert.h> | ||
4 | #include "common/geom.h" | ||
5 | #include "common/mem.h" | ||
6 | |||
7 | TriangleMap *trianglemap_create(CartesianMapping v1, CartesianMapping v2, CartesianMapping v3) { | ||
8 | TriangleMap *triangle = malloc_or_die(sizeof(TriangleMap)); | ||
9 | triangle->vertices[0] = v1; | ||
10 | triangle->vertices[1] = v2; | ||
11 | triangle->vertices[2] = v3; | ||
12 | return triangle; | ||
13 | } | ||
14 | |||
15 | TriangleMap *trianglemap_destroy(TriangleMap *t) { | ||
16 | TriangleMap *next = t->next; | ||
17 | free(t); | ||
18 | return next; | ||
19 | } | ||
20 | |||
21 | TriangleMap *trianglemap_to(TriangleMap *t, CartesianVector v) { | ||
22 | int edge; | ||
23 | |||
24 | for (edge = 0; edge < 3; ++edge) | ||
25 | if (triangle_area(t->vertices[edge].origin, t->vertices[(edge + 1) % 3].origin, v) >= 0) | ||
26 | return t->neighbors[edge]; | ||
27 | |||
28 | return t; | ||
29 | } | ||
30 | |||
31 | int trianglemap_find_common_edge(TriangleMap *t, TriangleMap *neighbor) { | ||
32 | int edge; | ||
33 | for (edge = 0; t->neighbors[edge] != neighbor && edge < 3; ++edge); | ||
34 | assert(t->neighbors[edge] == neighbor && neighbor != NULL); | ||
35 | return edge; | ||
36 | } | ||
37 | |||
38 | void trianglemap_set_neighbors(TriangleMap *t, TriangleMap *n1, TriangleMap *n2, TriangleMap *n3, TriangleMap *next) { | ||
39 | t->neighbors[0] = n1; | ||
40 | t->neighbors[1] = n2; | ||
41 | t->neighbors[2] = n3; | ||
42 | t->next = next; | ||
43 | } | ||
44 | |||
45 | void trianglemap_replace_neighbor(TriangleMap *t, TriangleMap *old, TriangleMap *new) { | ||
46 | if (t != NULL) t->neighbors[trianglemap_find_common_edge(t, old)] = new; | ||
47 | } | ||
48 | |||
49 | TriangleMap *trianglemap_split(TriangleMap *t, CartesianMapping v) { | ||
50 | assert(trianglemap_to(t, v.origin) == t); | ||
51 | |||
52 | TriangleMap *triangle2 = trianglemap_create(t->vertices[1], t->vertices[2], v); | ||
53 | TriangleMap *triangle3 = trianglemap_create(t->vertices[2], t->vertices[0], v); | ||
54 | t->vertices[2] = v; | ||
55 | |||
56 | trianglemap_replace_neighbor(t->neighbors[1], t, triangle2); | ||
57 | trianglemap_replace_neighbor(t->neighbors[2], t, triangle3); | ||
58 | |||
59 | trianglemap_set_neighbors(triangle3, t->neighbors[2], t, triangle2, t->next); | ||
60 | trianglemap_set_neighbors(triangle2, t->neighbors[1], triangle3, t, triangle3); | ||
61 | trianglemap_set_neighbors(t, t->neighbors[0], triangle2, triangle3, triangle2); | ||
62 | |||
63 | return t; | ||
64 | } | ||