From 0fec83ebc89bd6b86f772d942b7c39b13f773d3a Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 12 Jun 2014 13:45:06 -0400 Subject: Add a C89 compliance test for the headers. Technically we still require a couple things from C99 like "bool", but it works with -std=c89 under gcc. --- libdimension/dimension/geometry.h | 194 +++++++++++++++++++++----------------- 1 file changed, 108 insertions(+), 86 deletions(-) (limited to 'libdimension/dimension/geometry.h') diff --git a/libdimension/dimension/geometry.h b/libdimension/dimension/geometry.h index fd4a781..7b52a98 100644 --- a/libdimension/dimension/geometry.h +++ b/libdimension/dimension/geometry.h @@ -26,105 +26,115 @@ #include #include -/// A vector in 3 dimensions. +/** A vector in 3 dimensions. */ typedef struct dmnsn_vector { - double x; ///< The x component. - double y; ///< The y component. - double z; ///< The z component. + double x; /**< The x component. */ + double y; /**< The y component. */ + double z; /**< The z component. */ } dmnsn_vector; -/// A standard format string for vectors. +/** A standard format string for vectors. */ #define DMNSN_VECTOR_FORMAT "<%g, %g, %g>" -/// The appropriate arguements to printf() a vector. +/** The appropriate arguements to printf() a vector. */ #define DMNSN_VECTOR_PRINTF(v) (v).x, (v).y, (v).z -/// A 4x4 affine transformation matrix, with implied [0 0 0 1] bottom row. +/** A 4x4 affine transformation matrix, with implied [0 0 0 1] bottom row. */ typedef struct dmnsn_matrix { - double n[3][4]; ///< The matrix elements in row-major order. + double n[3][4]; /**< The matrix elements in row-major order. */ } dmnsn_matrix; -/// A standard format string for matricies. +/** A standard format string for matricies. */ #define DMNSN_MATRIX_FORMAT \ "[%g\t%g\t%g\t%g]\n" \ "[%g\t%g\t%g\t%g]\n" \ "[%g\t%g\t%g\t%g]\n" \ "[%g\t%g\t%g\t%g]" -/// The appropriate arguements to printf() a matrix. +/** The appropriate arguements to printf() a matrix. */ #define DMNSN_MATRIX_PRINTF(m) \ (m).n[0][0], (m).n[0][1], (m).n[0][2], (m).n[0][3], \ (m).n[1][0], (m).n[1][1], (m).n[1][2], (m).n[1][3], \ (m).n[2][0], (m).n[2][1], (m).n[2][2], (m).n[2][3], \ 0.0, 0.0, 0.0, 1.0 -/// A line, or ray. +/** A line, or ray. */ typedef struct dmnsn_line { - dmnsn_vector x0; ///< A point on the line. - dmnsn_vector n; ///< A normal vector; the direction of the line. + dmnsn_vector x0; /**< A point on the line. */ + dmnsn_vector n; /**< A normal vector; the direction of the line. */ } dmnsn_line; -/// A standard format string for lines. +/** A standard format string for lines. */ #define DMNSN_LINE_FORMAT "(<%g, %g, %g> + t*<%g, %g, %g>)" -/// The appropriate arguements to printf() a line. +/** The appropriate arguements to printf() a line. */ #define DMNSN_LINE_PRINTF(l) \ DMNSN_VECTOR_PRINTF((l).x0), DMNSN_VECTOR_PRINTF((l).n) -/// An axis-aligned bounding box (AABB). +/** An axis-aligned bounding box (AABB). */ typedef struct dmnsn_bounding_box { - dmnsn_vector min; ///< The coordinate-wise minimum extent of the box. - dmnsn_vector max; ///< The coordinate-wise maximum extent of the box. + dmnsn_vector min; /**< The coordinate-wise minimum extent of the box. */ + dmnsn_vector max; /**< The coordinate-wise maximum extent of the box. */ } dmnsn_bounding_box; -/// A standard format string for bounding boxes. +/** A standard format string for bounding boxes. */ #define DMNSN_BOUNDING_BOX_FORMAT "(<%g, %g, %g> ==> <%g, %g, %g>)" -/// The appropriate arguements to printf() a bounding box. +/** The appropriate arguements to printf() a bounding box. */ #define DMNSN_BOUNDING_BOX_PRINTF(box) \ DMNSN_VECTOR_PRINTF((box).min), DMNSN_VECTOR_PRINTF((box).max) -// Constants +/* Constants */ -/// The smallest value considered non-zero by some numerical algorithms. +/** The smallest value considered non-zero by some numerical algorithms. */ #define dmnsn_epsilon 1.0e-10 -/// The zero vector. +/** The zero vector. */ static const dmnsn_vector dmnsn_zero = { 0.0, 0.0, 0.0 }; -/// The x vector. +/** The x vector. */ static const dmnsn_vector dmnsn_x = { 1.0, 0.0, 0.0 }; -/// The y vector. +/** The y vector. */ static const dmnsn_vector dmnsn_y = { 0.0, 1.0, 0.0 }; -/// The z vector. +/** The z vector. */ static const dmnsn_vector dmnsn_z = { 0.0, 0.0, 1.0 }; -// Scalar functions +/** + * @def DMNSN_INFINITY + * Expands to floating-point infinity. + */ +#if defined(INFINITY) || DMNSN_C99 + #define DMNSN_INFINITY INFINITY +#else + #define DMNSN_INFINITY HUGE_VAL +#endif -/// Find the minimum of two scalars. +/* Scalar functions */ + +/** Find the minimum of two scalars. */ DMNSN_INLINE double dmnsn_min(double a, double b) { return a < b ? a : b; } -/// Find the maximum of two scalars. +/** Find the maximum of two scalars. */ DMNSN_INLINE double dmnsn_max(double a, double b) { return a > b ? a : b; } -/// Convert degrees to radians. +/** Convert degrees to radians. */ DMNSN_INLINE double dmnsn_radians(double degrees) { return degrees*atan(1.0)/45.0; } -/// Convert radians to degrees. +/** Convert radians to degrees. */ DMNSN_INLINE double dmnsn_degrees(double radians) { return radians*45.0/atan(1.0); } -/// Return the sign of a scalar. +/** Return the sign of a scalar. */ DMNSN_INLINE int dmnsn_sign(double n) { @@ -137,9 +147,9 @@ dmnsn_sign(double n) } } -// Shorthand for vector/matrix construction +/* Shorthand for vector/matrix construction */ -/// Construct a new vector. +/** Construct a new vector. */ DMNSN_INLINE dmnsn_vector dmnsn_new_vector(double x, double y, double z) { @@ -147,7 +157,7 @@ dmnsn_new_vector(double x, double y, double z) return v; } -/// Construct a new transformation matrix. +/** Construct a new transformation matrix. */ DMNSN_INLINE dmnsn_matrix dmnsn_new_matrix(double a0, double a1, double a2, double a3, double b0, double b1, double b2, double b3, @@ -159,7 +169,7 @@ dmnsn_new_matrix(double a0, double a1, double a2, double a3, return m; } -/// Construct a new transformation matrix from column vectors. +/** Construct a new transformation matrix from column vectors. */ DMNSN_INLINE dmnsn_matrix dmnsn_new_matrix4(dmnsn_vector a, dmnsn_vector b, dmnsn_vector c, dmnsn_vector d) @@ -170,14 +180,14 @@ dmnsn_new_matrix4(dmnsn_vector a, dmnsn_vector b, dmnsn_vector c, return m; } -/// Extract column vectors from a matrix. +/** Extract column vectors from a matrix. */ DMNSN_INLINE dmnsn_vector dmnsn_matrix_column(dmnsn_matrix M, unsigned int i) { return dmnsn_new_vector(M.n[0][i], M.n[1][i], M.n[2][i]); } -/// Return the identity matrix. +/** Return the identity matrix. */ dmnsn_matrix dmnsn_identity_matrix(void); /** @@ -238,119 +248,119 @@ dmnsn_new_bounding_box(dmnsn_vector min, dmnsn_vector max) return box; } -/// Return the bounding box which contains nothing. +/** Return the bounding box which contains nothing. */ DMNSN_INLINE dmnsn_bounding_box dmnsn_zero_bounding_box(void) { dmnsn_bounding_box box = { - { INFINITY, INFINITY, INFINITY }, - { -INFINITY, -INFINITY, -INFINITY } + { DMNSN_INFINITY, DMNSN_INFINITY, DMNSN_INFINITY }, + { -DMNSN_INFINITY, -DMNSN_INFINITY, -DMNSN_INFINITY } }; return box; } -/// Return the bounding box which contains everything. +/** Return the bounding box which contains everything. */ DMNSN_INLINE dmnsn_bounding_box dmnsn_infinite_bounding_box(void) { dmnsn_bounding_box box = { - { -INFINITY, -INFINITY, -INFINITY }, - { INFINITY, INFINITY, INFINITY } + { -DMNSN_INFINITY, -DMNSN_INFINITY, -DMNSN_INFINITY }, + { DMNSN_INFINITY, DMNSN_INFINITY, DMNSN_INFINITY } }; return box; } -// Vector and matrix arithmetic +/* Vector and matrix arithmetic */ -/// Negate a vector. +/** Negate a vector. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_negate(dmnsn_vector rhs) { - // 3 negations + /* 3 negations */ dmnsn_vector v = { -rhs.x, -rhs.y, -rhs.z }; return v; } -/// Add two vectors. +/** Add two vectors. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs) { - // 3 additions + /* 3 additions */ dmnsn_vector v = { lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z }; return v; } -/// Subtract two vectors. +/** Subtract two vectors. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs) { - // 3 additions + /* 3 additions */ dmnsn_vector v = { lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z }; return v; } -/// Multiply a vector by a scalar. +/** Multiply a vector by a scalar. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_mul(double lhs, dmnsn_vector rhs) { - // 3 multiplications + /* 3 multiplications */ dmnsn_vector v = { lhs*rhs.x, lhs*rhs.y, lhs*rhs.z }; return v; } -/// Divide a vector by a scalar. +/** Divide a vector by a scalar. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_div(dmnsn_vector lhs, double rhs) { - // 3 divisions + /* 3 divisions */ dmnsn_vector v = { lhs.x/rhs, lhs.y/rhs, lhs.z/rhs }; return v; } -/// Return the dot product of two vectors. +/** Return the dot product of two vectors. */ DMNSN_INLINE double dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs) { - // 3 multiplications, 2 additions + /* 3 multiplications, 2 additions */ return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; } -/// Return the cross product of two vectors. +/** Return the cross product of two vectors. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs) { - // 6 multiplications, 3 additions + /* 6 multiplications, 3 additions */ dmnsn_vector v = { lhs.y*rhs.z - lhs.z*rhs.y, lhs.z*rhs.x - lhs.x*rhs.z, lhs.x*rhs.y - lhs.y*rhs.x }; return v; } -/// Return the projection of \p u onto \p d. +/** Return the projection of \p u onto \p d. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_proj(dmnsn_vector u, dmnsn_vector d) { - // 1 division, 9 multiplications, 4 additions + /* 1 division, 9 multiplications, 4 additions */ return dmnsn_vector_mul(dmnsn_vector_dot(u, d)/dmnsn_vector_dot(d, d), d); } -/// Return the magnitude of a vector. +/** Return the magnitude of a vector. */ DMNSN_INLINE double dmnsn_vector_norm(dmnsn_vector n) { - // 1 sqrt, 3 multiplications, 2 additions + /* 1 sqrt, 3 multiplications, 2 additions */ return sqrt(dmnsn_vector_dot(n, n)); } -/// Return the direction of a vector. +/** Return the direction of a vector. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_normalized(dmnsn_vector n) { - // 1 sqrt, 3 divisions, 3 multiplications, 2 additions + /* 1 sqrt, 3 divisions, 3 multiplications, 2 additions */ return dmnsn_vector_div(n, dmnsn_vector_norm(n)); } -/// Return the component-wise minimum of two vectors. +/** Return the component-wise minimum of two vectors. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_min(dmnsn_vector a, dmnsn_vector b) { @@ -361,7 +371,7 @@ dmnsn_vector_min(dmnsn_vector a, dmnsn_vector b) ); } -/// Return the component-wise maximum of two vectors. +/** Return the component-wise maximum of two vectors. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_max(dmnsn_vector a, dmnsn_vector b) { @@ -372,17 +382,17 @@ dmnsn_vector_max(dmnsn_vector a, dmnsn_vector b) ); } -/// Invert a matrix. +/** Invert a matrix. */ dmnsn_matrix dmnsn_matrix_inverse(dmnsn_matrix A); -/// Multiply two matricies. +/** Multiply two matricies. */ dmnsn_matrix dmnsn_matrix_mul(dmnsn_matrix lhs, dmnsn_matrix rhs); -/// Transform a point by a matrix. +/** Transform a point by a matrix. */ DMNSN_INLINE dmnsn_vector dmnsn_transform_point(dmnsn_matrix T, dmnsn_vector v) { - // 9 multiplications, 9 additions + /* 9 multiplications, 9 additions */ dmnsn_vector r; r.x = T.n[0][0]*v.x + T.n[0][1]*v.y + T.n[0][2]*v.z + T.n[0][3]; r.y = T.n[1][0]*v.x + T.n[1][1]*v.y + T.n[1][2]*v.z + T.n[1][3]; @@ -390,11 +400,11 @@ dmnsn_transform_point(dmnsn_matrix T, dmnsn_vector v) return r; } -/// Transform a direction by a matrix. +/** Transform a direction by a matrix. */ DMNSN_INLINE dmnsn_vector dmnsn_transform_direction(dmnsn_matrix T, dmnsn_vector v) { - // 9 multiplications, 6 additions + /* 9 multiplications, 6 additions */ dmnsn_vector r; r.x = T.n[0][0]*v.x + T.n[0][1]*v.y + T.n[0][2]*v.z; r.y = T.n[1][0]*v.x + T.n[1][1]*v.y + T.n[1][2]*v.z; @@ -411,7 +421,8 @@ dmnsn_transform_direction(dmnsn_matrix T, dmnsn_vector v) DMNSN_INLINE dmnsn_vector dmnsn_transform_normal(dmnsn_matrix Tinv, dmnsn_vector v) { - // Multiply by the transpose of the inverse (9 multiplications, 6 additions) + /* Multiply by the transpose of the inverse + (9 multiplications, 6 additions) */ dmnsn_vector r; r.x = Tinv.n[0][0]*v.x + Tinv.n[1][0]*v.y + Tinv.n[2][0]*v.z; r.y = Tinv.n[0][1]*v.x + Tinv.n[1][1]*v.y + Tinv.n[2][1]*v.z; @@ -419,7 +430,7 @@ dmnsn_transform_normal(dmnsn_matrix Tinv, dmnsn_vector v) return r; } -/// Transform a bounding box by a matrix. +/** Transform a bounding box by a matrix. */ dmnsn_bounding_box dmnsn_transform_bounding_box(dmnsn_matrix T, dmnsn_bounding_box box); @@ -431,7 +442,7 @@ dmnsn_bounding_box dmnsn_transform_bounding_box(dmnsn_matrix T, DMNSN_INLINE dmnsn_line dmnsn_transform_line(dmnsn_matrix T, dmnsn_line l) { - // 18 multiplications, 24 additions + /* 18 multiplications, 24 additions */ dmnsn_line ret; ret.x0 = dmnsn_transform_point(T, l.x0); ret.n = dmnsn_transform_direction(T, l.n); @@ -448,7 +459,7 @@ dmnsn_line_point(dmnsn_line l, double t) return dmnsn_vector_add(l.x0, dmnsn_vector_mul(t, l.n)); } -/// Add epsilon*l.n to l.x0, to avoid self-intersections. +/** Add epsilon*l.n to l.x0, to avoid self-intersections. */ DMNSN_INLINE dmnsn_line dmnsn_line_add_epsilon(dmnsn_line l) { @@ -477,7 +488,7 @@ dmnsn_symmetric_bounding_box(dmnsn_vector r) return box; } -/// Return whether \p p is within the axis-aligned bounding box. +/** Return whether \p p is within the axis-aligned bounding box. */ DMNSN_INLINE bool dmnsn_bounding_box_contains(dmnsn_bounding_box box, dmnsn_vector p) { @@ -485,11 +496,11 @@ dmnsn_bounding_box_contains(dmnsn_bounding_box box, dmnsn_vector p) && (p.x <= box.max.x && p.y <= box.max.y && p.z <= box.max.z); } -/// Return whether a bounding box is infinite. +/** Return whether a bounding box is infinite. */ DMNSN_INLINE bool dmnsn_bounding_box_is_infinite(dmnsn_bounding_box box) { - return box.min.x == -INFINITY; + return box.min.x == -DMNSN_INFINITY; } /** @@ -508,21 +519,32 @@ dmnsn_bounding_box_swallow(dmnsn_bounding_box box, dmnsn_vector point) return ret; } -/// Return whether a vector contains any NaN components. +/** Return whether a scalar is NaN. */ +DMNSN_INLINE bool +dmnsn_isnan(double n) +{ +#if DMNSN_C99 + return isnan(n); +#else + return n != n; +#endif +} + +/** Return whether a vector contains any NaN components. */ DMNSN_INLINE bool dmnsn_vector_isnan(dmnsn_vector v) { - return isnan(v.x) || isnan(v.y) || isnan(v.z); + return dmnsn_isnan(v.x) || dmnsn_isnan(v.y) || dmnsn_isnan(v.z); } -/// Return whether a matrix contains any NaN components. +/** Return whether a matrix contains any NaN components. */ DMNSN_INLINE bool dmnsn_matrix_isnan(dmnsn_matrix m) { size_t i, j; for (i = 0; i < 3; ++i) { for (j = 0; j < 4; ++j) { - if (isnan(m.n[i][j])) { + if (dmnsn_isnan(m.n[i][j])) { return true; } } @@ -530,14 +552,14 @@ dmnsn_matrix_isnan(dmnsn_matrix m) return false; } -/// Return whether a line contains any NaN entries. +/** Return whether a line contains any NaN entries. */ DMNSN_INLINE bool dmnsn_line_isnan(dmnsn_line l) { return dmnsn_vector_isnan(l.x0) || dmnsn_vector_isnan(l.n); } -/// Return whether a bounding box has any NaN components. +/** Return whether a bounding box has any NaN components. */ DMNSN_INLINE bool dmnsn_bounding_box_isnan(dmnsn_bounding_box box) { -- cgit v1.2.3