1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file Device/Mask/Line.cpp
//! @brief Implements class Line.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#include "Device/Mask/Line.h"
#include "Base/Axis/Bin.h"
#include "Base/Math/Numeric.h"
#include <limits>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#include <boost/geometry.hpp>
#pragma clang diagnostic pop
using point_t = boost::geometry::model::d2::point_xy<double>;
using line_t = boost::geometry::model::linestring<point_t>;
Line::Line(double x1, double y1, double x2, double y2)
: IShape2D("Line")
, m_x1(x1)
, m_y1(y1)
, m_x2(x2)
, m_y2(y2)
{
}
bool Line::contains(double x, double y) const
{
point_t p(x, y);
line_t line;
line.emplace_back(m_x1, m_y1);
line.emplace_back(m_x2, m_y2);
double d = boost::geometry::distance(p, line);
return d < std::numeric_limits<double>::epsilon();
}
// Calculates if line crosses the box made out of our bins.
// Ugly implementation, see discussion at http://stackoverflow.com/questions/21408977
bool Line::contains(const Bin1D& binx, const Bin1D& biny) const
{
std::vector<point_t> box_points;
box_points.emplace_back(binx.min(), biny.min());
box_points.emplace_back(binx.min(), biny.max());
box_points.emplace_back(binx.max(), biny.max());
box_points.emplace_back(binx.max(), biny.min());
box_points.emplace_back(binx.min(), biny.min());
std::vector<point_t> line_points;
line_points.emplace_back(m_x1, m_y1);
line_points.emplace_back(m_x2, m_y2);
return boost::geometry::intersects(line_t(box_points.begin(), box_points.end()),
line_t(line_points.begin(), line_points.end()));
}
// ------------------------------------------------------------------------- //
//! @param x The value at which it crosses x-axes
VerticalLine::VerticalLine(double x)
: IShape2D("VerticalLine")
, m_x(x)
{
}
bool VerticalLine::contains(double x, double /*y*/) const
{
return Numeric::almostEqual(x, m_x, 2);
}
bool VerticalLine::contains(const Bin1D& binx, const Bin1D& /*biny*/) const
{
return m_x >= binx.min() && m_x <= binx.max();
}
// ------------------------------------------------------------------------- //
//! @param y The value at which it crosses y-axes
HorizontalLine::HorizontalLine(double y)
: IShape2D("HorizontalLine")
, m_y(y)
{
}
bool HorizontalLine::contains(double /*x*/, double y) const
{
return Numeric::almostEqual(y, m_y, 2);
}
bool HorizontalLine::contains(const Bin1D& /*binx*/, const Bin1D& biny) const
{
return m_y >= biny.min() && m_y <= biny.max();
}
|