File: Line.cpp

package info (click to toggle)
bornagain 23.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 103,936 kB
  • sloc: cpp: 423,131; python: 40,997; javascript: 11,167; awk: 630; sh: 318; ruby: 173; xml: 130; makefile: 51; ansic: 24
file content (103 lines) | stat: -rw-r--r-- 3,106 bytes parent folder | download | duplicates (2)
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();
}