summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpacien2017-12-24 15:35:54 +0100
committerpacien2017-12-24 15:35:54 +0100
commit2a9ca610acdd24ebf1a215f779bf2a5d9f80d9cf (patch)
tree458531b4f450307cc222856cf30155fa00d8d011
parentcdbae7a5e7515ba50ae21f15929a086fc40fcae3 (diff)
downloadmorpher-2a9ca610acdd24ebf1a215f779bf2a5d9f80d9cf.tar.gz
Move Delaunay propagation function
Signed-off-by: pacien <pacien.trangirard@pacien.net>
-rw-r--r--include/morpher/quadrilateral.h11
-rw-r--r--include/morpher/trianglemap.h10
-rw-r--r--src/morpher/quadrilateral.c8
-rw-r--r--src/morpher/trianglemap.c13
-rw-r--r--test/morpher/quadrilateral.c25
-rw-r--r--test/morpher/trianglemap.c28
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 */
37bool quadrilateral_is_delaunay(TriangleMap *t1, TriangleMap *t2); 37bool 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 */
48void 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
116void trianglemap_foreach_neighbor(TriangleMap *t, void (*f)(TriangleMap *current, TriangleMap *neighbor)); 116void 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 */
126void 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
65void 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
7static 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
6TriangleMap *trianglemap_create(CartesianMapping v1, CartesianMapping v2, CartesianMapping v3) { 15TriangleMap *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
63void trianglemap_propagate_delaunay(TriangleMap *t) {
64 trianglemap_foreach_neighbor(t, propagate_delaunay);
65}
66
54TriangleMap *trianglemap_split(TriangleMap *t, CartesianMapping v) { 67TriangleMap *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
56static 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
80int main(int argc, char **argv) { 56int 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
7static inline bool neighbors_equals(TriangleMap *neighbors[], 6static 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
66static 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
67int main(int argc, char **argv) { 90int 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}