summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/common/geom.h93
-rw-r--r--include/common/time.h4
-rw-r--r--src/common/geom.c27
-rw-r--r--src/morpher/trianglemap.c2
-rw-r--r--test/common/geom.c21
5 files changed, 137 insertions, 10 deletions
diff --git a/include/common/geom.h b/include/common/geom.h
index b3564a5..334e95c 100644
--- a/include/common/geom.h
+++ b/include/common/geom.h
@@ -15,6 +15,12 @@
15typedef int32_t IntVector; 15typedef int32_t IntVector;
16 16
17/** 17/**
18 * Type: RealVector
19 * An abstract 1-D real vector.
20 */
21typedef double RealVector;
22
23/**
18 * Struct: CartesianVector 24 * Struct: CartesianVector
19 * An abstract 2-D vector in cartesian coordinates. 25 * An abstract 2-D vector in cartesian coordinates.
20 * 26 *
@@ -27,6 +33,19 @@ typedef struct {
27} CartesianVector; 33} CartesianVector;
28 34
29/** 35/**
36 * Struct: BarycentricVector
37 * An abstract barycentric coordinate tuple relative to a triangle.
38 * The third barycentric coordinate is deduced from the first two ones.
39 *
40 * Fields:
41 * a - the first barycentric coordinate
42 * b - the second barycentric coordinate
43 */
44typedef struct {
45 RealVector a, b;
46} BarycentricVector;
47
48/**
30 * Struct: CartesianMapping 49 * Struct: CartesianMapping
31 * A tuple of cartesian vectors representing a mapping. 50 * A tuple of cartesian vectors representing a mapping.
32 * 51 *
@@ -38,6 +57,16 @@ typedef struct {
38 CartesianVector origin, target; 57 CartesianVector origin, target;
39} CartesianMapping; 58} CartesianMapping;
40 59
60/**
61 * Struct: Triangle
62 * Represents a simple triangle with three vertices.
63 *
64 * Fields:
65 * v[] - array of vertices
66 */
67typedef struct {
68 CartesianVector v[3];
69} Triangle;
41 70
42/** 71/**
43 * Function: m 72 * Function: m
@@ -66,6 +95,19 @@ CartesianMapping m(int x, int y);
66CartesianVector v(int x, int y); 95CartesianVector v(int x, int y);
67 96
68/** 97/**
98 * Function: b
99 * Shorthand for a barycentric vector.
100 *
101 * Parameters:
102 * a - the a-coordinate
103 * b - the b-coordinate
104 *
105 * Returns:
106 * A barycentric vector
107 */
108BarycentricVector b(double a, double b);
109
110/**
69 * Function: mappings_equals 111 * Function: mappings_equals
70 * Compares two cartesian mappings. 112 * Compares two cartesian mappings.
71 * 113 *
@@ -92,17 +134,54 @@ bool mappings_equals(CartesianMapping m1, CartesianMapping m2);
92bool vector_equals(CartesianVector v1, CartesianVector v2); 134bool vector_equals(CartesianVector v1, CartesianVector v2);
93 135
94/** 136/**
95 * Function: triangle_area 137 * Function: barycentric_vector_equals
96 * Computes the area of a triangle. 138 * Compares two barycentric vectors.
139 *
140 * Parameters:
141 * v1 - the first vector
142 * v2 - the second vector
143 *
144 * Returns:
145 * T(v1 is equal to v2)
146 */
147bool barycentric_vector_equals(BarycentricVector b1, BarycentricVector b2);
148
149/**
150 * Function: square_area
151 * Computes the area of a square spawned by three positively oriented vertices.
152 *
153 * Parameters:
154 * vi - vertices
155 *
156 * Returns:
157 * The area of the square
158 */
159IntVector square_area(CartesianVector v1, CartesianVector v2, CartesianVector v3);
160
161/**
162 * Function: cartesian_to_barycentric
163 * Computes and returns the barycentric coordinates of a given point in the given reference triangle.
164 *
165 * Parameters:
166 * t - reference triangle
167 * p - the vector to convert
168 *
169 * Returns:
170 * The barycentric coordinates vector
171 */
172BarycentricVector cartesian_to_barycentric(Triangle t, CartesianVector p);
173
174/**
175 * Function: barycentric_to_cartesian
176 * Computes and returns the cartesian coordinates of a given point in the given reference triangle.
97 * 177 *
98 * Parameters: 178 * Parameters:
99 * v1 - first vertex 179 * t - reference triangle
100 * v2 - second vertex 180 * p - the vector to convert
101 * v3 - third vertex
102 * 181 *
103 * Returns: 182 * Returns:
104 * The area of the triangle spawned by the three supplied vertices 183 * The cartesian coordinate vector
105 */ 184 */
106IntVector triangle_area(CartesianVector v1, CartesianVector v2, CartesianVector v3); 185CartesianVector barycentric_to_cartesian(Triangle t, BarycentricVector p);
107 186
108#endif 187#endif
diff --git a/include/common/time.h b/include/common/time.h
index 54a7bb2..e207ad7 100644
--- a/include/common/time.h
+++ b/include/common/time.h
@@ -5,6 +5,8 @@
5 * File: time.h 5 * File: time.h
6 */ 6 */
7 7
8#include "geom.h"
9
8/** 10/**
9 * Constants: Time vectors 11 * Constants: Time vectors
10 * 12 *
@@ -18,6 +20,6 @@
18 * Type: TimeVector 20 * Type: TimeVector
19 * An abstract time vector. 21 * An abstract time vector.
20 */ 22 */
21typedef float TimeVector; 23typedef RealVector TimeVector;
22 24
23#endif 25#endif
diff --git a/src/common/geom.c b/src/common/geom.c
index 219270f..eb35727 100644
--- a/src/common/geom.c
+++ b/src/common/geom.c
@@ -1,6 +1,12 @@
1#include "common/geom.h" 1#include "common/geom.h"
2#include <math.h>
3#include <common/geom.h>
2#include "morpher/matrix.h" 4#include "morpher/matrix.h"
3 5
6static inline IntVector int_round(RealVector x) {
7 return (IntVector) round(x);
8}
9
4CartesianMapping m(int x, int y) { 10CartesianMapping m(int x, int y) {
5 return (CartesianMapping) {{x, y}, 11 return (CartesianMapping) {{x, y},
6 {x, y}}; 12 {x, y}};
@@ -10,6 +16,10 @@ CartesianVector v(int x, int y) {
10 return (CartesianVector) {x, y}; 16 return (CartesianVector) {x, y};
11} 17}
12 18
19BarycentricVector b(double a, double b) {
20 return (BarycentricVector) {a, b};
21}
22
13bool mappings_equals(CartesianMapping m1, CartesianMapping m2) { 23bool mappings_equals(CartesianMapping m1, CartesianMapping m2) {
14 return vector_equals(m1.origin, m2.origin) && vector_equals(m1.target, m2.target); 24 return vector_equals(m1.origin, m2.origin) && vector_equals(m1.target, m2.target);
15} 25}
@@ -18,7 +28,22 @@ bool vector_equals(CartesianVector v1, CartesianVector v2) {
18 return v1.x == v2.x && v1.y == v2.y; 28 return v1.x == v2.x && v1.y == v2.y;
19} 29}
20 30
21IntVector triangle_area(CartesianVector v1, CartesianVector v2, CartesianVector v3) { 31bool barycentric_vector_equals(BarycentricVector b1, BarycentricVector b2) {
32 return b1.a == b2.a && b1.b == b2.b;
33}
34
35IntVector square_area(CartesianVector v1, CartesianVector v2, CartesianVector v3) {
22 return matrix_int_det2(v1.x - v3.x, v2.x - v3.x, 36 return matrix_int_det2(v1.x - v3.x, v2.x - v3.x,
23 v1.y - v3.y, v2.y - v3.y); 37 v1.y - v3.y, v2.y - v3.y);
24} 38}
39
40BarycentricVector cartesian_to_barycentric(Triangle t, CartesianVector p) {
41 RealVector total_area = square_area(t.v[0], t.v[1], t.v[2]);
42 return (BarycentricVector) {square_area(t.v[1], t.v[2], p) / total_area,
43 square_area(t.v[2], t.v[0], p) / total_area};
44}
45
46CartesianVector barycentric_to_cartesian(Triangle t, BarycentricVector p) {
47 return (CartesianVector) {int_round(p.a * (t.v[0].x - t.v[2].x) + p.b * (t.v[1].x - t.v[2].x) + t.v[2].x),
48 int_round(p.a * (t.v[0].y - t.v[2].y) + p.b * (t.v[1].y - t.v[2].y) + t.v[2].y)};
49}
diff --git a/src/morpher/trianglemap.c b/src/morpher/trianglemap.c
index e2f3eb9..ad526bc 100644
--- a/src/morpher/trianglemap.c
+++ b/src/morpher/trianglemap.c
@@ -30,7 +30,7 @@ TriangleMap *trianglemap_to(TriangleMap *t, CartesianVector v) {
30 int edge; 30 int edge;
31 31
32 for (edge = 0; edge < 3; ++edge) 32 for (edge = 0; edge < 3; ++edge)
33 if (triangle_area(t->vertices[edge].origin, t->vertices[(edge + 1) % 3].origin, v) > 0) 33 if (square_area(t->vertices[edge].origin, t->vertices[(edge + 1) % 3].origin, v) > 0)
34 return t->neighbors[edge]; 34 return t->neighbors[edge];
35 35
36 return t; 36 return t;
diff --git a/test/common/geom.c b/test/common/geom.c
new file mode 100644
index 0000000..f05e0a1
--- /dev/null
+++ b/test/common/geom.c
@@ -0,0 +1,21 @@
1#include "common/geom.h"
2#include <assert.h>
3
4static void test_square_area() {
5 assert(square_area(v(0, 0), v(10, 0), v(10, 10)) == 100);
6 assert(square_area(v(0, 0), v(0, 10), v(10, 10)) == -100);
7}
8
9static void test_cartesian_barycentric_vectors() {
10 Triangle t = {{v(0, 0), v(10, 0), v(10, 10)}};
11 CartesianVector c = v(3, 2);