summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpacien2017-12-22 01:57:03 +0100
committerpacien2017-12-22 01:57:25 +0100
commit553dc4a5b272a1828940e72a07b1c9a7210be464 (patch)
tree0dfaf1b2e3229e064258e4dc5c117a1250f40f87 /src
parenta767c658cb603de9ec9f0577627b9b32cbf82b2b (diff)
downloadmorpher-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.c58
-rw-r--r--src/morpher/trianglemap.c64
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
5static inline IntVector p2(IntVector n) {
6 return n * n;
7}
8
9static 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
17static 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
33static 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
49void 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
55bool 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
7TriangleMap *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
15TriangleMap *trianglemap_destroy(TriangleMap *t) {
16 TriangleMap *next = t->next;
17 free(t);
18 return next;
19}
20
21TriangleMap *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
31int 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
38void 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
45void trianglemap_replace_neighbor(TriangleMap *t, TriangleMap *old, TriangleMap *new) {
46 if (t != NULL) t->neighbors[trianglemap_find_common_edge(t, old)] = new;
47}
48
49TriangleMap *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}