Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // VectorTraits.h
- #pragma once
- template <typename Vector>
- struct VectorTraits;
- // QVector3DTraits.h
- #pragma once
- #include "VectorTraits.h"
- #include <QVector3D>
- template <>
- struct VectorTraits<QVector3D>{
- using VectorType = QVector3D;
- using RealType = float;
- static VectorType normalized(const VectorType &vec){
- return vec.normalized();
- }
- static RealType dotProduct(const VectorType &first, const VectorType &second){
- return QVector3D::dotProduct(first, second);
- }
- static VectorType crossProduct(const VectorType &first, const VectorType &second){
- return QVector3D::crossProduct(first, second);
- }
- static RealType length(const VectorType &vec){
- return vec.length();
- }
- };
- // PlaneBase.h
- #pragma once
- #include "TriangleBase.h"
- #include "VectorTraits.h"
- #include <cmath>
- template <typename Vector, typename Traits = VectorTraits<Vector>>
- class PlaneBase{
- public:
- using VectorType = typename Traits::VectorType;
- using RealType = typename Traits::RealType;
- public:
- constexpr PlaneBase()
- : normal_{1, 0, 0}
- , constant_{}
- {}
- constexpr explicit PlaneBase(const VectorType &vector, const RealType &constant = {})
- : normal_{Traits::normalized(vector)}
- , constant_{constant}
- {}
- constexpr explicit PlaneBase(const TriangleBase<Vector, Traits> &triangle)
- : normal_{triangle.normal()}
- , constant_{-Traits::dotProduct(normal_, triangle.a())}
- {}
- constexpr PlaneBase(const VectorType &point1, const VectorType &point2, const VectorType &point3)
- : PlaneBase{TriangleBase<Vector, Traits>(point1, point2, point3)}
- {}
- constexpr PlaneBase(const PlaneBase &) = default;
- PlaneBase(PlaneBase &&) = default;
- PlaneBase &operator = (const PlaneBase &) = default;
- PlaneBase &operator = (PlaneBase &&) = default;
- constexpr VectorType normal() const {
- return normal_;
- }
- constexpr RealType constant() const {
- return constant_;
- }
- bool containsPoint(const VectorType &point) const{
- constexpr RealType tolerance = static_cast<RealType>(0.00001);
- return std::abs(Traits::dotProduct(normal_, point) + constant_) <= tolerance;
- }
- private:
- //Ax + By + Cy + D = 0
- VectorType normal_; // {A, B, C}
- RealType constant_; // D
- };
- template <typename Vector, typename Traits = VectorTraits<Vector>>
- typename Traits::RealType dihedralAngle(const PlaneBase<Vector, Traits> &firstPlane, const PlaneBase<Vector, Traits> &secondPlane) {
- return std::acos(Traits::dotProduct(firstPlane.normal(), secondPlane.normal()));
- }
- // TriangleBase.h
- #pragma once
- #include "VectorTraits.h"
- #include <array>
- #include <cmath>
- constexpr size_t vertexCountPerTriangle = 3;
- template <typename Vector, typename Traits = VectorTraits<Vector>>
- class TriangleBase{
- enum {A, B, C};
- public:
- using PointType = typename Traits::VectorType;
- using RealType = typename Traits::RealType;
- public:
- TriangleBase()
- : vertices_{}
- {}
- TriangleBase (const TriangleBase &) = default;
- TriangleBase (TriangleBase &&) = default;
- TriangleBase &operator = (const TriangleBase &) = default;
- TriangleBase &operator = (TriangleBase &&) = default;
- ~TriangleBase() = default;
- TriangleBase(const PointType &point1, const PointType &point2, const PointType &point3)
- : vertices_{point1, point2, point3}
- {}
- TriangleBase(const std::array<PointType, vertexCountPerTriangle> &vertices)
- : vertices_{vertices}
- {}
- PointType a() const{
- return vertices_[A];
- }
- PointType b() const{
- return vertices_[B];
- }
- PointType c() const{
- return vertices_[C];
- }
- PointType ab() const{
- return b() - a();
- }
- PointType ac() const{
- return c() - a();
- }
- PointType bc() const{
- return c() - b();
- }
- PointType perpendicular() const{
- return Traits::crossProduct(ab(), ac());
- }
- PointType normal() const{
- return Traits::normalized(perpendicular());
- }
- PointType normal(const PointType &pointUnderPlane) const{
- const PointType &result = normal();
- //FIXME: исправить
- if(pointUnderPlane.distanceToPlane(a(), b(), c()) > 0){
- return -result;
- }
- else{
- return result;
- }
- }
- bool isPointInside(const PointType &point) const{
- const PointType &unitVectorFromAtoPoint = Traits::normalized(a() - point);
- const PointType &unitVectorFromBtoPoint = Traits::normalized(b() - point);
- const PointType &unitVectorFromCtoPoint = Traits::normalized(c() - point);
- const RealType cosAngle1 = Traits::dotProduct(unitVectorFromAtoPoint, unitVectorFromBtoPoint);
- const RealType cosAngle2 = Traits::dotProduct(unitVectorFromBtoPoint, unitVectorFromCtoPoint);
- const RealType cosAngle3 = Traits::dotProduct(unitVectorFromCtoPoint, unitVectorFromAtoPoint);
- const RealType angleSum = acos(cosAngle1) + acos(cosAngle2) + acos(cosAngle3);
- constexpr RealType tolerance = 1e-4;
- if (std::abs(angleSum - M_PI * 2) < tolerance && !qIsNaN(angleSum)){
- return true;
- }
- return false;
- }
- RealType square() const{
- return Traits::length(Traits::crossProduct(ab(), ac())) / 2;
- }
- PointType center() const{
- return (a() + b() + c()) / 3;
- }
- void shrink(RealType factor){
- const PointType ¢er = this->center();
- for (PointType &vertex: vertices_){
- vertex += (center - vertex) * factor;
- }
- }
- TriangleBase shrinked(RealType factor) const
- {
- TriangleBase result(*this);
- result.shrink(factor);
- return result;
- }
- void setAllPoints(const PointType &point){
- vertices_.fill(point);
- }
- private:
- std::array<PointType, vertexCountPerTriangle> vertices_;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement