TeiaCareSDK  v0.1.0
TeiaCareSDK is a collection of reusable C++ components
Loading...
Searching...
No Matches
line.hpp
1// Copyright 2024 TeiaCare
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#include <teiacare/sdk/geometry/point.hpp>
18
19#include <optional>
20#include <string>
21
22namespace tc::sdk
23{
24/*!
25 * \class line
26 * \brief 2D line specified by a pair of start/end points.
27 * \tparam T Underlying points coordinate type.
28 *
29 */
30template <typename T>
31class line
32{
33public:
34 /*!
35 * \brief Default Constructor. Creates a default tc::sdk::line instance.
36 */
37 constexpr line() = default;
38
39 /*!
40 * \brief Copy Constructor. Copy a tc::sdk::line instance into another one.
41 */
42 constexpr line(const line&) = default;
43
44 /*!
45 * \brief Move Constructor. Copy a tc::sdk::line instance into another one.
46 */
47 constexpr line(line&&) = default;
48
49 /*!
50 * \brief Constructor. Creates tc::sdk::line instance with given start and end points.
51 * \param start the start point of the line.
52 * \param end the end point of the line.
53 */
55 : _start{start}
56 , _end{end}
57 {
58 }
59
60 /*!
61 * \brief Assignment operator. Assign a tc::sdk::line instance to another one.
62 */
63 line& operator=(const line&) = default;
64
65 /*!
66 * \brief Move assignment operator. Assign a tc::sdk::line instance to another one.
67 */
68 line& operator=(line&&) = default;
69
70 /*!
71 * \brief Equality operator.
72 * \param other the line to compare against.
73 * \return true if the two lines have the same start and end points.
74 */
75 constexpr inline bool operator==(const line& other) const noexcept
76 {
77 return (_start == other._start && _end == other._end) ||
78 (_start == other._end && _end == other._start);
79 }
80
81 /*!
82 * \brief Inequality operator.
83 * \param other the line to compare against.
84 * \return true if the two lines have different start or end points.
85 */
86 constexpr inline bool operator!=(const line& other) const noexcept
87 {
88 return !operator==(other);
89 }
90
91 /*!
92 * \brief Check if the line is a point.
93 * \return true if the start and end points are the same.
94 */
95 constexpr bool is_null() const noexcept
96 {
97 return _start == _end;
98 }
99
100 /*!
101 * \brief Check if the line is vertical.
102 * \return true if the start and end points have the same x coordinate.
103 */
105 {
106 return _start.x() == _end.x();
107 }
108
109 /*!
110 * \brief Check if the line is horizontal.
111 * \return true if the start and end points have the same y coordinate.
112 */
114 {
115 return _start.y() == _end.y();
116 }
117
118 /*!
119 * \brief Start point getter.
120 * \return Start point of the line.
121 */
123 {
124 return _start;
125 }
126
127 /*!
128 * \brief End point getter.
129 * \return End point of the line.
130 */
132 {
133 return _end;
134 }
135
136 /*!
137 * \brief Start point setter. Set the start point of the line.
138 */
139 inline void set_start(tc::sdk::point<T> start) noexcept
140 {
141 _start = start;
142 }
143
144 /*!
145 * \brief End point setter. Set the end point of the line.
146 */
147 inline void set_end(tc::sdk::point<T> end) noexcept
148 {
149 _end = end;
150 }
151
152 /*!
153 * \brief Check if the given line segments intersects the current instance.
154 * \param other the line to check the intersection against.
155 * \return true if the two lines intersects.
156 */
157 bool intersects(tc::sdk::line<T> other) const noexcept
158 {
159 return get_intersection(other) != std::nullopt;
160 }
161
162 /*!
163 * \brief Computes the intersection between the given line and the current one.
164 * \param other the compute to check the intersection against.
165 * \return std::nullopt if the two lines do not intersect, otherwise a std::optional<tc::sdk::point<double>> with the intersection point.
166 */
167 std::optional<tc::sdk::point<double>> get_intersection(tc::sdk::line<T> other) const noexcept
168 {
169 // https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection#Given_two_points_on_each_line_segment
170
171 auto is_unit_range = [](double value) {
172 return 0.0 <= value && value <= 1.0;
173 };
174
175 const double x_A = static_cast<double>(_start.x());
176 const double y_A = static_cast<double>(_start.y());
177
178 const double x_B = static_cast<double>(_end.x());
179 const double y_B = static_cast<double>(_end.y());
180
181 const double x_C = static_cast<double>(other._start.x());
182 const double y_C = static_cast<double>(other._start.y());
183
184 const double x_D = static_cast<double>(other._end.x());
185 const double y_D = static_cast<double>(other._end.y());
186
187 const double denom = ((x_A - x_B) * (y_C - y_D) - (y_A - y_B) * (x_C - x_D));
188
189 const double t = ((x_A - x_C) * (y_C - y_D) - (y_A - y_C) * (x_C - x_D)) / denom;
190 if (!is_unit_range(t))
191 return std::nullopt;
192
193 const double u = ((x_A - x_B) * (y_A - y_C) - (y_A - y_B) * (x_A - x_C)) / denom;
194 if (!is_unit_range(-u))
195 return std::nullopt;
196
197 const double intersection_x = x_A + t * (x_B - x_A);
198 const double intersection_y = y_A + t * (y_B - y_A);
199
201 }
202
203 /*!
204 * \brief Get the line string representation
205 * \return String representation of the current line.
206 */
207 constexpr std::string to_string() const
208 {
209 return std::string("(" + _start.to_string() + " : " + _end.to_string() + ")");
210 }
211
212 /*!
213 * \brief Output stream operator.
214 * \param stream the output stream to write into.
215 * \param l the line object to stream.
216 * \return reference to the output stream operator, with the line string representation written into it.
217 */
218 friend std::ostream& operator<<(std::ostream& stream, const line& l)
219 {
220 return stream << l.to_string();
221 }
222
223private:
224 tc::sdk::point<T> _start{};
225 tc::sdk::point<T> _end{};
226};
227
228}
Thread safe, blocking queue.
2D line specified by a pair of start/end points.
Definition line.hpp:32
constexpr tc::sdk::point< T > start() const noexcept
Start point getter.
Definition line.hpp:122
constexpr bool is_null() const noexcept
Check if the line is a point.
Definition line.hpp:95
constexpr bool operator!=(const line &other) const noexcept
Inequality operator.
Definition line.hpp:86
constexpr line(const line &)=default
Copy Constructor. Copy a tc::sdk::line instance into another one.
constexpr line()=default
Default Constructor. Creates a default tc::sdk::line instance.
friend std::ostream & operator<<(std::ostream &stream, const line &l)
Output stream operator.
Definition line.hpp:218
constexpr tc::sdk::point< T > end() const noexcept
End point getter.
Definition line.hpp:131
constexpr std::string to_string() const
Get the line string representation.
Definition line.hpp:207
void set_end(tc::sdk::point< T > end) noexcept
End point setter. Set the end point of the line.
Definition line.hpp:147
constexpr line(line &&)=default
Move Constructor. Copy a tc::sdk::line instance into another one.
constexpr line(tc::sdk::point< T > start, tc::sdk::point< T > end) noexcept
Constructor. Creates tc::sdk::line instance with given start and end points.
Definition line.hpp:54
line & operator=(line &&)=default
Move assignment operator. Assign a tc::sdk::line instance to another one.
std::optional< tc::sdk::point< double > > get_intersection(tc::sdk::line< T > other) const noexcept
Computes the intersection between the given line and the current one.
Definition line.hpp:167
bool is_vertical() const noexcept
Check if the line is vertical.
Definition line.hpp:104
void set_start(tc::sdk::point< T > start) noexcept
Start point setter. Set the start point of the line.
Definition line.hpp:139
constexpr bool operator==(const line &other) const noexcept
Equality operator.
Definition line.hpp:75
bool intersects(tc::sdk::line< T > other) const noexcept
Check if the given line segments intersects the current instance.
Definition line.hpp:157
bool is_horizontal() const noexcept
Check if the line is horizontal.
Definition line.hpp:113
line & operator=(const line &)=default
Assignment operator. Assign a tc::sdk::line instance to another one.