Program Listing for File geom_point.h¶
↰ Return to documentation for file (src/rlenvs/utils/geometry/geom_point.h)
#ifndef GEOM_POINT_H
#define GEOM_POINT_H
#include "rlenvs/rlenvs_types_v2.h"
#include <vector>
#include <array>
#include <cmath>
#include <ostream>
#include <algorithm>
#include <string>
namespace rlenvscpp{
namespace utils{
namespace geom{
template<int spacedim, typename T=real_t>
class GeomPoint
{
public:
typedef T value_type;
static const int dimension = spacedim;
explicit GeomPoint(T val = T());
template<typename Container>
explicit GeomPoint(const Container& data);
GeomPoint(const std::initializer_list<T>& list);
GeomPoint(const GeomPoint& t);
GeomPoint& operator=(const GeomPoint& t);
virtual ~GeomPoint(){}
GeomPoint & operator += (const GeomPoint &);
GeomPoint & operator -= (const GeomPoint &);
GeomPoint & operator *= (T factor);
GeomPoint & operator /= (T factor);
GeomPoint& operator=(const std::initializer_list<T>& list);
void scale(T factor);
void scale(const std::vector<T>& factors);
void zero();
void add_scaled(const GeomPoint& p, T factor);
T& operator[](uint_t i);
T operator[](uint_t i)const;
T entry(uint_t i)const{return (*this)[i];}
auto coordinates()const{return data_;}
T max()const;
T min()const;
T distance(const GeomPoint&)const;
T L2_norm()const{return distance(GeomPoint(static_cast<T>(0)));}
T dot(const GeomPoint& other)const;
T square_sum()const;
std::ostream& print_point_info(std::ostream &out)const;
const std::string to_string()const;
private:
std::array<T, spacedim> data_;
};
template<int spacedim,typename T>
inline
GeomPoint<spacedim,T>::GeomPoint(T val)
:
data_()
{
std::for_each(data_.begin(), data_.end(), [=](T& item){item = val;});
}
template<int spacedim,typename T>
template<typename Container>
inline
GeomPoint<spacedim,T>::GeomPoint(const Container& data)
:
data_()
{
for(uint_t i=0; i<data_.size(); ++i){
data_[i] = data[i];
}
}
template<int spacedim,typename T>
GeomPoint<spacedim,T>::GeomPoint(const std::initializer_list<T>& list)
:
data_()
{
if(list.size() != spacedim){
std::string msg;
msg += "Invalid initialization ";
msg += " list size for point construction. "+ std::to_string(list.size());
msg += " not equal to "+std::to_string(spacedim);
throw std::logic_error(msg);
}
auto start = list.begin();
auto end = list.end();
uint_t i = 0;
for(; start != end; ++start){
data_[i++] = *start;
}
}
template<int spacedim,typename T>
inline
GeomPoint<spacedim,T>::GeomPoint(const GeomPoint<spacedim,T>& t)
:
data_(t.data_)
{}
template<int spacedim,typename T>
inline
GeomPoint<spacedim,T>&
GeomPoint<spacedim,T>::operator=(const GeomPoint<spacedim, T>& t){
if(this==&t) {
return *this;
}
data_ = t.data_;
return *this;
}
template<int spacedim,typename T>
inline
T&
GeomPoint<spacedim,T>::operator[](uint_t i){
return data_[i];
}
template<int spacedim,typename T>
inline
T
GeomPoint<spacedim,T>::operator[](uint_t i)const{
return data_[i];
}
template<int spacedim,typename T>
inline
GeomPoint<spacedim,T>&
GeomPoint<spacedim,T>::operator += (const GeomPoint<spacedim,T> & t){
for(int i=0; i<spacedim; ++i){
data_[i] += t.data_[i];
}
return *this;
}
template<int spacedim,typename T>
inline
GeomPoint<spacedim,T>&
GeomPoint<spacedim,T>::operator -= (const GeomPoint<spacedim,T> & t){
for(int i=0; i<spacedim; ++i){
data_[i] -= t.data_[i];
}
return *this;
}
template<int spacedim,typename T>
inline
GeomPoint<spacedim,T>&
GeomPoint<spacedim,T>::operator *= (T factor){
for(int i=0; i<spacedim; ++i){
data_[i] *= factor;
}
return *this;
}
template<int spacedim,typename T>
inline
GeomPoint<spacedim,T> &
GeomPoint<spacedim,T>::operator /= (T factor){
(*this) *= (static_cast<T>(1)/factor);
return *this;
}
template<int spacedim,typename T>
inline
GeomPoint<spacedim, T>&
GeomPoint<spacedim,T>::operator=(const std::initializer_list<T>& list){
if(list.size() != spacedim){
std::string msg;
msg += "Invalid initialization ";
msg += " list size for point construction. "+ std::to_string(list.size());
msg += " not equal to "+std::to_string(spacedim);
throw std::logic_error(msg);
}
auto start = list.begin();
auto end = list.end();
uint_t i = 0;
for(; start != end; ++start){
data_[i++] = *start;
}
return *this;
}
template<int spacedim,typename T>
inline
void
GeomPoint<spacedim,T>::add_scaled(const GeomPoint<spacedim,T>& p, T factor){
for(int i=0; i<spacedim; ++i){
data_[i] += p.data_[i]*factor;
}
}
template<int spacedim,typename T>
T
GeomPoint<spacedim,T>::max()const{
T max_val = data_[0];
for(int i=1; i < spacedim; ++i){
max_val = std::max(max_val,data_[i]);
}
return max_val;
}
template<int spacedim,typename T>
T
GeomPoint<spacedim,T>::min()const{
T min_val = data_[0];
for(int i=1; i<spacedim; ++i){
min_val = std::min(min_val,data_[i]);
}
return min_val;
}
template<int spacedim,typename T>
T
GeomPoint<spacedim,T>::distance(const GeomPoint<spacedim,T>& p)const{
T sum = T();
auto data = p.coordinates();
for(int i=0; i<spacedim; ++i)
sum += (data_[i]-data[i])*(data_[i]-data[i]);
return std::sqrt(sum);
}
template<int spacedim,typename T>
void
GeomPoint<spacedim,T>::scale(const std::vector<T>& factors){
for(int i=0; i<spacedim; ++i){
data_[i] *= factors[i];
}
}
template<int spacedim,typename T>
T
GeomPoint<spacedim,T>::square_sum()const{
T result = T(0);
std::for_each(data_.begin(), data_.end(),
[&](const T& value){
result += value*value;
});
return result;
}
template<int spacedim,typename T>
T
GeomPoint<spacedim,T>::dot(const GeomPoint<spacedim, T>& other)const{
T result = (*this)[0]*other[0];
for(uint_t i = 1; i<spacedim; ++i){
result += (*this)[i]*other[i];
}
return result;
}
template<int spacedim,typename T>
inline
void
GeomPoint<spacedim,T>::zero(){
for(int i=0; i<spacedim; ++i)
data_[i] = T();
}
template<int spacedim,typename T>
inline
std::ostream&
GeomPoint<spacedim,T>::print_point_info(std::ostream &out)const
{
out<<"( ";
for(int i=0; i<spacedim; ++i){
out<<data_[i];
if(i<spacedim-1){
out<<",";
}
}
out<<" )";
return out;
}
template<int spacedim,typename T>
const std::string
GeomPoint<spacedim,T>::to_string()const{
std::string rslt("");
auto end = data_.begin();
std::advance(end, spacedim-1);
std::for_each(data_.begin(), end,
[&](const T& value){
rslt += std::to_string(value);
rslt +=",";
});
rslt += std::to_string(data_[spacedim - 1]);
return rslt;
}
template<int spacedim,typename T>
inline
std::ostream & operator << (std::ostream &out, const GeomPoint<spacedim,T> &p){
return p.print_point_info(out);
}
template<int spacedim,typename T>
const GeomPoint<spacedim,T> scale(const GeomPoint<spacedim,T>& t, T factor){
return (GeomPoint<spacedim,T>(t)*=factor);
}
template<int spacedim,typename T>
const GeomPoint<spacedim,T> scale(const GeomPoint<spacedim,T>& t, const std::vector<T>& factors){
auto data = t.data();
for(int i=0; i<spacedim; ++i)
data[i] *= factors[i];
return GeomPoint<spacedim,T>(data);
}
template<int spacedim,typename T>
const GeomPoint<spacedim,T> abs(const GeomPoint<spacedim,T>& t){
auto data = t.coordinates();
for(int i=0; i<spacedim; ++i)
data[i] = std::abs(data[i]);
return GeomPoint<spacedim,T>(data);
}
template<int spacedim,typename T>
const GeomPoint<spacedim,T> operator*(T factor,const GeomPoint<spacedim,T>& t){
return (GeomPoint<spacedim,T>(t)*=factor);
}
template<int spacedim,typename T>
const GeomPoint<spacedim,T> operator*(const GeomPoint<spacedim,T>& t,T factor){
return (GeomPoint<spacedim,T>(t)*=factor);
}
template<int spacedim,typename T>
const GeomPoint<spacedim,T> operator/(const GeomPoint<spacedim,T>& t,T factor){
return (GeomPoint<spacedim,T>(t)/=factor);
}
template<int spacedim,typename T>
const GeomPoint<spacedim,T> operator+(const GeomPoint<spacedim,T>& t1, const GeomPoint<spacedim,T>& t2){
return (GeomPoint<spacedim,T>(t1) += t2);
}
template<int spacedim, typename T>
const GeomPoint<spacedim, T> operator-(const GeomPoint<spacedim,T>& t1, const GeomPoint<spacedim,T>& t2){
return (GeomPoint<spacedim,T>(t1) -= t2);
}
template<int spacedim, typename T>
bool operator==(const GeomPoint<spacedim,T>& t1, const GeomPoint<spacedim,T>& t2){
bool result=true;
for(int i=0; i<spacedim; ++i){
if(t1[i] != t2[i]){
result = false;
}
}
return result;
}
template<int spacedim,typename T>
bool operator!=(const GeomPoint<spacedim,T>& t1, const GeomPoint<spacedim,T>& t2){
return !(t1==t2);
}
}
}
}
#endif // GEOM_POINT_H