Skip to content

Latest commit

 

History

History
212 lines (121 loc) · 101 KB

CppCoordinat.md

File metadata and controls

212 lines (121 loc) · 101 KB

 

 

 

 

 

 

STLQt CreatorLubuntu

 

Coordinat is a class for a coordinat.

Technical facts

 

 

 

 

 

 

./CppCoordinat/CppCoordinat.pri

 


INCLUDEPATH += \     ../../Classes/CppCoordinat SOURCES += \     ../../Classes/CppCoordinat/coordinat.cpp \     ../../Classes/CppCoordinat/coordinat3d.cpp \     ../../Classes/CppCoordinat/coordinat2d.cpp \     ../../Classes/CppCoordinat/constcoordinat2d.cpp HEADERS  += \     ../../Classes/CppCoordinat/coordinat.h \     ../../Classes/CppCoordinat/coordinat3d.h \     ../../Classes/CppCoordinat/coordinat2d.h \     ../../Classes/CppCoordinat/constcoordinat2d.h OTHER_FILES += \     ../../Classes/CppCoordinat/Licence.txt

 

 

 

 

 

./CppCoordinat/constcoordinat2d.h

 


//--------------------------------------------------------------------------- /* Coordinat, coordinat classes Copyright 2013-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppCoordinat.htm //--------------------------------------------------------------------------- #ifndef RIBI_CONSTCOORDINAT2D_H #define RIBI_CONSTCOORDINAT2D_H //typedef boost::geometry::model::d2::point_xy<double> ConstCoordinat2D; #ifdef USE_CUSTOM_RIBI_CONSTCOORDINAT2D #include <array> #include <iosfwd> #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #include <boost/checked_delete.hpp> #include <boost/shared_ptr.hpp> #pragma GCC diagnostic pop namespace ribi { ///An immutable X-Y coordinat //Note: I dislike to write this class: I wish there was a library (STL, Boost) //with an alternative. struct ConstCoordinat2D {   ConstCoordinat2D(     const double x = 0.0,     const double y = 0.0   ) noexcept;   double GetX() const noexcept { return m_co[0]; }   double GetY() const noexcept { return m_co[1]; }   private:   ConstCoordinat2D(const ConstCoordinat2D&) = delete;   ConstCoordinat2D& operator=(const ConstCoordinat2D&) = delete;   virtual ~ConstCoordinat2D() noexcept {}   friend void boost::checked_delete<>(ConstCoordinat2D*);   friend void boost::checked_delete<>(const ConstCoordinat2D*);   static const int dimensionality = 2;   const std::array<double,dimensionality> m_co;   #ifndef NDEBUG   static void Test() noexcept;   #endif }; double Distance(const ConstCoordinat2D& lhs,const ConstCoordinat2D& rhs) noexcept; double DotProduct(   const boost::shared_ptr<const ConstCoordinat2D> v1,   const boost::shared_ptr<const ConstCoordinat2D> v2) noexcept; ///Distance to origin double Length(const boost::shared_ptr<const ConstCoordinat2D> v) noexcept; boost::shared_ptr<const ConstCoordinat2D> Scale(   const double scalar,   const boost::shared_ptr<const ConstCoordinat2D> v ) noexcept; bool operator==(const ConstCoordinat2D& lhs, const ConstCoordinat2D& rhs) noexcept; bool operator<(const ConstCoordinat2D& lhs, const ConstCoordinat2D& rhs) noexcept; std::ostream& operator<<(std::ostream& os, const ConstCoordinat2D& n) noexcept; boost::shared_ptr<const ConstCoordinat2D> operator+(   const boost::shared_ptr<const ConstCoordinat2D> v1,   const boost::shared_ptr<const ConstCoordinat2D> v2 ) noexcept; boost::shared_ptr<const ConstCoordinat2D> operator-(   const boost::shared_ptr<const ConstCoordinat2D> v1,   const boost::shared_ptr<const ConstCoordinat2D> v2 ) noexcept; } //~namespace ribi #endif #endif // RIBI_CONSTCOORDINAT2D_H

 

 

 

 

 

./CppCoordinat/constcoordinat2d.cpp

 


//--------------------------------------------------------------------------- /* Coordinat, coordinat classes Copyright 2013-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppCoordinat.htm //--------------------------------------------------------------------------- #ifdef USE_CUSTOM_RIBI_CONSTCOORDINAT2D #include "constcoordinat2d.h" #include <array> #include <iostream> #include "trace.h" #include "xml.h" ConstCoordinat2D::ConstCoordinat2D(const double x, const double y) noexcept   : m_co{ { x,y } } {   #ifndef NDEBUG   Test();   #endif } double ribi::DotProduct(   const boost::shared_ptr<const ConstCoordinat2D> v1,   const boost::shared_ptr<const ConstCoordinat2D> v2 ) noexcept {   return       ( v1->GetX() * v2->GetX())     + ( v1->GetY() * v2->GetY())   ; } double ribi::Distance(const ConstCoordinat2D& lhs,const ConstCoordinat2D& rhs) noexcept {   const double dx = lhs.GetX() - rhs.GetX();   const double dy = lhs.GetY() - rhs.GetY();   return std::sqrt(       (dx * dx)     + (dy * dy)   ); } double ribi::Length(const boost::shared_ptr<const ConstCoordinat2D> v) noexcept {   const double dx = v->GetX();   const double dy = v->GetY();   return std::sqrt((dx*dx)+(dy*dy)); } boost::shared_ptr<const ConstCoordinat2D> ribi::Scale(   const double scalar,   const boost::shared_ptr<const ConstCoordinat2D> v) noexcept {   const boost::shared_ptr<const ConstCoordinat2D> p(     new ConstCoordinat2D(       scalar * v->GetX(),       scalar * v->GetY()     )   );   assert(p);   return p; } #ifndef NDEBUG void ConstCoordinat2D::Test() noexcept {   {     static bool is_tested{false};     if (is_tested) return;     is_tested = true;   }   const TestTimer test_timer(__func__,__FILE__,1.0); } #endif boost::shared_ptr<const ConstCoordinat2D> ribi::operator-(   const boost::shared_ptr<const ConstCoordinat2D> v1,   const boost::shared_ptr<const ConstCoordinat2D> v2) noexcept {   const boost::shared_ptr<const ConstCoordinat2D> p(     new ConstCoordinat2D(       v1->GetX() - v2->GetX(),       v1->GetY() - v2->GetY()     )   );   assert(p);   return p; } boost::shared_ptr<const ConstCoordinat2D> ribi::operator+(   const boost::shared_ptr<const ConstCoordinat2D> v1,   const boost::shared_ptr<const ConstCoordinat2D> v2) noexcept {   const boost::shared_ptr<const ConstCoordinat2D> p(     new ConstCoordinat2D(       v1->GetX() + v2->GetX(),       v1->GetY() + v2->GetY()     )   );   assert(p);   return p; } bool ribi::operator==(const ConstCoordinat2D& lhs, const ConstCoordinat2D& rhs) noexcept {   return lhs.GetX() == rhs.GetX()       && lhs.GetY() == rhs.GetY(); } bool ribi::operator<(const ConstCoordinat2D& lhs, const ConstCoordinat2D& rhs) noexcept {   if (lhs.GetX() < rhs.GetX()) return true;   if (lhs.GetX() > rhs.GetX()) return false;   if (lhs.GetY() < rhs.GetY()) return true;   if (lhs.GetY() > rhs.GetY()) return false;   return false; } std::ostream& ribi::operator<<(std::ostream& os, const ConstCoordinat2D& n) noexcept {   std::stringstream s;   s     << ribi::xml::ToXml("x",n.GetX())     << ribi::xml::ToXml("y",n.GetY())   ;   os << ribi::xml::ToXml("coordinat2d",s.str());   return os; } #endif

 

 

 

 

 

./CppCoordinat/coordinat.h

 


//--------------------------------------------------------------------------- /* Coordinat, coordinat classes Copyright 2013-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppCoordinat.htm //--------------------------------------------------------------------------- #ifndef RIBI_COORDINAT_H #define RIBI_COORDINAT_H #ifdef USE_CUSTOM_RIBI_COORDINAT #include <cassert> #include "trace.h" ///A normal (x,y) coordinat template <class Length> struct Coordinat {   explicit Coordinat(const Length& x, const Length& y) noexcept;   const Length& GetX() const noexcept { return m_x; }   const Length& GetY() const noexcept { return m_y; }   void Translate(const Length& dx, const Length& dy) noexcept;   void Translate(const Coordinat& delta) noexcept;   private:   Length m_x;   Length m_y;   #ifndef NDEBUG   static void Test() noexcept;   #endif }; template <class Length> Coordinat::Coordinat(const Length& x, const Length& y) noexcept   : m_x { x },     m_y { y } {   #ifndef NDEBUG   Test();   #endif } template <class Length> void Coordinat::Translate(const Coordinat& delta) noexcept {   Translate(delta.GetX(),delta.GetY()); } template <class Length> void Coordinat::Translate(const Length& dx, const Length& dy) noexcept {   m_x += dx;   m_y += dy; } template <class Length> Coordinat operator+(const Coordinat& lhs, const Coordinat& rhs) noexcept {   return Coordinat(     lhs.GetX() + rhs.GetX(),     lhs.GetY() + rhs.GetY()   ); } template <class Length> bool operator==(const Coordinat& lhs, const Coordinat& rhs) noexcept {   return lhs.GetX() == rhs.GetX()       && lhs.GetY() == rhs.GetY(); } #ifndef NDEBUG template <class Length> void Coordinat::Test() noexcept {   {     static bool is_tested { false };     if (is_tested) return;     is_tested = true;   }   const TestTimer test_timer(__func__,__FILE__,1.0);   {     const Coordinat<double> a(0.0,0.0);     const Coordinat<double> b(0.0,0.0);     assert(a == b);     const Coordinat<double> c(a);   } } #endif #endif // USE_CUSTOM_RIBI_COORDINAT #endif // RIBI_COORDINAT_H

 

 

 

 

 

./CppCoordinat/coordinat.cpp

 


//--------------------------------------------------------------------------- /* Coordinat, coordinat classes Copyright 2013-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppCoordinat.htm //--------------------------------------------------------------------------- #ifdef USE_CUSTOM_RIBI_COORDINAT #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #pragma GCC diagnostic ignored "-Wunused-but-set-parameter" #include "coordinat.h" #pragma GCC diagnostic pop #endif // USE_CUSTOM_RIBI_COORDINAT

 

 

 

 

 

./CppCoordinat/coordinat2d.h

 


//--------------------------------------------------------------------------- /* Coordinat, coordinat classes Copyright 2013-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppCoordinat.htm //--------------------------------------------------------------------------- #ifndef RIBI_COORDINAT2D_H #define RIBI_COORDINAT2D_H //typedef boost::geometry::model::d2::point_xy<double> Coordinat2D; #ifdef USE_CUSTOM_RIBI_COORDINAT2D #include <array> #include <iosfwd> #include <vector> namespace ribi { ///An X-Y coordinat //Note: I dislike to write this class: I wish there was a library (STL, Boost) //with an alternative. struct Coordinat2D {   Coordinat2D(     const double x = 0.0,     const double y = 0.0   ) noexcept;   void ChangeX(const double dx) noexcept { m_co[0] += dx; }   void ChangeY(const double dy) noexcept { m_co[1] += dy; }   double GetX() const noexcept { return m_co[0]; }   double GetY() const noexcept { return m_co[1]; }   void SetX(const double x) noexcept { m_co[0] = x; }   void SetY(const double y) noexcept { m_co[1] = y; }   Coordinat2D& operator+=(const Coordinat2D& rhs) noexcept;   Coordinat2D& operator-=(const Coordinat2D& rhs) noexcept;   private:   static const int dimensionality = 2;   std::array<double,dimensionality> m_co;   #ifndef NDEBUG   static void Test() noexcept;   #endif }; bool operator==(const Coordinat2D& lhs, const Coordinat2D& rhs) noexcept; bool operator<(const Coordinat2D& lhs, const Coordinat2D& rhs) noexcept; std::ostream& operator<<(std::ostream& os, const Coordinat2D& n) noexcept; ///The dot product double operator*(const Coordinat2D& v1,const Coordinat2D& v2) noexcept; ///Calculate the point in the center of the collection of points Coordinat2D CalcCenter(const std::vector<Coordinat2D>& points) noexcept; double Distance(const Coordinat2D& lhs,const Coordinat2D& rhs) noexcept; ///Distance to origin double Length(const Coordinat2D& v) noexcept; Coordinat2D Scale(   const double scalar,   const Coordinat2D& v ) noexcept; Coordinat2D operator+(   const Coordinat2D& v1,   const Coordinat2D& v2) noexcept; Coordinat2D operator*(   const double scalar,   const Coordinat2D& v) noexcept; Coordinat2D operator-(   const Coordinat2D& v1,   const Coordinat2D& v2) noexcept; } //~namespace ribi #endif #endif // RIBI_COORDINAT2D_H

 

 

 

 

 

./CppCoordinat/coordinat2d.cpp

 


//--------------------------------------------------------------------------- /* Coordinat, coordinat classes Copyright 2013-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppCoordinat.htm //--------------------------------------------------------------------------- #ifdef USE_CUSTOM_RIBI_COORDINAT3D #include "coordinat2d.h" #include <array> #include <iostream> #include "trace.h" #include "xml.h" ribi::Coordinat2D::Coordinat2D(const double x, const double y) noexcept   : m_co{ { x,y } } {   #ifndef NDEBUG   Test();   #endif } //ribi::Coordinat2D::Coordinat2D(const Coordinat2D& rhs) //  : m_co{ { rhs.GetX(), rhs.GetY() } } //{ //  assert(*this == rhs); //} //ribi::Coordinat2D& ribi::Coordinat2D::operator=(const Coordinat2D& rhs) //{ //  m_co = { rhs.GetX(), rhs.GetY() }; //  assert(*this == rhs); //  return *this; //} ribi::Coordinat2D& ribi::Coordinat2D::operator+=(const Coordinat2D& rhs) noexcept {   m_co[0] += rhs.GetX();   m_co[1] += rhs.GetY();   return *this; } ribi::Coordinat2D& ribi::Coordinat2D::operator-=(const Coordinat2D& rhs) noexcept {   m_co[0] -= rhs.GetX();   m_co[1] -= rhs.GetY();   return *this; } double ribi::operator*(const Coordinat2D& v1,const Coordinat2D& v2) noexcept {   return       ( v1.GetX() * v2.GetX())     + ( v1.GetY() * v2.GetY())   ; } ribi::Coordinat2D ribi::CalcCenter(const std::vector<ribi::Coordinat2D>& points) noexcept {   Coordinat2D sum;   for (const auto& point: points)   {     sum += point;   }   const double n { static_cast<double>(points.size()) };   const Coordinat2D center(     sum.GetX() / n,     sum.GetY() / n   );   return center; } double ribi::Distance(const Coordinat2D& lhs,const Coordinat2D& rhs) noexcept {   const double dx = lhs.GetX() - rhs.GetX();   const double dy = lhs.GetY() - rhs.GetY();   return std::sqrt(       (dx * dx)     + (dy * dy)   ); } double ribi::Length(const Coordinat2D& v) noexcept {   return std::sqrt( (v.GetX() * v.GetX()) + (v.GetY() * v.GetY())); } ribi::Coordinat2D ribi::Scale(   const double scalar,   const ribi::Coordinat2D& v ) noexcept {   assert(scalar != 0.0);   const ribi::Coordinat2D c(     v.GetX() / scalar,     v.GetY() / scalar   );   return c; } #ifndef NDEBUG void ribi::Coordinat2D::Test() noexcept {   {     static bool is_tested{false};     if (is_tested) return;     is_tested = true;   }   const TestTimer test_timer(__func__,__FILE__,1.0); } #endif ribi::Coordinat2D ribi::operator-(   const Coordinat2D& v1,   const Coordinat2D& v2) noexcept {   return {     v1.GetX()-v2.GetX(),     v1.GetY()-v2.GetY()   }; } ribi::Coordinat2D ribi::operator+(   const Coordinat2D& v1,   const Coordinat2D& v2) noexcept {   return {     v1.GetX()+v2.GetX(),     v1.GetY()+v2.GetY()   }; } ribi::Coordinat2D ribi::operator*(   const double scalar,   const Coordinat2D& v) noexcept {   return Coordinat2D(     scalar * v.GetX(),     scalar * v.GetY()   ); } bool ribi::operator==(const Coordinat2D& lhs, const Coordinat2D& rhs) noexcept {   return lhs.GetX() == rhs.GetX()     && lhs.GetY() == rhs.GetY(); } bool ribi::operator<(const Coordinat2D& lhs, const Coordinat2D& rhs) noexcept {   if (lhs.GetX() < rhs.GetX()) return true;   if (lhs.GetX() > rhs.GetX()) return false;   if (lhs.GetY() < rhs.GetY()) return true;   if (lhs.GetY() > rhs.GetY()) return false;   return false; } std::ostream& ribi::operator<<(std::ostream& os, const Coordinat2D& n) noexcept {   std::stringstream s;   s     << ribi::xml::ToXml("x",n.GetX())     << ribi::xml::ToXml("y",n.GetY())   ;   os << ribi::xml::ToXml("coordinat2d",s.str());   return os; } #endif

 

 

 

 

 

