Skip to content
Snippets Groups Projects
Commit 1fd36149 authored by Dmitri Naumov's avatar Dmitri Naumov
Browse files

Merge pull request #62 from TomFischer/ImprovePoints

Improve points.

This clarifies comparison operations (and also corrects them) on points. Tests included.
parents 146abb40 d128c2b8
No related branches found
No related tags found
No related merge requests found
......@@ -12,48 +12,66 @@
#include <cmath>
#include <limits>
#include "Point.h"
namespace GeoLib {
bool lessX (GeoLib::Point const & p0, GeoLib::Point const & p1)
bool operator<= (const GeoLib::Point& p0, const GeoLib::Point& p1)
{
if (p0[0] <= p1[0]) return true;
return false;
}
if (p0[0] > p1[0]) {
return false;
} else {
if (p0[0] < p1[0]) {
return true;
}
}
// => p0[0] == p1[0]
bool lessY (GeoLib::Point const & p0, GeoLib::Point const & p1)
{
if (p0[1] <= p1[1]) return true;
return false;
}
if (p0[1] > p1[1]) {
return false;
} else {
if (p0[1] < p1[1]) {
return true;
}
}
// => p0[1] == p1[1]
bool lessZ (GeoLib::Point const & p0, GeoLib::Point const & p1)
{
if (p0[2] <= p1[2]) return true;
return false;
if (p0[2] > p1[2]) {
return false;
} else {
return true;
}
}
bool operator<= (const GeoLib::Point& p0, const GeoLib::Point& p1)
bool lessEq(const GeoLib::Point& p0, const GeoLib::Point& p1, double tol)
{
double tol (sqrt (std::numeric_limits<double>::min()));
if (fabs (p0[0]-p1[0]) > tol * fabs(p0[0])) {
if (p0[0] < p1[0]) return true;
else return false;
// test a relative and an absolute criterion
if (fabs(p0[0]-p1[0]) > tol * std::min(fabs(p1[0]), fabs(p0[0])) && fabs(p0[0]-p1[0]) > tol) {
if (p0[0] <= p1[0])
return true;
else
return false;
} else {
// assume p0[0] == p1[0]
if (fabs (p0[1]-p1[1]) > tol * fabs(p0[1])) {
if (p0[1] < p1[1]) return true;
else return false;
if (fabs (p0[1]-p1[1]) > tol * fabs(p0[1]) && fabs(p0[1]-p1[1]) > tol) {
if (p0[1] <= p1[1])
return true;
else
return false;
} else {
// assume p0[1] == p1[1] and p0[0] == p1[0]
if (p0[2] < p1[2]) return true;
else return false;
if (fabs (p0[2]-p1[2]) > tol * fabs(p0[2]) && fabs(p0[2]-p1[2]) > tol) {
if (p0[2] <= p1[2])
return true;
else
return false;
} else {
return true;
}
}
}
}
} // end namespace GeoLib
......@@ -13,6 +13,8 @@
#ifndef POINT_H_
#define POINT_H_
#include <limits>
#include "TemplatePoint.h"
namespace GeoLib {
......@@ -24,33 +26,19 @@ namespace GeoLib {
typedef TemplatePoint<double> Point;
/**
* comparison based on the x coordinate
* @param p0 first point
* @param p1 second point
* @return true if the x coordinate of p0 is smaller equal the x coordinate of p1, else false
*/
bool lessX (Point const & p0, Point const & p1);
/**
* comparison based on the y coordinate
* @param p0 first point
* @param p1 second point
* @return true if the y coordinate of p0 is smaller equal the y coordinate of p1, else false
*/
bool lessY (Point const & p0, Point const & p1);
/**
* comparison based on the z coordinate
* @param p0 first point
* @param p1 second point
* @return true if the z coordinate of p0 is smaller equal the z coordinate of p1, else false
* lexicographic comparison of points
*/
bool lessZ (Point const & p0, Point const & p1);
bool operator<= (GeoLib::Point const & p0, GeoLib::Point const & p1);
/**
* lexicographic comparison of points
* lexicographical comparison of points taking an epsilon into account
* @param p0 first input Point
* @param p1 first input Point
* @param tol tolerance (if in the comparison operation the property fabs(p0[k] - p1[k]) < tol
* holds for the k-th coordinate the points are assumed the be equal in this coordinate)
* @return true, if p0 is lexicographically smaller than p1
*/
bool operator<= (GeoLib::Point const & p0, GeoLib::Point const & p1);
bool lessEq(const GeoLib::Point& p0, const GeoLib::Point& p1, double tol = std::numeric_limits<double>::epsilon());
}
......
/**
* @file TestPoint.cpp
* @author Thomas Fischer
* @date Nov 8, 2012
*
* @copyright
* Copyright (c) 2012, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/LICENSE.txt
*/
#include <ctime>
#include "gtest/gtest.h"
#include "Point.h"
using namespace GeoLib;
TEST(GeoLib, PointComparisonLessEq)
{
// first coordinate
ASSERT_TRUE(lessEq(Point(0,1,1),Point(1,1,1)));
ASSERT_FALSE(lessEq(Point(1,1,1),Point(0,1,1)));
// second coordinate
ASSERT_TRUE(lessEq(Point(1,0,1),Point(1,1,1)));
ASSERT_FALSE(lessEq(Point(1,1,1),Point(1,0,1)));
// third coordinate
ASSERT_TRUE(lessEq(Point(1,1,0),Point(1,1,1)));
ASSERT_FALSE(lessEq(Point(1,1,1),Point(1,1,0)));
const double e(2*std::numeric_limits<double>::epsilon());
// first coordinate
ASSERT_TRUE(lessEq(Point(1-e,1,1),Point(1,1,1)));
ASSERT_FALSE(lessEq(Point(1,1,1),Point(1-e,1,1)));
// second coordinate
ASSERT_TRUE(lessEq(Point(1,1-e,1),Point(1,1,1)));
ASSERT_FALSE(lessEq(Point(1,1,1),Point(1,1-e,1)));
// third coordinate
ASSERT_TRUE(lessEq(Point(1,1,1-e),Point(1,1,1)));
ASSERT_FALSE(lessEq(Point(1,1,1),Point(1,1,1-e)));
ASSERT_TRUE(lessEq(Point(1,1,1),Point(1,1,1)));
const double half_eps(0.5*std::numeric_limits<double>::epsilon());
ASSERT_TRUE(lessEq(Point(1+half_eps,1,1),Point(1,1,1)));
ASSERT_TRUE(lessEq(Point(1,1+half_eps,1),Point(1,1,1)));
ASSERT_TRUE(lessEq(Point(1,1,1+half_eps),Point(1,1,1)));
ASSERT_TRUE(lessEq(Point(1,1,1),Point(1+half_eps,1,1)));
ASSERT_TRUE(lessEq(Point(1,1,1),Point(1,1+half_eps,1)));
ASSERT_TRUE(lessEq(Point(1,1,1),Point(1,1,1+half_eps)));
ASSERT_TRUE(lessEq(Point(1-half_eps,1,1),Point(1,1,1)));
ASSERT_TRUE(lessEq(Point(1,1-half_eps,1),Point(1,1,1)));
ASSERT_TRUE(lessEq(Point(1,1,1-half_eps),Point(1,1,1)));
ASSERT_TRUE(lessEq(Point(1,1,1),Point(1-half_eps,1,1)));
ASSERT_TRUE(lessEq(Point(1,1,1),Point(1,1-half_eps,1)));
ASSERT_TRUE(lessEq(Point(1,1,1),Point(1,1,1-half_eps)));
const double m(std::numeric_limits<double>::min());
ASSERT_TRUE(lessEq(Point(m+half_eps,m,m),Point(m,m,m)));
ASSERT_TRUE(lessEq(Point(m,m+half_eps,m),Point(m,m,m)));
ASSERT_TRUE(lessEq(Point(m,m,m+half_eps),Point(m,m,m)));
ASSERT_TRUE(lessEq(Point(m,m,m),Point(m+half_eps,m,m)));
ASSERT_TRUE(lessEq(Point(m,m,m),Point(m,m+half_eps,m)));
ASSERT_TRUE(lessEq(Point(m,m,m),Point(m,m,m+half_eps)));
const double zero(0.0);
ASSERT_TRUE(lessEq(Point(zero+half_eps,zero,zero),Point(zero,zero,zero)));
ASSERT_TRUE(lessEq(Point(zero,zero+half_eps,zero),Point(zero,zero,zero)));
ASSERT_TRUE(lessEq(Point(zero,zero,zero+half_eps),Point(zero,zero,zero)));
ASSERT_TRUE(lessEq(Point(zero,zero,zero),Point(zero+half_eps,zero,zero)));
ASSERT_TRUE(lessEq(Point(zero,zero,zero),Point(zero,zero+half_eps,zero)));
ASSERT_TRUE(lessEq(Point(zero,zero,zero),Point(zero,zero,zero+half_eps)));
ASSERT_TRUE(lessEq(Point(m+half_eps,m,m),Point(zero,zero,zero)));
ASSERT_TRUE(lessEq(Point(m,m+half_eps,m),Point(zero,zero,zero)));
ASSERT_TRUE(lessEq(Point(m,m,m+half_eps),Point(zero,zero,zero)));
ASSERT_TRUE(lessEq(Point(m,m,m),Point(zero+half_eps,zero,zero)));
ASSERT_TRUE(lessEq(Point(m,m,m),Point(zero,zero+half_eps,zero)));
ASSERT_TRUE(lessEq(Point(m,m,m),Point(zero,zero,zero+half_eps)));
ASSERT_TRUE(lessEq(Point(zero+half_eps,zero,zero),Point(m,m,m)));
ASSERT_TRUE(lessEq(Point(zero,zero+half_eps,zero),Point(m,m,m)));
ASSERT_TRUE(lessEq(Point(zero,zero,zero+half_eps),Point(m,m,m)));
ASSERT_TRUE(lessEq(Point(zero,zero,zero),Point(m+half_eps,m,m)));
ASSERT_TRUE(lessEq(Point(zero,zero,zero),Point(m,m+half_eps,m)));
ASSERT_TRUE(lessEq(Point(zero,zero,zero),Point(m,m,m+half_eps)));
ASSERT_TRUE(lessEq(Point(half_eps+half_eps,half_eps,half_eps),Point(half_eps,half_eps,half_eps)));
ASSERT_TRUE(lessEq(Point(half_eps,half_eps+half_eps,zero),Point(half_eps,half_eps,half_eps)));
ASSERT_TRUE(lessEq(Point(zero,zero,zero+half_eps),Point(half_eps,half_eps,half_eps)));
ASSERT_TRUE(lessEq(Point(half_eps,half_eps,half_eps),Point(half_eps+half_eps,half_eps,half_eps)));
ASSERT_TRUE(lessEq(Point(half_eps,half_eps,half_eps),Point(half_eps,half_eps+half_eps,half_eps)));
ASSERT_TRUE(lessEq(Point(half_eps,half_eps,half_eps),Point(half_eps,half_eps,half_eps+half_eps)));
ASSERT_TRUE(lessEq(Point(10.0+half_eps,10.0,10.0),Point(10.0,10.0,10.0)));
ASSERT_TRUE(lessEq(Point(10.0,10.0+half_eps,10.0),Point(10.0,10.0,10.0)));
ASSERT_TRUE(lessEq(Point(10.0,10.0,10.0+half_eps),Point(10.0,10.0,10.0)));
ASSERT_TRUE(lessEq(Point(10.0,10.0,10.0),Point(10.0+half_eps,10.0,10.0)));
ASSERT_TRUE(lessEq(Point(10.0,10.0,10.0),Point(10.0,10.0+half_eps,10.0)));
ASSERT_TRUE(lessEq(Point(10.0,10.0,10.0),Point(10.0,10.0,10.0+half_eps)));
}
TEST(GeoLib, PointComparisonOperatorLessEq)
{
const double my_eps(std::numeric_limits<double>::epsilon());
ASSERT_FALSE(Point(1.0+my_eps,1.0,1.0) <= Point(1.0,1.0,1.0));
ASSERT_FALSE(Point(1.0,1.0+my_eps,1.0) <= Point(1.0,1.0,1.0));
ASSERT_FALSE(Point(1.0,1.0,1.0+my_eps) <= Point(1.0,1.0,1.0));
ASSERT_TRUE(Point(1.0,1.0,1.0) <= Point(1.0+my_eps,1.0,1.0));
ASSERT_TRUE(Point(1.0,1.0,1.0) <= Point(1.0,1.0+my_eps,1.0));
ASSERT_TRUE(Point(1.0,1.0,1.0) <= Point(1.0,1.0,1.0+my_eps));
ASSERT_TRUE(Point(1.0-my_eps,1.0,1.0) <= Point(1.0,1.0,1.0));
ASSERT_TRUE(Point(1.0,1.0-my_eps,1.0) <= Point(1.0,1.0,1.0));
ASSERT_TRUE(Point(1.0,1.0,1.0-my_eps) <= Point(1.0,1.0,1.0));
ASSERT_FALSE(Point(1.0,1.0,1.0) <= Point(1.0-my_eps,1.0,1.0));
ASSERT_FALSE(Point(1.0,1.0,1.0) <= Point(1.0,1.0-my_eps,1.0));
ASSERT_FALSE(Point(1.0,1.0,1.0) <= Point(1.0,1.0,1.0-my_eps));
std::size_t n(10000);
srand ( time(NULL) );
for (std::size_t k(0); k<n; ++k) {
double random_val_x(((double)(rand()) / RAND_MAX - 0.5)); //real_dist(rng));
double random_val_y(((double)(rand()) / RAND_MAX - 0.5)); //real_dist(rng));
double random_val_z(((double)(rand()) / RAND_MAX - 0.5)); //real_dist(rng));
double big_x(random_val_x * std::numeric_limits<double>::max());
double big_y(random_val_y * std::numeric_limits<double>::max());
double big_z(random_val_z * std::numeric_limits<double>::max());
ASSERT_TRUE(Point(big_x-my_eps,big_y,big_z) <= Point(big_x,big_y,big_z));
ASSERT_TRUE(Point(big_x,big_y-my_eps,big_z) <= Point(big_x,big_y,big_z));
ASSERT_TRUE(Point(big_x,big_y,big_z-my_eps) <= Point(big_x,big_y,big_z));
ASSERT_TRUE(Point(big_x-my_eps,big_y-my_eps,big_z) <= Point(big_x,big_y,big_z));
ASSERT_TRUE(Point(big_x-my_eps,big_y,big_z-my_eps) <= Point(big_x,big_y,big_z));
ASSERT_TRUE(Point(big_x,big_y-my_eps,big_z-my_eps) <= Point(big_x,big_y,big_z));
ASSERT_TRUE(Point(big_x-my_eps,big_y-my_eps,big_z-my_eps) <= Point(big_x,big_y,big_z));
double small_x(random_val_x * std::numeric_limits<double>::epsilon());
double small_y(random_val_y * std::numeric_limits<double>::epsilon());
double small_z(random_val_z * std::numeric_limits<double>::epsilon());
ASSERT_TRUE(Point(small_x-my_eps,small_y,small_z) <= Point(small_x,small_y,small_z));
ASSERT_TRUE(Point(small_x,small_y-my_eps,small_z) <= Point(small_x,small_y,small_z));
ASSERT_TRUE(Point(small_x,small_y,small_z-my_eps) <= Point(small_x,small_y,small_z));
ASSERT_TRUE(Point(small_x-my_eps,small_y-my_eps,small_z) <= Point(small_x,small_y,small_z));
ASSERT_TRUE(Point(small_x-my_eps,small_y,small_z-my_eps) <= Point(small_x,small_y,small_z));
ASSERT_TRUE(Point(small_x,small_y-my_eps,small_z-my_eps) <= Point(small_x,small_y,small_z));
ASSERT_TRUE(Point(small_x-my_eps,small_y-my_eps,small_z-my_eps) <= Point(small_x,small_y,small_z));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment