diff --git a/INSTALL.t2t b/INSTALL.t2t index 4d71170..564eb76 100644 --- a/INSTALL.t2t +++ b/INSTALL.t2t @@ -11,6 +11,7 @@ libraries installed: - //pcap// - the //Boost// C++ libraries, and particularly the ``program_options`` module +- the //Tween// module of the //Claw// C++ library - //iwlib// from the Wireless Tools (package``libiw-dev`` on Debian, ``wireless-tools-devel`` on Fedora); only for OwlPS Listener's ``-K`` option diff --git a/cmake/Modules/FindClawTween.cmake b/cmake/Modules/FindClawTween.cmake new file mode 100644 index 0000000..9caa929 --- /dev/null +++ b/cmake/Modules/FindClawTween.cmake @@ -0,0 +1,28 @@ +# This file is part of the Owl Positioning System (OwlPS) project. +# It is subject to the copyright notice and license terms in the +# COPYRIGHT.t2t file found in the top-level directory of this +# distribution and at +# http://code.lm7.fr/p/owlps/source/tree/master/COPYRIGHT.t2t +# No part of the OwlPS Project, including this file, may be copied, +# modified, propagated, or distributed except according to the terms +# contained in the COPYRIGHT.t2t file; the COPYRIGHT.t2t file must be +# distributed along with this file, either separately or by replacing +# this notice by the COPYRIGHT.t2t file's contents. + +# This module tries to find the Claw Tween library and sets the +# following variables: +# CLAWTWEEN_INCLUDE_DIR +# CLAWTWEEN_LIBRARY +# CLAWTWEEN_FOUND + +# Search for the header file +find_path(CLAWTWEEN_INCLUDE_DIR tweener.hpp + PATH_SUFFIXES include/claw/tween) + +# Search for the library +find_library(CLAWTWEEN_LIBRARY claw_tween + PATH_SUFFIXES lib) + +# Did we find everything we need? +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ClawTween DEFAULT_MSG + CLAWTWEEN_LIBRARY CLAWTWEEN_INCLUDE_DIR) diff --git a/owlps-positioner/CMakeLists.txt b/owlps-positioner/CMakeLists.txt index 66f8e2e..ac426c3 100644 --- a/owlps-positioner/CMakeLists.txt +++ b/owlps-positioner/CMakeLists.txt @@ -18,7 +18,16 @@ if (NOT Boost_FOUND) endif() include_directories(${Boost_INCLUDE_DIRS}) -set(EXTRA_LIBS ${EXTRA_LIBS} ${Boost_LIBRARIES} m) +# Make sure libclaw_tween is installed +find_package(ClawTween) +if (NOT CLAWTWEEN_FOUND) + message(WARNING + "OwlPS Positioner dependency missing: Claw Tween (libclaw_tween)") + return() +endif() +include_directories(${CLAWTWEEN_INCLUDE_DIR}) + +set(EXTRA_LIBS ${EXTRA_LIBS} ${Boost_LIBRARIES} ${CLAWTWEEN_LIBRARY} m) # On Linux and other GNU systems (e.g. GNU/kFreeBSD), we need -lrt for # clock_gettime() diff --git a/owlps-positioner/point3d.cc b/owlps-positioner/point3d.cc index f28a4d7..666caec 100644 --- a/owlps-positioner/point3d.cc +++ b/owlps-positioner/point3d.cc @@ -18,6 +18,11 @@ #include +// For interpolate() +#include +#include +#include + using namespace std ; @@ -122,6 +127,72 @@ void Point3D::rotate_2d(const Point3D &c, float angle) +/* *** Other operations *** */ + + +/** + * This function computes the intermediate (linear) values between the + * current point and the point `end`. + * + * The number of steps is function of `step_hint` and the distance + * between the two points. `step_hint`, as its name indicates, is a hint + * of the desired distance between two intermediate coordinates. It is + * adjusted by the function to distribute equally the intermediate + * coordinates between the two extremities. + * + * @param[in] end Coordinate of the last extremity. + * @param[in,out] step_hint The desired approximate distance between two + * intermediate points; when the function returns, it is set to the + * actual step used. + * @param[out] interpolated The vector in which the intermediate values + * will be stored. The two extremities are not included in this vector, + * but of course the calling function can add values prior and after the + * function call. + */ +void Point3D::interpolate(const Point3D &end, float &step_hint, + std::vector &interpolated) const +{ + /** + * Example of step computation: if the distance between the two + * extremities (`*this` and `end`) is 12.42 m and `step_hint` is set + * to 2 m, the number of steps is 12 / 2 == 6, and the actual distance + * between two intermediate coordinates is 12.42 / 6 == 2.07 m. + */ + float dist = distance(end) ; + int nb_steps = dist / step_hint ; + step_hint = dist / nb_steps ; + + /* Set up the tweener */ + // Individual tweeners for X, Y and Z + double tweened_x = x, tweened_y = y, tweened_z = z ; + claw::tween::single_tweener + interpolator_x(tweened_x, end.x, dist, + claw::tween::easing_linear::ease_in) ; + claw::tween::single_tweener + interpolator_y(tweened_y, end.y, dist, + claw::tween::easing_linear::ease_in) ; + claw::tween::single_tweener + interpolator_z(tweened_z, end.z, dist, + claw::tween::easing_linear::ease_in) ; + // Consolidated tweener for both X and Y + claw::tween::tweener_group interpolator ; + interpolator.insert(interpolator_x) ; + interpolator.insert(interpolator_y) ; + interpolator.insert(interpolator_z) ; + + /* Compute interpolated values */ + do + { + // Update tweened_x, tweened_y, tweened_z + interpolator.update(step_hint); + // Add the new coordinates to the vector + interpolated.push_back(Point3D(tweened_x, tweened_y, tweened_z)) ; + } + while (! interpolator.is_finished()) ; +} + + + /* *** Operators *** */ diff --git a/owlps-positioner/point3d.hh b/owlps-positioner/point3d.hh index 9f3792c..56f77c0 100644 --- a/owlps-positioner/point3d.hh +++ b/owlps-positioner/point3d.hh @@ -79,6 +79,13 @@ public: void rotate_2d(const Point3D ¢er, float angle) ; //@} + /** @name Other operations */ + //@{ + /// Interpolates the coordinates of a Point3D + void interpolate(const Point3D &end, float &step_hint, + std::vector &interpolated) const ; + //@} + /** @name Operators */ //@{ Point3D& operator=(const Point3D &source) ;