240 lines
5.4 KiB
C++
240 lines
5.4 KiB
C++
/*
|
|
* This file is part of the Owl Positioning System (OwlPS).
|
|
* OwlPS is a project of the University of Franche-Comte
|
|
* (Université de Franche-Comté), France.
|
|
*
|
|
* Copyright © Université de Franche-Comté 2007-2012.
|
|
*
|
|
* Corresponding author: Matteo Cypriani <mcy@lm7.fr>
|
|
*
|
|
***********************************************************************
|
|
*
|
|
* This software is governed by the CeCILL license under French law and
|
|
* abiding by the rules of distribution of free software. You can use,
|
|
* modify and/or redistribute the software under the terms of the CeCILL
|
|
* license as circulated by CEA, CNRS and INRIA at the following URL:
|
|
* http://www.cecill.info
|
|
*
|
|
* As a counterpart to the access to the source code and rights to copy,
|
|
* modify and redistribute granted by the license, users are provided
|
|
* only with a limited warranty and the software's authors, the holder
|
|
* of the economic rights, and the successive licensors have only
|
|
* limited liability.
|
|
*
|
|
* In this respect, the user's attention is drawn to the risks
|
|
* associated with loading, using, modifying and/or developing or
|
|
* reproducing the software by the user in light of its specific status
|
|
* of free software, that may mean that it is complicated to manipulate,
|
|
* and that also therefore means that it is reserved for developers and
|
|
* experienced professionals having in-depth computer knowledge. Users
|
|
* are therefore encouraged to load and test the software's suitability
|
|
* as regards their requirements in conditions enabling the security of
|
|
* their systems and/or data to be ensured and, more generally, to use
|
|
* and operate it in the same conditions as regards security.
|
|
*
|
|
* The fact that you are presently reading this means that you have had
|
|
* knowledge of the CeCILL license and that you accept its terms.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
|
|
|
|
#include "point3d.hh"
|
|
#include "posutil.hh"
|
|
#include "posexcept.hh"
|
|
|
|
#include <sstream>
|
|
#include <boost/functional/hash.hpp>
|
|
|
|
using namespace std ;
|
|
|
|
|
|
|
|
/* *** Constructors *** */
|
|
|
|
|
|
Point3D::Point3D(const string &source)
|
|
{
|
|
float pos[3] ;
|
|
istringstream iss(source) ;
|
|
|
|
for (int i = 0 ; i < 2 ; ++i)
|
|
{
|
|
iss >> pos[i] ;
|
|
if (iss.get() != ';')
|
|
throw malformed_input_data(
|
|
"Point3D(string): cannot extract coordinates!") ;
|
|
}
|
|
iss >> pos[2] ;
|
|
|
|
set_coordinates(pos) ;
|
|
}
|
|
|
|
|
|
|
|
/* *** Distance operations *** */
|
|
|
|
|
|
/**
|
|
* The distance is not square rooted after the computation, in order
|
|
* to optimise comparisons.
|
|
*/
|
|
float Point3D::square_distance_2d(const Point3D &source) const
|
|
{
|
|
return
|
|
(x - source.x) * (x - source.x) +
|
|
(y - source.y) * (y - source.y) ;
|
|
}
|
|
|
|
|
|
/**
|
|
* The distance is not square rooted after the computation, in order
|
|
* to optimise comparisons.
|
|
*/
|
|
float Point3D::square_distance(const Point3D &source) const
|
|
{
|
|
return
|
|
(x - source.x) * (x - source.x) +
|
|
(y - source.y) * (y - source.y) +
|
|
(z - source.z) * (z - source.z) ;
|
|
}
|
|
|
|
|
|
/**
|
|
* A, B and C are three points, A being the current Point3D (*this).
|
|
* This function computes the angle BÂC, in two dimensions (i.e. the Z
|
|
* coordinate of the points is ignored).
|
|
*
|
|
* If the points are aligned, the angle returned is always 0° (and not
|
|
* 180°, even in the case where A is on [BC]).
|
|
*
|
|
* @returns The angle BÂC, in the interval [0, 180[ degrees.
|
|
*/
|
|
double Point3D::angle_2d(const Point3D &b, const Point3D &c) const
|
|
{
|
|
double
|
|
sq_ab = square_distance_2d(b),
|
|
sq_ac = square_distance_2d(c),
|
|
sq_bc = b.square_distance_2d(c) ;
|
|
|
|
if (sq_ab == 0 || sq_ac == 0 || sq_bc == 0)
|
|
return 0 ;
|
|
|
|
double
|
|
ab = sqrt(sq_ab),
|
|
ac = sqrt(sq_ac) ;
|
|
|
|
double cos_bac = (sq_ab + sq_ac - sq_bc) / (2 * ab * ac) ;
|
|
double bac = acos(cos_bac) ;
|
|
|
|
return PosUtil::rad2deg(bac) ;
|
|
}
|
|
|
|
|
|
/**
|
|
* #x and #y are updated with the rotated image of the point.
|
|
*
|
|
* Note that as this functions does a 2D rotation, the c.z is ignored,
|
|
* and so is this->x.
|
|
*/
|
|
void Point3D::rotate_2d(const Point3D &c, float angle)
|
|
{
|
|
angle = PosUtil::deg2rad(angle) ;
|
|
|
|
float new_x = cos(angle) * (x-c.x) - sin(angle) * (y-c.y) + c.x ;
|
|
float new_y = sin(angle) * (x-c.x) + cos(angle) * (y-c.y) + c.y ;
|
|
|
|
x = new_x ;
|
|
y = new_y ;
|
|
}
|
|
|
|
|
|
|
|
/* *** Operators *** */
|
|
|
|
|
|
Point3D& Point3D::operator=(const Point3D &source)
|
|
{
|
|
if (this == &source)
|
|
return *this ;
|
|
|
|
x = source.x ;
|
|
y = source.y ;
|
|
z = source.z ;
|
|
|
|
return *this ;
|
|
}
|
|
|
|
|
|
bool Point3D::operator==(const Point3D &source) const
|
|
{
|
|
if (this == &source)
|
|
return true ;
|
|
|
|
return
|
|
x == source.x &&
|
|
y == source.y &&
|
|
z == source.z ;
|
|
}
|
|
|
|
|
|
bool Point3D::operator<(const Point3D &source) const
|
|
{
|
|
if (x < source.x)
|
|
return true ;
|
|
if (x > source.x)
|
|
return false ;
|
|
|
|
if (y < source.y)
|
|
return true ;
|
|
if (y > source.y)
|
|
return false ;
|
|
|
|
if (z < source.z)
|
|
return true ;
|
|
|
|
return false ;
|
|
}
|
|
|
|
|
|
Point3D::operator std::string(void) const
|
|
{
|
|
ostringstream oss ;
|
|
oss << *this ;
|
|
return oss.str() ;
|
|
}
|
|
|
|
|
|
/**
|
|
* @return \em true if either #x, #y or #z is non-zero.
|
|
* @return \em false if #x, #y and #z are defined to 0.
|
|
*/
|
|
Point3D::operator bool(void) const
|
|
{
|
|
return
|
|
x != 0 ||
|
|
y != 0 ||
|
|
z != 0 ;
|
|
}
|
|
|
|
|
|
|
|
ostream& operator<<(ostream &os, const Point3D &p)
|
|
{
|
|
os << "(" << p.x << ";" << p.y << ";" << p.z << ")" ;
|
|
return os ;
|
|
}
|
|
|
|
|
|
|
|
size_t hash_value(const Point3D &source)
|
|
{
|
|
size_t seed = 0 ;
|
|
|
|
boost::hash_combine(seed, source.x) ;
|
|
boost::hash_combine(seed, source.y) ;
|
|
boost::hash_combine(seed, source.z) ;
|
|
|
|
return seed ;
|
|
}
|