From 76c809f031d0e1e1dc288c1b9b384231a0d07c8d Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Tue, 17 Apr 2018 14:26:23 +1000 Subject: [PATCH] point/vector: homog no longer takes a size parameter --- geom/ellipse.cpp | 39 ++++++++++++++++++++---------- geom/ellipse.hpp | 8 +++++++ geom/ray.cpp | 13 ---------- geom/ray.hpp | 11 +++++++-- matrix.cpp | 56 ++++++++++++++++++++++--------------------- matrix.hpp | 50 +++++++++++++++++++++++++++++++------- point.hpp | 20 ++-------------- test/affine.cpp | 10 ++++---- test/geom/ellipse.cpp | 7 ++++++ test/point.cpp | 6 ++--- vector.hpp | 7 +++--- 11 files changed, 134 insertions(+), 93 deletions(-) diff --git a/geom/ellipse.cpp b/geom/ellipse.cpp index 3fcb0418..7abe960c 100644 --- a/geom/ellipse.cpp +++ b/geom/ellipse.cpp @@ -47,30 +47,38 @@ util::geom::intersects (A a, B b) //----------------------------------------------------------------------------- -template bool util::geom::intersects (ellipse<2,float>, util::point<2,float>); -template bool util::geom::intersects (ellipse<3,float>, util::point<3,float>); + + +/////////////////////////////////////////////////////////////////////////////// +template +util::point +util::geom::project (util::geom::ray lhs, + util::geom::ellipse rhs) +{ + return lhs.origin + lhs.direction * distance (lhs, rhs); +} /////////////////////////////////////////////////////////////////////////////// // query a ray-ellipse distance by transforming spaces such that the ellipse is // a sphere -template <> -float -util::geom::distance (ray<3,float> r, ellipse<3,float> e) +template +ValueT +util::geom::distance (ray r, ellipse e) { // find a transform that puts the ellipse at origin and scales it to a // unit sphere. - auto const from_scaled = util::scale (e.radius) * - util::look_at (e.origin, {0,0,-1}, e.up); + auto const from_scaled = util::translation (e.origin.template as ()) * + util::scale (e.radius); auto const to_scaled = inverse (from_scaled); // transform the ray into this new space and query against a unit sphere auto const scaled_r = to_scaled * r; - auto const scaled_d = distance (scaled_r, sphere3f {0, 1.f}); + auto const scaled_d = distance (scaled_r, sphere {0, 1.f}); auto const scaled_p = scaled_r.at (scaled_d); // transform the result back into the original space - return distance (r.origin, (from_scaled * scaled_p.homog<4> ()).redim<3> ()); + return distance (r.origin, (from_scaled * scaled_p.homog ()).template redim ()); } @@ -95,6 +103,13 @@ util::geom::bounds (K k) } -//----------------------------------------------------------------------------- -template util::geom::aabb<2,float> util::geom::bounds (ellipse<2,float>); -template util::geom::aabb<3,float> util::geom::bounds (ellipse<3,float>); + +/////////////////////////////////////////////////////////////////////////////// +#define INSTANTIATE_S_T(S,T) \ +template bool util::geom::intersects (ellipse, util::point); \ +template util::point util::geom::project(ray, ellipse); \ +template util::geom::aabb util::geom::bounds (ellipse); + + +INSTANTIATE_S_T(2,float) +INSTANTIATE_S_T(3,float) diff --git a/geom/ellipse.hpp b/geom/ellipse.hpp index 7ea3367b..5d833717 100644 --- a/geom/ellipse.hpp +++ b/geom/ellipse.hpp @@ -39,6 +39,14 @@ namespace util::geom { }; + template + point + project ( + ray, + ellipse + ); + + /// returns the distance along a ray to the surface of an ellipse. /// /// returns infinity if there is no intersection diff --git a/geom/ray.cpp b/geom/ray.cpp index 885d22ce..56c4fcd1 100644 --- a/geom/ray.cpp +++ b/geom/ray.cpp @@ -44,19 +44,6 @@ ray::at (T t) const } -/////////////////////////////////////////////////////////////////////////////// -util::geom::ray3f -util::geom::operator* (util::matrix4f lhs, ray3f rhs) -{ - return { - (lhs * rhs.origin.homog<4> ()).redim<3> (), - normalised ( - (lhs * rhs.direction.homog<4> ()).redim<3> () - ) - }; -} - - /////////////////////////////////////////////////////////////////////////////// template std::ostream& diff --git a/geom/ray.hpp b/geom/ray.hpp index cb24492f..65792ece 100644 --- a/geom/ray.hpp +++ b/geom/ray.hpp @@ -50,8 +50,15 @@ namespace util::geom { /////////////////////////////////////////////////////////////////////////// - ray3f - operator* (matrix4f, ray3f); + template + ray + operator* (matrix lhs, ray rhs) + { + return { + lhs * rhs.origin, + normalised (lhs * rhs.direction) + }; + } /////////////////////////////////////////////////////////////////////////// diff --git a/matrix.cpp b/matrix.cpp index 4c4e0800..954f0b25 100644 --- a/matrix.cpp +++ b/matrix.cpp @@ -225,30 +225,31 @@ util::look_at (const util::point<3,T> eye, { 0, 0, 0, 1 }, }}; - return rot * util::translation (0-eye); + return rot * util::translation (0-eye); } template util::matrix4f util::look_at (util::point3f, util::point3f, util::vector3f); //----------------------------------------------------------------------------- -template -util::matrix4 -util::translation (util::vector<3,T> v) -{ - return { { - { 1.f, 0.f, 0.f, v.x }, - { 0.f, 1.f, 0.f, v.y }, - { 0.f, 0.f, 1.f, v.z }, - { 0.f, 0.f, 0.f, 1.f }, - } }; -} - - -template util::matrix4f util::translation (util::vector3f); +//template +//util::matrix4 +//util::translation (util::vector<3,T> v) +//{ +// return { { +// { 1.f, 0.f, 0.f, v.x }, +// { 0.f, 1.f, 0.f, v.y }, +// { 0.f, 0.f, 1.f, v.z }, +// { 0.f, 0.f, 0.f, 1.f }, +// } }; +//} +// +// +//template util::matrix4f util::translation (util::vector3f); //----------------------------------------------------------------------------- +#if 0 template util::matrix4 util::scale (T mag) @@ -257,22 +258,23 @@ util::scale (T mag) } template util::matrix4f util::scale(float); +#endif //----------------------------------------------------------------------------- -template -util::matrix4 -util::scale (util::vector<3,T> v) -{ - return { { - { v.x, 0.f, 0.f, 0.f }, - { 0.f, v.y, 0.f, 0.f }, - { 0.f, 0.f, v.z, 0.f }, - { 0.f, 0.f, 0.f, 1.f } - } }; -} +//template +//util::matrix4 +//util::scale (util::vector<3,T> v) +//{ +// return { { +// { v.x, 0.f, 0.f, 0.f }, +// { 0.f, v.y, 0.f, 0.f }, +// { 0.f, 0.f, v.z, 0.f }, +// { 0.f, 0.f, 0.f, 1.f } +// } }; +//} -template util::matrix4f util::scale(util::vector3f); +//template util::matrix4f util::scale(util::vector3f); //----------------------------------------------------------------------------- diff --git a/matrix.hpp b/matrix.hpp index ab5a0cff..05753e18 100644 --- a/matrix.hpp +++ b/matrix.hpp @@ -172,12 +172,16 @@ namespace util { auto operator* (const VectorT &rhs) const { - VectorT out; - - for (std::size_t r = 0; r < Rows; ++r) - out[r] = dot (rhs, values[r]); - - return out; + if constexpr (VectorT::elements + 1 == Cols) { + return ( + *this * rhs.homog () + ).template redim (); + } else { + VectorT out; + for (std::size_t r = 0; r < Rows; ++r) + out[r] = dot (rhs, values[r]); + return out; + } } bool is_affine (void) const; @@ -222,11 +226,39 @@ namespace util { template matrix<4,4,T> look_at (point<3,T> eye, point<3,T> target, vector<3,T> up); // Affine matrices - template matrix<4,4,T> translation (vector<3,T>); - template matrix<4,4,T> scale (vector<3,T>); - template matrix<4,4,T> scale (T); + template + matrix + translation (vector offset) + { + matrix res {}; + for (size_t i = 0; i != S; ++i) { + res[i][i] = 1; + res[i][S] = offset[i]; + } + res[S][S] = 1; + return res; + } + + + template + matrix + scale (vector factor) + { + matrix res {}; + for (size_t i = 0; i != S; ++i) + res[i][i] = factor[i]; + res[S][S] = 1; + return res; + } + + //template matrix<4,4,T> translation (vector<3,T>); + //template matrix<4,4,T> scale (vector<3,T>); + //template matrix<4,4,T> scale (T); template matrix<4,4,T> rotation (T angle, vector<3,T> about); + //template matrix<3,3,T> translation (vector<2,T>); + //template matrix<3,3,T> scale (vector<2,T>); + template bool diff --git a/point.hpp b/point.hpp index f7091094..100ebfe8 100644 --- a/point.hpp +++ b/point.hpp @@ -50,26 +50,10 @@ namespace util { /// expand point to use homogenous coordinates of a higher dimension. /// ie, fill with (0,..,0,1) - template - point + point homog (void) const { - static_assert (D > S, "homog will not overwrite data"); - - point out; - - // Copy the existing data - auto c = std::copy (this->begin (), - this->end (), - out.begin ()); - - // Fill until the second last element with zeros - auto f = std::fill_n (c, D - S - 1, T{0}); - - // Last element should be one - *f = T{1}; - - return out; + return this->template redim (1); } /////////////////////////////////////////////////////////////////////// diff --git a/test/affine.cpp b/test/affine.cpp index f46fd7ce..1cb0cb97 100644 --- a/test/affine.cpp +++ b/test/affine.cpp @@ -20,8 +20,8 @@ test_matrix_identities (util::TAP::logger &tap) util::point3f p { 1, 2, 3 }; auto m = util::translation (0-p); - auto x = m * p.homog<4> (); - tap.expect_eq (x, util::point4f {0,0,0,1}, "trivial translation to origin"); + auto x = m * p; + tap.expect_eq (x, util::point3f {0}, "trivial translation to origin"); } { @@ -29,7 +29,7 @@ test_matrix_identities (util::TAP::logger &tap) auto m = util::rotation (1, { 1, 0, 0 }) * util::rotation (1, { 0, 1, 0 }) * util::rotation (1, { 0, 0, 1 }); - auto x = m * p.homog<4> (); + auto x = m * p.homog (); tap.expect_eq (x, util::point4f {0,0,0,1}, "trivial rotation at origin"); } @@ -39,7 +39,7 @@ test_matrix_identities (util::TAP::logger &tap) util::point3f tgt { 0, 0, 0 }; auto m = util::look_at (eye, tgt, UP); - auto x = m * eye.homog<4> (); + auto x = m * eye.homog (); tap.expect_eq (x, util::point4f {0,0,0,1}, "look_at eye translation"); } @@ -48,7 +48,7 @@ test_matrix_identities (util::TAP::logger &tap) util::point3f tgt { 4, 5, 6 }; auto m = util::look_at (eye, tgt, UP); - auto x = m * eye.homog<4> (); + auto x = m * eye.homog (); tap.expect_eq (x, util::point4f {0,0,0,1}, "look_at eye translation with target"); } } diff --git a/test/geom/ellipse.cpp b/test/geom/ellipse.cpp index 12f43881..a3d36ef2 100644 --- a/test/geom/ellipse.cpp +++ b/test/geom/ellipse.cpp @@ -29,6 +29,13 @@ main () .distance = .5f, .message = "ellipse on origin, extended on z, ray along z", }, + + { + .shape = { .origin = 1, .radius = 1, .up = { 0, 1, 0 } }, + .caster = { .origin = {1,1,3}, .direction = {0,0,-1} }, + .distance = 1.f, + .message = "ellipse at 1,1,1, ray along -z", + } }; diff --git a/test/point.cpp b/test/point.cpp index cdc6c0ae..93c8c69c 100644 --- a/test/point.cpp +++ b/test/point.cpp @@ -65,13 +65,13 @@ main (void) // redim to 4-dimension homogenous coords { - const point2f p (3, 4); - const point4f q = p.homog<4> (); + const point3f p (3, 4, 5); + const point4f q = p.homog (); tap.expect ( equal (q.x, 3.f) && equal (q.y, 4.f) && - equal (q.z, 0.f) && + equal (q.z, 5.f) && equal (q.w, 1.f), "homogenous redim" diff --git a/vector.hpp b/vector.hpp index b0b736fd..03198605 100644 --- a/vector.hpp +++ b/vector.hpp @@ -46,11 +46,10 @@ namespace util { } // representations - template - vector homog (void) const + vector + homog (void) const { - static_assert (D > S, "reducing size loses data"); - return (*this).template redim (0.f); + return (*this).template redim (0.f); } // constants