/* * 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 * https://code.lm7.fr/mcy/owlps/src/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. */ #ifndef _OWLPS_POSITIONING_POINT3D_HH_ #define _OWLPS_POSITIONING_POINT3D_HH_ class Timestamp ; #include "posutil.hh" #include #include #include #include /// Represents a point of the 3-D space class Point3D { protected: float x ; ///< X horizontal coordinate (abscissa) float y ; ///< Y horizontal coordinate (ordinate) float z ; ///< Vertical coordinate public: Point3D(const float _x = 0, const float _y = 0, const float _z = 0): x(_x), y(_y), z(_z) {} Point3D(const Point3D &source): x(source.x), y(source.y), z(source.z) {} explicit Point3D(const float source[3]): x(source[0]), y(source[1]), z(source[2]) {} explicit Point3D(const std::string &source); virtual ~Point3D(void) {} /** @name Read accessors */ //@{ float get_x(void) const ; float get_y(void) const ; float get_z(void) const ; //@} /** @name Write accessors */ //@{ void set_x(const float _x) ; void set_y(const float _y) ; void set_z(const float _z) ; void set_coordinates(const float _x, const float _y, const float _z) ; void set_coordinates(const float source[3]) ; void set_coordinates(const Point3D &source) ; //@} /** @name Distance & angles operations */ //@{ /// Square euclidean distance to a Point3D, in 2D float square_distance_2d(const Point3D &p) const ; /// Square euclidean distance to a Point3D float square_distance(const Point3D &p) const ; /// Euclidean distance to a Point3D, in 2D float distance_2d(const Point3D &p) const ; /// Euclidean distance to a Point3D float distance(const Point3D &p) const ; /// Euclidean distance to the radius of a sphere float distance_to_sphere(const Point3D ¢re, const float radius) const ; /// Angle BÂC (A being *this) in 2D double angle_2d(const Point3D &b, const Point3D &c) const ; /// Rotate #x and #y with a given angle around a center c void rotate_2d(const Point3D ¢er, float angle) ; //@} /** @name Other operations */ //@{ /// Interpolates the coordinates of a Point3D to compute intermediate /// coordinates between two points void interpolate(const Point3D &end, float &step_hint, std::vector &interpolated) const ; /// Interpolates the coordinates of a Point3D according to the speed of /// the mobile Point3D interpolate(const Point3D &end, const float speed, const Timestamp &duration) const ; //@} /** @name Operators */ //@{ Point3D& operator=(const Point3D &source) ; bool operator==(const Point3D &source) const ; bool operator!=(const Point3D &source) const ; bool operator<(const Point3D &source) const ; bool operator>(const Point3D &source) const ; bool operator<=(const Point3D &source) const ; bool operator>=(const Point3D &source) const ; operator bool(void) const ; operator std::string(void) const ; //@} /// Displays a Point3D friend std::ostream& operator<<(std::ostream &os, const Point3D &p) ; } ; /* *** Read accessors *** */ inline float Point3D::get_x() const { return x ; } inline float Point3D::get_y() const { return y ; } inline float Point3D::get_z() const { return z ; } /* *** Write accessors *** */ inline void Point3D::set_x(const float _x) { x = _x ; } inline void Point3D::set_y(const float _y) { y = _y ; } inline void Point3D::set_z(const float _z) { z = _z ; } inline void Point3D:: set_coordinates(const float _x, const float _y, const float _z) { x = _x ; y = _y ; z = _z ; } inline void Point3D:: set_coordinates(const float source[3]) { x = source[0] ; y = source[1] ; z = source[2] ; } /** * Updates x, y, z by passing a Point3D. * This is useful for derivated classes, and different than a direct * call to operator=(). */ inline void Point3D::set_coordinates(const Point3D &source) { this->operator=(source) ; } /* *** Distance operations *** */ /** * Note: to compare distances, use preferably square_distance_2d(), * which is more efficient. */ inline float Point3D::distance_2d(const Point3D &source) const { return sqrtf(square_distance_2d(source)) ; } /** * Note: to compare distances, use preferably square_distance(), * which is more efficient. */ inline float Point3D::distance(const Point3D &source) const { return sqrtf(square_distance(source)) ; } /** * @param centre The centre of the sphere. * @param radius The radius of the sphere. */ inline float Point3D::distance_to_sphere( const Point3D ¢re, const float radius) const { return distance(centre) - radius ; } /* *** Operators *** */ inline bool Point3D::operator!=(const Point3D &source) const { return !(*this == source) ; } inline bool Point3D::operator>(const Point3D &source) const { return source < *this ; } inline bool Point3D::operator<=(const Point3D &source) const { return *this == source || *this < source ; } inline bool Point3D::operator>=(const Point3D &source) const { return source <= *this ; } namespace std { template<> struct hash { public: size_t operator()(const Point3D &source) const { size_t seed = 0 ; PosUtil::hash_combine(seed, source.get_x()) ; PosUtil::hash_combine(seed, source.get_y()) ; PosUtil::hash_combine(seed, source.get_z()) ; return seed ; } } ; } #endif // _OWLPS_POSITIONING_POINT3D_HH_