Advertisement
Guest User

Untitled

a guest
Mar 2nd, 2017
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // VectorTraits.h
  2. #pragma once
  3.  
  4. template <typename Vector>
  5. struct VectorTraits;
  6.  
  7. // QVector3DTraits.h
  8. #pragma once
  9.  
  10. #include "VectorTraits.h"
  11. #include <QVector3D>
  12.  
  13. template <>
  14. struct VectorTraits<QVector3D>{
  15.     using VectorType = QVector3D;
  16.     using RealType = float;
  17.  
  18.     static VectorType normalized(const VectorType &vec){
  19.         return vec.normalized();
  20.     }
  21.  
  22.     static RealType dotProduct(const VectorType &first, const VectorType &second){
  23.         return QVector3D::dotProduct(first, second);
  24.     }
  25.  
  26.     static VectorType crossProduct(const VectorType &first, const VectorType &second){
  27.         return QVector3D::crossProduct(first, second);
  28.     }
  29.  
  30.     static RealType length(const VectorType &vec){
  31.         return vec.length();
  32.     }
  33. };
  34.  
  35. // PlaneBase.h
  36. #pragma once
  37.  
  38. #include "TriangleBase.h"
  39. #include "VectorTraits.h"
  40. #include <cmath>
  41.  
  42. template <typename Vector, typename Traits = VectorTraits<Vector>>
  43. class PlaneBase{
  44. public:
  45.     using VectorType = typename Traits::VectorType;
  46.     using RealType = typename Traits::RealType;
  47.  
  48. public:
  49.     constexpr PlaneBase()
  50.         : normal_{1, 0, 0}
  51.         , constant_{}
  52.     {}
  53.  
  54.     constexpr explicit PlaneBase(const VectorType &vector, const RealType &constant = {})
  55.         : normal_{Traits::normalized(vector)}
  56.         , constant_{constant}
  57.     {}
  58.  
  59.     constexpr explicit PlaneBase(const TriangleBase<Vector, Traits> &triangle)
  60.         : normal_{triangle.normal()}
  61.         , constant_{-Traits::dotProduct(normal_, triangle.a())}
  62.     {}
  63.  
  64.     constexpr PlaneBase(const VectorType &point1, const VectorType &point2, const VectorType &point3)
  65.         : PlaneBase{TriangleBase<Vector, Traits>(point1, point2, point3)}
  66.     {}
  67.  
  68.     constexpr PlaneBase(const PlaneBase &) = default;
  69.     PlaneBase(PlaneBase &&) = default;
  70.     PlaneBase &operator = (const PlaneBase &) = default;
  71.     PlaneBase &operator = (PlaneBase &&) = default;
  72.  
  73.     constexpr VectorType normal() const {
  74.         return normal_;
  75.     }
  76.  
  77.     constexpr RealType constant() const {
  78.         return constant_;
  79.     }
  80.  
  81.     bool containsPoint(const VectorType &point) const{
  82.         constexpr RealType tolerance = static_cast<RealType>(0.00001);
  83.  
  84.         return std::abs(Traits::dotProduct(normal_, point) + constant_) <= tolerance;
  85.     }
  86.  
  87. private:
  88.     //Ax + By + Cy + D = 0
  89.     VectorType normal_; // {A, B, C}
  90.     RealType constant_; // D
  91. };
  92.  
  93. template <typename Vector, typename Traits = VectorTraits<Vector>>
  94. typename Traits::RealType dihedralAngle(const PlaneBase<Vector, Traits> &firstPlane, const PlaneBase<Vector, Traits> &secondPlane) {
  95.     return std::acos(Traits::dotProduct(firstPlane.normal(), secondPlane.normal()));
  96. }
  97.  
  98. // TriangleBase.h
  99. #pragma once
  100.  
  101. #include "VectorTraits.h"
  102. #include <array>
  103. #include <cmath>
  104.  
  105. constexpr size_t vertexCountPerTriangle = 3;
  106.  
  107. template <typename Vector, typename Traits = VectorTraits<Vector>>
  108. class TriangleBase{
  109.     enum {A, B, C};
  110. public:
  111.     using PointType = typename Traits::VectorType;
  112.     using RealType = typename Traits::RealType;
  113.  
  114. public:
  115.     TriangleBase()
  116.         : vertices_{}
  117.     {}
  118.  
  119.     TriangleBase (const TriangleBase &) = default;
  120.     TriangleBase (TriangleBase &&) = default;
  121.     TriangleBase &operator = (const TriangleBase &) = default;
  122.     TriangleBase &operator = (TriangleBase &&) = default;
  123.     ~TriangleBase() = default;
  124.  
  125.     TriangleBase(const PointType &point1, const PointType &point2, const PointType &point3)
  126.         : vertices_{point1, point2, point3}
  127.     {}
  128.  
  129.     TriangleBase(const std::array<PointType, vertexCountPerTriangle> &vertices)
  130.         : vertices_{vertices}
  131.     {}
  132.  
  133.     PointType a() const{
  134.         return vertices_[A];
  135.     }
  136.  
  137.     PointType b() const{
  138.         return vertices_[B];
  139.     }
  140.  
  141.     PointType c() const{
  142.         return vertices_[C];
  143.     }
  144.  
  145.     PointType ab() const{
  146.         return b() - a();
  147.     }
  148.  
  149.     PointType ac() const{
  150.         return c() - a();
  151.     }
  152.  
  153.     PointType bc() const{
  154.         return c() - b();
  155.     }
  156.  
  157.     PointType perpendicular() const{
  158.         return Traits::crossProduct(ab(), ac());
  159.     }
  160.  
  161.     PointType normal() const{
  162.         return Traits::normalized(perpendicular());
  163.     }
  164.  
  165.     PointType normal(const PointType &pointUnderPlane) const{
  166.         const PointType &result = normal();
  167.         //FIXME: исправить
  168.         if(pointUnderPlane.distanceToPlane(a(), b(), c()) > 0){
  169.             return -result;
  170.         }
  171.         else{
  172.             return result;
  173.         }
  174.     }
  175.  
  176.     bool isPointInside(const PointType &point) const{
  177.         const PointType &unitVectorFromAtoPoint = Traits::normalized(a() - point);
  178.         const PointType &unitVectorFromBtoPoint = Traits::normalized(b() - point);
  179.         const PointType &unitVectorFromCtoPoint = Traits::normalized(c() - point);
  180.  
  181.         const RealType cosAngle1 = Traits::dotProduct(unitVectorFromAtoPoint, unitVectorFromBtoPoint);
  182.         const RealType cosAngle2 = Traits::dotProduct(unitVectorFromBtoPoint, unitVectorFromCtoPoint);
  183.         const RealType cosAngle3 = Traits::dotProduct(unitVectorFromCtoPoint, unitVectorFromAtoPoint);
  184.  
  185.         const RealType angleSum = acos(cosAngle1) + acos(cosAngle2) + acos(cosAngle3);
  186.  
  187.         constexpr RealType tolerance = 1e-4;
  188.  
  189.         if (std::abs(angleSum - M_PI * 2) < tolerance && !qIsNaN(angleSum)){
  190.             return true;
  191.         }
  192.         return false;
  193.     }
  194.  
  195.     RealType square() const{
  196.         return Traits::length(Traits::crossProduct(ab(), ac())) / 2;
  197.     }
  198.  
  199.     PointType center() const{
  200.         return (a() + b() + c()) / 3;
  201.     }
  202.  
  203.     void shrink(RealType factor){
  204.         const PointType &center = this->center();
  205.         for (PointType &vertex: vertices_){
  206.             vertex += (center - vertex) * factor;
  207.         }
  208.     }
  209.  
  210.     TriangleBase shrinked(RealType factor) const
  211.     {
  212.         TriangleBase result(*this);
  213.         result.shrink(factor);
  214.         return result;
  215.     }
  216.  
  217.     void setAllPoints(const PointType &point){
  218.         vertices_.fill(point);
  219.     }
  220.  
  221.  
  222. private:
  223.     std::array<PointType, vertexCountPerTriangle> vertices_;
  224. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement