diff options
author | pacien | 2017-12-24 15:35:54 +0100 |
---|---|---|
committer | pacien | 2017-12-24 15:35:54 +0100 |
commit | 2a9ca610acdd24ebf1a215f779bf2a5d9f80d9cf (patch) | |
tree | 458531b4f450307cc222856cf30155fa00d8d011 | |
parent | cdbae7a5e7515ba50ae21f15929a086fc40fcae3 (diff) | |
download | morpher-2a9ca610acdd24ebf1a215f779bf2a5d9f80d9cf.tar.gz |
Move Delaunay propagation function
Signed-off-by: pacien <pacien.trangirard@pacien.net>
-rw-r--r-- | include/morpher/quadrilateral.h | 11 | ||||
-rw-r--r-- | include/morpher/trianglemap.h | 10 | ||||
-rw-r--r-- | src/morpher/quadrilateral.c | 8 | ||||
-rw-r--r-- | src/morpher/trianglemap.c | 13 | ||||
-rw-r--r-- | test/morpher/quadrilateral.c | 25 | ||||
-rw-r--r-- | test/morpher/trianglemap.c | 28 |
6 files changed, 49 insertions, 46 deletions
diff --git a/include/morpher/quadrilateral.h b/include/morpher/quadrilateral.h index 8691263..c8cf3a1 100644 --- a/include/morpher/quadrilateral.h +++ b/include/morpher/quadrilateral.h | |||
@@ -36,15 +36,4 @@ void quadrilateral_flip_diagonal(TriangleMap *t1, TriangleMap *t2); | |||
36 | */ | 36 | */ |
37 | bool quadrilateral_is_delaunay(TriangleMap *t1, TriangleMap *t2); | 37 | bool quadrilateral_is_delaunay(TriangleMap *t1, TriangleMap *t2); |
38 | 38 | ||
39 | /** | ||
40 | * Function: quadrilateral_propagate_delaunay | ||
41 | * Ensures that the quadrilateral spawned by the given triangles fulfills the Delaunay criterion, | ||
42 | * flipping the diagonal if necessary and propagating the changes to the neighbouring triangles. | ||
43 | * | ||
44 | * Parameters: | ||
45 | * *start - the starting triangle | ||
46 | * *neighbor - a neighboring triangle | ||
47 | */ | ||
48 | void quadrilateral_propagate_delaunay(TriangleMap *start, TriangleMap *neighbor); | ||
49 | |||
50 | #endif | 39 | #endif |
diff --git a/include/morpher/trianglemap.h b/include/morpher/trianglemap.h index 0bb6a1d..f690a37 100644 --- a/include/morpher/trianglemap.h +++ b/include/morpher/trianglemap.h | |||
@@ -116,6 +116,16 @@ void trianglemap_replace_neighbor(TriangleMap *t, TriangleMap *old, TriangleMap | |||
116 | void trianglemap_foreach_neighbor(TriangleMap *t, void (*f)(TriangleMap *current, TriangleMap *neighbor)); | 116 | void trianglemap_foreach_neighbor(TriangleMap *t, void (*f)(TriangleMap *current, TriangleMap *neighbor)); |
117 | 117 | ||
118 | /** | 118 | /** |
119 | * Function: trianglemap_propagate_delaunay | ||
120 | * Ensures that the quadrilateral spawned by the given triangles and its neighbours fulfill the Delaunay criterion, | ||
121 | * flipping the diagonal if necessary and propagating the changes to the neighbouring triangles. | ||
122 | * | ||
123 | * Parameters: | ||
124 | * *t - the starting triangle | ||
125 | */ | ||
126 | void trianglemap_propagate_delaunay(TriangleMap *t); | ||
127 | |||
128 | /** | ||
119 | * Function: trianglemap_split | 129 | * Function: trianglemap_split |
120 | * Splits a triangle into three sub-triangles at the supplied center vertex, updating the surrounding triangles. | 130 | * Splits a triangle into three sub-triangles at the supplied center vertex, updating the surrounding triangles. |
121 | * The first triangle resulting from the split is returned, with the two others chained as linear neighbours. | 131 | * The first triangle resulting from the split is returned, with the two others chained as linear neighbours. |
diff --git a/src/morpher/quadrilateral.c b/src/morpher/quadrilateral.c index af77f0f..9c73dfa 100644 --- a/src/morpher/quadrilateral.c +++ b/src/morpher/quadrilateral.c | |||
@@ -61,11 +61,3 @@ bool quadrilateral_is_delaunay(TriangleMap *t1, TriangleMap *t2) { | |||
61 | return not_in_circumcircle(t1, t2->vertices[(trianglemap_find_common_edge(t2, t1) + 2) % 3].origin) && | 61 | return not_in_circumcircle(t1, t2->vertices[(trianglemap_find_common_edge(t2, t1) + 2) % 3].origin) && |
62 | not_in_circumcircle(t2, t1->vertices[(trianglemap_find_common_edge(t1, t2) + 2) % 3].origin); | 62 | not_in_circumcircle(t2, t1->vertices[(trianglemap_find_common_edge(t1, t2) + 2) % 3].origin); |
63 | } | 63 | } |
64 | |||
65 | void quadrilateral_propagate_delaunay(TriangleMap *start, TriangleMap *neighbor) { | ||
66 | assert(start != NULL && neighbor != NULL); | ||
67 | if (!quadrilateral_is_delaunay(start, neighbor)) { | ||
68 | quadrilateral_flip_diagonal(start, neighbor); | ||
69 | trianglemap_foreach_neighbor(neighbor, quadrilateral_propagate_delaunay); | ||
70 | } | ||
71 | } | ||
diff --git a/src/morpher/trianglemap.c b/src/morpher/trianglemap.c index 01b66c9..6658901 100644 --- a/src/morpher/trianglemap.c +++ b/src/morpher/trianglemap.c | |||
@@ -1,8 +1,17 @@ | |||
1 | #include "morpher/trianglemap.h" | 1 | #include "morpher/trianglemap.h" |
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <assert.h> | 3 | #include <assert.h> |
4 | #include "morpher/quadrilateral.h" | ||
4 | #include "common/mem.h" | 5 | #include "common/mem.h" |
5 | 6 | ||
7 | static void propagate_delaunay(TriangleMap *start, TriangleMap *neighbor) { | ||
8 | assert(start != NULL && neighbor != NULL); | ||
9 | if (!quadrilateral_is_delaunay(start, neighbor)) { | ||
10 | quadrilateral_flip_diagonal(start, neighbor); | ||
11 | trianglemap_foreach_neighbor(neighbor, propagate_delaunay); | ||
12 | } | ||
13 | } | ||
14 | |||
6 | TriangleMap *trianglemap_create(CartesianMapping v1, CartesianMapping v2, CartesianMapping v3) { | 15 | TriangleMap *trianglemap_create(CartesianMapping v1, CartesianMapping v2, CartesianMapping v3) { |
7 | TriangleMap *triangle = malloc_or_die(sizeof(TriangleMap)); | 16 | TriangleMap *triangle = malloc_or_die(sizeof(TriangleMap)); |
8 | triangle->vertices[0] = v1; | 17 | triangle->vertices[0] = v1; |
@@ -51,6 +60,10 @@ void trianglemap_foreach_neighbor(TriangleMap *t, void (*f)(TriangleMap *, Trian | |||
51 | for (cursor = 0; cursor < 3; ++cursor) if (t->neighbors[cursor] != NULL) f(t, t->neighbors[cursor]); | 60 | for (cursor = 0; cursor < 3; ++cursor) if (t->neighbors[cursor] != NULL) f(t, t->neighbors[cursor]); |
52 | } | 61 | } |
53 | 62 | ||
63 | void trianglemap_propagate_delaunay(TriangleMap *t) { | ||
64 | trianglemap_foreach_neighbor(t, propagate_delaunay); | ||
65 | } | ||
66 | |||
54 | TriangleMap *trianglemap_split(TriangleMap *t, CartesianMapping v) { | 67 | TriangleMap *trianglemap_split(TriangleMap *t, CartesianMapping v) { |
55 | assert(trianglemap_to(t, v.origin) == t); | 68 | assert(trianglemap_to(t, v.origin) == t); |
56 | 69 | ||
diff --git a/test/morpher/quadrilateral.c b/test/morpher/quadrilateral.c index b278e2f..31b22d6 100644 --- a/test/morpher/quadrilateral.c +++ b/test/morpher/quadrilateral.c | |||
@@ -53,34 +53,9 @@ static void test_quadrilateral_is_delaunay(CartesianMapping A, CartesianMapping | |||
53 | trianglemap_destroy(r); | 53 | trianglemap_destroy(r); |
54 | } | 54 | } |
55 | 55 | ||
56 | static void test_quadrilateral_propagate_delaunay() { | ||
57 | CartesianMapping A = m(0, 0), B = m(0, 10), C = m(10, 10), D = m(10, 0), E = m(4, 6), F = m(8, 7); | ||
58 | TriangleMap *l = trianglemap_create(A, B, C); | ||
59 | TriangleMap *r = trianglemap_create(A, C, D); | ||
60 | trianglemap_set_neighbors(l, NULL, NULL, r, r); | ||
61 | trianglemap_set_neighbors(r, l, NULL, NULL, NULL); | ||
62 | trianglemap_split(l, E); | ||
63 | trianglemap_split(r, F); | ||
64 | |||
65 | trianglemap_foreach_neighbor(r, quadrilateral_propagate_delaunay); | ||
66 | |||
67 | { | ||
68 | TriangleMap *triangle; | ||
69 | int neighbor_index; | ||
70 | for (triangle = l; triangle != NULL; triangle = triangle->next) | ||
71 | for (neighbor_index = 0; neighbor_index < 3; ++neighbor_index) | ||
72 | if (triangle->neighbors[neighbor_index] != NULL) | ||
73 | assert(quadrilateral_is_delaunay(triangle, triangle->neighbors[neighbor_index])); | ||
74 | } | ||
75 | |||
76 | trianglemap_destroy(l); | ||
77 | trianglemap_destroy(r); | ||
78 | } | ||
79 | |||
80 | int main(int argc, char **argv) { | 56 | int main(int argc, char **argv) { |
81 | test_quadrilateral_flip_diagonal(); | 57 | test_quadrilateral_flip_diagonal(); |
82 | test_quadrilateral_is_delaunay(m(0, 0), m(0, 3), m(3, 3), m(2, 1), false); | 58 | test_quadrilateral_is_delaunay(m(0, 0), m(0, 3), m(3, 3), m(2, 1), false); |
83 | test_quadrilateral_is_delaunay(m(0, 0), m(0, 3), m(3, 3), m(4, -1), true); | 59 | test_quadrilateral_is_delaunay(m(0, 0), m(0, 3), m(3, 3), m(4, -1), true); |
84 | test_quadrilateral_propagate_delaunay(); | ||
85 | return 0; | 60 | return 0; |
86 | } | 61 | } |
diff --git a/test/morpher/trianglemap.c b/test/morpher/trianglemap.c index 608f3c9..a00f89b 100644 --- a/test/morpher/trianglemap.c +++ b/test/morpher/trianglemap.c | |||
@@ -1,8 +1,7 @@ | |||
1 | #include "morpher/trianglemap.h" | 1 | #include "morpher/trianglemap.h" |
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <assert.h> | 3 | #include <assert.h> |
4 | #include <stdio.h> | 4 | #include "morpher/quadrilateral.h" |
5 | #include "common/geom.h" | ||
6 | 5 | ||
7 | static inline bool neighbors_equals(TriangleMap *neighbors[], | 6 | static inline bool neighbors_equals(TriangleMap *neighbors[], |
8 | TriangleMap *n1, TriangleMap *n2, TriangleMap *n3) { | 7 | TriangleMap *n1, TriangleMap *n2, TriangleMap *n3) { |
@@ -64,8 +63,33 @@ static void test_triangle_split() { | |||
64 | free_map(t); | 63 | free_map(t); |
65 | } | 64 | } |
66 | 65 | ||
66 | static void test_trianglemap_propagate_delaunay() { | ||
67 | CartesianMapping A = m(0, 0), B = m(0, 10), C = m(10, 10), D = m(10, 0), E = m(4, 6), F = m(8, 7); | ||
68 | TriangleMap *l = trianglemap_create(A, B, C); | ||
69 | TriangleMap *r = trianglemap_create(A, C, D); | ||
70 | trianglemap_set_neighbors(l, NULL, NULL, r, r); | ||
71 | trianglemap_set_neighbors(r, l, NULL, NULL, NULL); | ||
72 | trianglemap_split(l, E); | ||
73 | trianglemap_split(r, F); | ||
74 | |||
75 | trianglemap_propagate_delaunay(r); | ||
76 | |||
77 | { | ||
78 | TriangleMap *triangle; | ||
79 | int neighbor_index; | ||
80 | for (triangle = l; triangle != NULL; triangle = triangle->next) | ||
81 | for (neighbor_index = 0; neighbor_index < 3; ++neighbor_index) | ||
82 | if (triangle->neighbors[neighbor_index] != NULL) | ||
83 | assert(quadrilateral_is_delaunay(triangle, triangle->neighbors[neighbor_index])); | ||
84 | } | ||
85 | |||
86 | trianglemap_destroy(l); | ||
87 | trianglemap_destroy(r); | ||
88 | } | ||
89 | |||
67 | int main(int argc, char **argv) { | 90 | int main(int argc, char **argv) { |
68 | test_triangle_to(); | 91 | test_triangle_to(); |
69 | test_triangle_split(); | 92 | test_triangle_split(); |
93 | test_trianglemap_propagate_delaunay(); | ||
70 | return 0; | 94 | return 0; |
71 | } | 95 | } |