Program Listing for File generic_line.h

Return to documentation for file (src/rlenvs/utils/geometry/generic_line.h)

#ifndef GENERIC_LINE_H
#define GENERIC_LINE_H

#include "rlenvs/rlenvs_types_v2.h"
#include "rlenvs/rlenvs_consts.h"
#include "rlenvs/utils/geometry/geom_point.h"
#include "rlenvs/utils/maths/math_utils.h"

#include <cmath>
#include <stdexcept>

namespace rlenvscpp{
namespace utils{
namespace geom{



template<int dim>
class GenericLine
{
public:

    static const int dimension = dim;

    typedef GeomPoint<dim> vertex_type;

    GenericLine();

    GenericLine(const vertex_type& p1, const vertex_type& p2);

    GenericLine(const vertex_type& p1, const vertex_type& p2, uint_t id);

    const vertex_type& get_vertex(uint_t v)const;

    vertex_type& get_vertex(uint_t v);

    bool has_valid_id()const noexcept{return id_ != rlenvscpp::consts::INVALID_ID;}

    uint_t get_id()const noexcept{return id_;}

    void set_id(uint_t id)noexcept{id_ = id;}

    real_t slope()const;


    real_t factor()const;

    real_t distance(const vertex_type& n)const;

    real_t length()const{return end_.distance(start_);}

private:

    uint_t id_;
    vertex_type start_;
    vertex_type end_;

};

template<int dim>
GenericLine<dim>::GenericLine()
:
id_(rlenvscpp::consts::INVALID_ID),
start_(),
end_()
{}

template<int dim>
GenericLine<dim>::GenericLine(const vertex_type& p1, const vertex_type& p2, uint_t id)
:
id_(id),
start_(p1),
end_(p2)
{}

template<int dim>
GenericLine<dim>::GenericLine(const vertex_type& p1, const vertex_type& p2)
:
GenericLine<dim>(p1,p2,rlenvscpp::consts::INVALID_ID)
{}

template<int dim>
const typename GenericLine<dim>::vertex_type&
GenericLine<dim>::get_vertex(uint_t v)const{

    if(v == 0){
        return start_;
    }
    else if(v == 1){
        return end_;
    }

    throw std::logic_error("Invalid vertex index. Index not in [0,1]");

}

template<int dim>
typename GenericLine<dim>::vertex_type&
GenericLine<dim>::get_vertex(uint_t v){

    if(v == 0){
        return start_;
    }
    else if(v == 1){
        return end_;
    }

    throw std::logic_error("Invalid vertex index. Index not in [0,1]");

}

template<int dim>
real_t
GenericLine<dim>::slope()const{
    return (end_[1] - start_[1])/(end_[0] - start_[0]);
}

template<int dim>
real_t
GenericLine<dim>::factor()const{
    auto slope_  = slope();
    return start_[1] - slope_ * start_[0];
}

template<>
real_t
GenericLine<2>::distance(const GenericLine<2>::vertex_type& n)const{
    // we use the formula from
    // https://brilliant.org/wiki/dot-product-distance-between-point-and-a-line/
    // to calculate the distance

    real_t A = -slope();
    real_t C = -factor();
    real_t B = 1.0;

    return std::fabs(A * n[0] + B * n[1] + C)/std::sqrt(rlenvscpp::utils::maths::sqr(A) + rlenvscpp::utils::maths::sqr(B));

}

}
}
}
#endif // GENERIC_LINE_H