./CppCoordinat/coordinat3d.h

 


//--------------------------------------------------------------------------- /* Coordinat, coordinat classes Copyright 2013-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppCoordinat.htm //--------------------------------------------------------------------------- #ifndef RIBI_COORDINAT3D_H #define RIBI_COORDINAT3D_H //typedef boost::geometry::model::point<double,3,boost::geometry::cs::cartesian> Coordinat3D; #ifdef USE_CUSTOM_RIBI_COORDINAT3D #include <array> #include <iosfwd> #include <vector> #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #include <boost/geometry.hpp> #include <boost/geometry/geometries/point_xy.hpp> #ifndef _WIN32 #include <boost/geometry/geometries/polygon.hpp> #endif #pragma GCC diagnostic pop namespace ribi { ///An X-Y-Z coordinat //Note: I dislike to write this class: I wish there was a library (STL, Boost) //with an alternative. struct Coordinat3D {   explicit Coordinat3D(     const double x = 0.0,     const double y = 0.0,     const double z = 0.0   ) noexcept;   explicit Coordinat3D(     const boost::geometry::model::point<double,3,boost::geometry::cs::cartesian>& p   ) noexcept   : Coordinat3D(     boost::geometry::get<0>(p),     boost::geometry::get<1>(p),     boost::geometry::get<2>(p)   ) {}   void ChangeX(const double dx) noexcept { m_co[0] += dx; }   void ChangeY(const double dy) noexcept { m_co[1] += dy; }   void ChangeZ(const double dz) noexcept { m_co[2] += dz; }   std::string GetVersion() const noexcept;   std::vector<std::string> GetVersionHistory() const noexcept;   double GetX() const noexcept { return m_co[0]; }   double GetY() const noexcept { return m_co[1]; }   double GetZ() const noexcept { return m_co[2]; }   void SetX(const double x) noexcept { m_co[0] = x; }   void SetY(const double y) noexcept { m_co[1] = y; }   void SetZ(const double z) noexcept { m_co[2] = z; }   boost::geometry::model::point<double,3,boost::geometry::cs::cartesian>     ToBoostGeometryPoint() const noexcept   {     return boost::geometry::model::point<double,3,boost::geometry::cs::cartesian>(       m_co[0],m_co[1],m_co[2]     );   }   Coordinat3D& operator+=(const Coordinat3D& rhs) noexcept;   Coordinat3D& operator-=(const Coordinat3D& rhs) noexcept;   Coordinat3D& operator/=(const double f);   Coordinat3D& operator*=(const double f) noexcept;   private:   static const int dimensionality = 3;   std::array<double,dimensionality> m_co;   #ifndef NDEBUG   static void Test() noexcept;   #endif }; bool operator==(const Coordinat3D& lhs, const Coordinat3D& rhs) noexcept; bool operator<(const Coordinat3D& lhs, const Coordinat3D& rhs) noexcept; std::ostream& operator<<(std::ostream& os, const Coordinat3D& n) noexcept; Coordinat3D operator-(   const Coordinat3D& v1,   const Coordinat3D& v2) noexcept; Coordinat3D operator+(   const Coordinat3D& v1,   const Coordinat3D& v2) noexcept; ///Divide all components of the coordinat by f Coordinat3D operator/(   const Coordinat3D& c,   const double f); ///Multiply all components of the coordinat by f Coordinat3D operator*(   const Coordinat3D& c,   const double f) noexcept; ///Calculate the point in the center of the collection of points Coordinat3D CalcCenter(const std::vector<Coordinat3D>& points) noexcept; ///Calculate the cross product Coordinat3D CalcCrossProduct(   const Coordinat3D& a,   const Coordinat3D& b ) noexcept; ///Calculate the cross product double CalcDotProduct(   const Coordinat3D& a,   const Coordinat3D& b ) noexcept; ///Calculate the normal of a triangle ///The normal will be (0,0,-1) if a,b and c lie in the XY plane and ordered clockwise (when viewed from above) ///The normal will be (0,0, 1) if a,b and c lie in the XY plane and ordered counter-clockwise (when viewed from above) ///I use this convention as it appears to be used most extensively Coordinat3D CalcNormal(   const Coordinat3D& a,   const Coordinat3D& b,   const Coordinat3D& c ) noexcept; ///Calculate the distance between two coordinats double Distance(const Coordinat3D& lhs,const Coordinat3D& rhs) noexcept; ///When viewing a coordinat as a vector from origin, calculate its length double Length(const Coordinat3D& v) noexcept; } //~namespace ribi #endif #endif // RIBI_COORDINAT3D_H

 

 

 

 

 

./CppCoordinat/coordinat3d.cpp

 


//--------------------------------------------------------------------------- /* Coordinat, coordinat classes Copyright 2013-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppCoordinat.htm //--------------------------------------------------------------------------- #ifdef USE_CUSTOM_RIBI_COORDINAT3D #include "coordinat3d.h" #include <array> #include <cmath> #include "trace.h" #include "xml.h" Coordinat3D::Coordinat3D(const double x, const double y, const double z) noexcept   : m_co{ { x,y,z } } {   #ifndef NDEBUG   Test();   #endif } std::string Coordinat3D::GetVersion() const noexcept {   return "1.1"; } std::vector<std::string> Coordinat3D::GetVersionHistory() const noexcept {   return {     "201x-xx-xx: version 1.0: initial version"     "2014-03-07: version 1.1: initial versioning"   }; } Coordinat3D& Coordinat3D::operator+=(const Coordinat3D& rhs) noexcept {   m_co[0] += rhs.GetX();   m_co[1] += rhs.GetY();   m_co[2] += rhs.GetZ();   return *this; } Coordinat3D& Coordinat3D::operator-=(const Coordinat3D& rhs) noexcept {   m_co[0] -= rhs.GetX();   m_co[1] -= rhs.GetY();   m_co[2] -= rhs.GetZ();   return *this; } Coordinat3D& Coordinat3D::operator/=(const double f) {   assert(f != 0.0);   m_co[0] /= f;   m_co[1] /= f;   m_co[2] /= f;   return *this; } Coordinat3D& Coordinat3D::operator*=(const double f) noexcept {   m_co[0] *= f;   m_co[1] *= f;   m_co[2] *= f;   return *this; } Coordinat3D ribi::CalcCenter(const std::vector<Coordinat3D>& points) noexcept {   Coordinat3D sum;   for (const auto& point: points)   {     sum += point;   }   const double n { static_cast<double>(points.size()) };   const Coordinat3D center(     sum.GetX() / n,     sum.GetY() / n,     sum.GetZ() / n   );   return center; } Coordinat3D ribi::CalcCrossProduct(   const Coordinat3D& a,   const Coordinat3D& b ) noexcept {   return Coordinat3D(     (a.GetY() * b.GetZ()) - (a.GetZ() * b.GetY()),     (a.GetZ() * b.GetX()) - (a.GetX() * b.GetZ()),     (a.GetX() * b.GetY()) - (a.GetY() * b.GetX())   ); } double ribi::CalcDotProduct(   const Coordinat3D& a,   const Coordinat3D& b ) noexcept {   return       (a.GetX() * b.GetX())     + (a.GetY() * b.GetY())     + (a.GetZ() * b.GetZ()); } Coordinat3D ribi::CalcNormal(   const Coordinat3D& a,   const Coordinat3D& b,   const Coordinat3D& c ) noexcept {   const Coordinat3D u { c - a};   const Coordinat3D v { b - a};   return CalcCrossProduct(u,v); } double ribi::Distance(const Coordinat3D& lhs,const Coordinat3D& rhs) noexcept {   const double dx = lhs.GetX() - rhs.GetX();   const double dy = lhs.GetY() - rhs.GetY();   const double dz = lhs.GetZ() - rhs.GetZ();   return std::sqrt(       (dx * dx)     + (dy * dy)     + (dz * dz)   ); } double ribi::Length(const Coordinat3D& v) noexcept {   return std::sqrt(       (v.GetX() * v.GetX())     + (v.GetY() * v.GetY())     + (v.GetZ() * v.GetZ())   ); } #ifndef NDEBUG void Coordinat3D::Test() noexcept {   {     static bool is_tested{false};     if (is_tested) return;     is_tested = true;   }   const TestTimer test_timer(__func__,__FILE__,1.0);   //CalcCenter, one Coordinat3D   {     assert(CalcCenter( { Coordinat3D() } ) == Coordinat3D());     assert(CalcCenter( { Coordinat3D(1.1,2.2) } ) == Coordinat3D(1.1,2.2));   }   //CalcCenter, three Coordinat3D   {     const Coordinat3D center {       CalcCenter(         {           Coordinat3D(0.0,1.0),           Coordinat3D(1.0,2.0),           Coordinat3D(2.0,3.0)         }       )     };     const Coordinat3D expected(1.0,2.0);     assert(std::abs(center.GetX() - expected.GetX()) < 0.0001);     assert(std::abs(center.GetY() - expected.GetY()) < 0.0001);     assert(std::abs(center.GetZ() - expected.GetZ()) < 0.0001);   }   //CalcCenter, three Coordinat3D   {     const Coordinat3D center {       CalcCenter(         {           Coordinat3D(-0.0,-1.0,2.0),           Coordinat3D(-1.0,-2.0,4.0),           Coordinat3D(-2.0,-3.0,6.0)         }       )     };     const Coordinat3D expected(-1.0,-2.0,4.0);     assert(std::abs(center.GetX() - expected.GetX()) < 0.0001);     assert(std::abs(center.GetY() - expected.GetY()) < 0.0001);     assert(std::abs(center.GetZ() - expected.GetZ()) < 0.0001);   }   //CalcCrossProduct, XY plane   {     //Follow https://en.wikipedia.org/wiki/Cross_product     //where     //- a     = {1.0,0.0, 0.0}     //-     b = {0.0,1.0, 0.0}     //- a * b = {0.0,0.0, 1.0}     //- b * a = {0.0,0.0,-1.0}     const Coordinat3D a(1.0,0.0,0.0);     const Coordinat3D b(0.0,1.0,0.0);     const Coordinat3D p1 { CalcCrossProduct(a,b) };     const Coordinat3D p1_expected(0.0,0.0,1.0);     const Coordinat3D p2 { CalcCrossProduct(b,a) };     const Coordinat3D p2_expected(0.0,0.0,-1.0);     assert(std::abs(p1.GetX() - p1_expected.GetX()) < 0.0001);     assert(std::abs(p1.GetY() - p1_expected.GetY()) < 0.0001);     assert(std::abs(p1.GetZ() - p1_expected.GetZ()) < 0.0001);     assert(std::abs(p2.GetX() - p2_expected.GetX()) < 0.0001);     assert(std::abs(p2.GetY() - p2_expected.GetY()) < 0.0001);     assert(std::abs(p2.GetZ() - p2_expected.GetZ()) < 0.0001);   }   //CalcDotProduct, XY plane   {     //From https://en.wikipedia.org/wiki/Dotproduct     const Coordinat3D a(1.0, 3.0,-5.0);     const Coordinat3D b(4.0,-2.0,-1.0);     const double p { CalcDotProduct(a,b) };     const double q { CalcDotProduct(b,a) };     const double e { 3.0 };     assert(std::abs(p - e) < 0.0001);     assert(std::abs(q - e) < 0.0001);     assert(std::abs(p - q) < 0.0001);   }   {     //From https://en.wikipedia.org/wiki/Dotproduct     //'In particular, if A and B are orthogonal, then [...] A dot b = 0'     const Coordinat3D a(1.0,0.0,0.0);     const Coordinat3D b(0.0,1.0,0.0);     const double p { CalcDotProduct(a,b) };     const double q { CalcDotProduct(b,a) };     const double e { 0.0 };     assert(std::abs(p - e) < 0.0001);     assert(std::abs(q - e) < 0.0001);     assert(std::abs(p - q) < 0.0001);   }   //CalcNormal, XY plane   {     /*        0 1 2 3      0 +------X        |      1 | A    (Z = 1)        | |\      2 | C-B        |      3 |        Y     */     const Coordinat3D normal {       CalcNormal(         Coordinat3D(1.0,1.0,-1.0), //A         Coordinat3D(2.0,2.0,-1.0), //B         Coordinat3D(1.0,2.0,-1.0)  //C       )     };     const Coordinat3D expected(0.0,0.0,-1.0);     assert(std::abs(normal.GetX() - expected.GetX()) < 0.0001);     assert(std::abs(normal.GetY() - expected.GetY()) < 0.0001);     assert(std::abs(normal.GetZ() - expected.GetZ()) < 0.0001);   }   //CalcNormal, XY plane   {     /*        0 1 2 3      0 +------X        |      1 | A    (Z = 1)        | |\      2 | B-C        |      3 |        Y     */     const Coordinat3D normal {       CalcNormal(         Coordinat3D(1.0,1.0,-1.0), //A         Coordinat3D(1.0,2.0,-1.0), //B         Coordinat3D(2.0,2.0,-1.0)  //C       )     };     const Coordinat3D expected(0.0,0.0,1.0);     assert(std::abs(normal.GetX() - expected.GetX()) < 0.0001);     assert(std::abs(normal.GetY() - expected.GetY()) < 0.0001);     assert(std::abs(normal.GetZ() - expected.GetZ()) < 0.0001);   } } #endif Coordinat3D ribi::operator-(   const Coordinat3D& v1,   const Coordinat3D& v2) noexcept {   return Coordinat3D(     v1.GetX()-v2.GetX(),     v1.GetY()-v2.GetY(),     v1.GetZ()-v2.GetZ()   ); } Coordinat3D ribi::operator+(   const Coordinat3D& v1,   const Coordinat3D& v2) noexcept {   return Coordinat3D(     v1.GetX()+v2.GetX(),     v1.GetY()+v2.GetY(),     v1.GetZ()+v2.GetZ()   ); } Coordinat3D ribi::operator/(   const Coordinat3D& c,   const double f) {   assert(f != 0.0);   return Coordinat3D(     c.GetX() / f,     c.GetY() / f,     c.GetZ() / f   ); } Coordinat3D ribi::operator*(   const Coordinat3D& c,   const double f) noexcept {   return Coordinat3D(     c.GetX() * f,     c.GetY() * f,     c.GetZ() * f   ); } bool ribi::operator==(const Coordinat3D& lhs, const Coordinat3D& rhs) noexcept {   return        lhs.GetX() == rhs.GetX()     && lhs.GetY() == rhs.GetY()     && lhs.GetZ() == rhs.GetZ(); } bool ribi::operator<(const Coordinat3D& lhs, const Coordinat3D& rhs) noexcept {   if (lhs.GetX() < rhs.GetX()) return true;   if (lhs.GetX() > rhs.GetX()) return false;   if (lhs.GetY() < rhs.GetY()) return true;   if (lhs.GetY() > rhs.GetY()) return false;   return lhs.GetZ() < rhs.GetZ(); } std::ostream& ribi::operator<<(std::ostream& os, const Coordinat3D& n) noexcept {   std::stringstream s;   s     << ribi::xml::ToXml("x",n.GetX())     << ribi::xml::ToXml("y",n.GetY())     << ribi::xml::ToXml("z",n.GetZ());   os << ribi::xml::ToXml("coordinat3d",s.str());   return os; } #endif