Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
line.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
91#ifndef LINE_H
92#define LINE_H
93
94#include <cmath>
95#include <utility>
96#include <string>
97#include <sstream>
98#include <ah-errors.H>
99
100namespace Aleph
101{
102
106inline constexpr double LINE_EPSILON = 1e-10;
107
120struct LineEq
121{
122 double y0 = 0;
123 double m = 1;
124
130 constexpr LineEq() noexcept = default;
131
146 : y0(__y0), m(__m) {}
147
163 constexpr LineEq(double x1, double y1, double __m) noexcept
164 : y0(y1 - __m * x1), m(__m) {}
165
187 LineEq(double x1, double y1, double x2, double y2)
188 {
189 ah_domain_error_if(std::abs(x1 - x2) < LINE_EPSILON)
190 << "Cannot create line from points with same x-coordinate (vertical line): "
191 << "x1 = " << x1 << ", x2 = " << x2;
192
193 m = (y2 - y1) / (x2 - x1);
194 y0 = y1 - m * x1;
195 }
196
211 [[nodiscard]] constexpr double operator()(double x) const noexcept
212 {
213 return y0 + m * x;
214 }
215
220 [[nodiscard]] constexpr double slope() const noexcept { return m; }
221
226 [[nodiscard]] constexpr double y_intercept() const noexcept { return y0; }
227
233 [[nodiscard]] constexpr bool is_horizontal(double epsilon = LINE_EPSILON) const noexcept
234 {
235 return std::abs(m) < epsilon;
236 }
237
247 [[nodiscard]] constexpr bool is_parallel_to(const LineEq & l,
248 double epsilon = LINE_EPSILON) const noexcept
249 {
250 return std::abs(m - l.m) < epsilon;
251 }
252
262 [[nodiscard]] constexpr bool is_perpendicular_to(const LineEq & l,
263 double epsilon = LINE_EPSILON) const noexcept
264 {
265 return std::abs(m * l.m + 1.0) < epsilon;
266 }
267
277 [[nodiscard]] double x_at(double y) const
278 {
280 << "Cannot compute x for horizontal line (slope = 0)";
281 return (y - y0) / m;
282 }
283
305 [[nodiscard]] std::pair<double, double> intersection(const LineEq & l,
306 double epsilon = LINE_EPSILON) const
307 {
309 << "Cannot compute intersection of parallel lines: "
310 << "slope1 = " << m << ", slope2 = " << l.m;
311
312 double x = (y0 - l.y0) / (l.m - m);
313 return {x, (*this)(x)};
314 }
315
327 [[nodiscard]] LineEq perpendicular_through(double px, double py) const
328 {
330 << "Cannot compute perpendicular to horizontal line (would be vertical)";
331
332 double perp_slope = -1.0 / m;
333 return LineEq(px, py, perp_slope);
334 }
335
345 [[nodiscard]] double distance_to(double px, double py) const noexcept
346 {
347 double diff = py - (y0 + m * px);
348 return std::abs(diff) / std::sqrt(1.0 + m * m);
349 }
350
359 [[nodiscard]] bool contains_point(double px, double py,
360 double epsilon = LINE_EPSILON) const noexcept
361 {
362 return std::abs(py - (*this)(px)) < epsilon;
363 }
364
374 [[nodiscard]] bool operator==(const LineEq & l) const noexcept
375 {
376 return std::abs(y0 - l.y0) < LINE_EPSILON and
377 std::abs(m - l.m) < LINE_EPSILON;
378 }
379
386 [[nodiscard]] bool operator!=(const LineEq & l) const noexcept
387 {
388 return not (*this == l);
389 }
390
396 [[nodiscard]] std::string to_string() const
397 {
398 std::ostringstream s;
399 s << "y = " << y0 << " + " << m << " * x";
400 return s.str();
401 }
402
410 friend std::ostream & operator<<(std::ostream & out, const LineEq & l)
411 {
412 return out << l.to_string();
413 }
414};
415
416} // namespace Aleph
417
418// Global namespace compatibility
419using Aleph::LineEq;
421
422#endif // LINE_H
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Definition ah-errors.H:522
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_y1_function > > y1(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4103
static mpfr_t y
Definition mpfr_mul_d.c:3
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
constexpr double LINE_EPSILON
Default epsilon for floating-point comparisons.
Definition line.H:106
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
DynList< T > maps(const C &c, Op op)
Classic map operation.
2D infinite line in slope-intercept form.
Definition line.H:121
LineEq(double x1, double y1, double x2, double y2)
Construct line through two points.
Definition line.H:187
constexpr bool is_horizontal(double epsilon=LINE_EPSILON) const noexcept
Check if the line is horizontal (slope = 0).
Definition line.H:233
bool operator!=(const LineEq &l) const noexcept
Test inequality of two lines.
Definition line.H:386
double x_at(double y) const
Compute x-coordinate for a given y-coordinate.
Definition line.H:277
constexpr LineEq(double x1, double y1, double __m) noexcept
Construct line through a point with given slope.
Definition line.H:163
double distance_to(double px, double py) const noexcept
Compute distance from a point to this line.
Definition line.H:345
double y0
Y-intercept (where line crosses y-axis)
Definition line.H:122
constexpr LineEq() noexcept=default
Default constructor creates line y = x.
constexpr bool is_parallel_to(const LineEq &l, double epsilon=LINE_EPSILON) const noexcept
Check if this line is parallel to another.
Definition line.H:247
friend std::ostream & operator<<(std::ostream &out, const LineEq &l)
Output stream operator.
Definition line.H:410
LineEq perpendicular_through(double px, double py) const
Compute perpendicular line through a point.
Definition line.H:327
constexpr double y_intercept() const noexcept
Get the y-intercept of the line.
Definition line.H:226
constexpr double operator()(double x) const noexcept
Evaluate line at given x-coordinate.
Definition line.H:211
std::string to_string() const
Convert line to string representation.
Definition line.H:396
double m
Slope (dy/dx)
Definition line.H:123
std::pair< double, double > intersection(const LineEq &l, double epsilon=LINE_EPSILON) const
Compute intersection point with another line.
Definition line.H:305
bool contains_point(double px, double py, double epsilon=LINE_EPSILON) const noexcept
Check if a point lies on this line.
Definition line.H:359
bool operator==(const LineEq &l) const noexcept
Test equality of two lines.
Definition line.H:374
constexpr bool is_perpendicular_to(const LineEq &l, double epsilon=LINE_EPSILON) const noexcept
Check if this line is perpendicular to another.
Definition line.H:262
constexpr double slope() const noexcept
Get the slope of the line.
Definition line.H:220
DynList< int > l