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#include <point.H>
100
101namespace Aleph
102{
103
111inline const Geom_Number LINE_EPSILON(0);
112
125struct LineEq
126{
129
135 constexpr LineEq() noexcept = default;
136
152
169 : y0(y1 - __m * x1), m(__m) {}
170
192 LineEq(const Geom_Number & x1, const Geom_Number & y1,
193 const Geom_Number & x2, const Geom_Number & y2)
194 {
195 ah_domain_error_if(x1 == x2)
196 << "Cannot create line from points with same x-coordinate (vertical line): "
197 << "x1 = " << x1 << ", x2 = " << x2;
198
199 m = (y2 - y1) / (x2 - x1);
200 y0 = y1 - m * x1;
201 }
202
215 LineEq(const Point & p, const Geom_Number & __m) noexcept
216 : LineEq(p.get_x(), p.get_y(), __m) {}
217
232 LineEq(const Point & p1, const Point & p2)
233 : LineEq(p1.get_x(), p1.get_y(), p2.get_x(), p2.get_y()) {}
234
249 [[nodiscard]] Geom_Number operator()(const Geom_Number & x) const noexcept
250 {
251 return y0 + m * x;
252 }
253
258 [[nodiscard]] const Geom_Number & slope() const noexcept { return m; }
259
265
271 [[nodiscard]] bool is_horizontal(const Geom_Number & epsilon = LINE_EPSILON) const noexcept
272 {
273 return abs(m) <= epsilon;
274 }
275
286 const Geom_Number & epsilon = LINE_EPSILON) const noexcept
287 {
288 return abs(m - l.m) <= epsilon;
289 }
290
301 const Geom_Number & epsilon = LINE_EPSILON) const noexcept
302 {
303 return abs(m * l.m + Geom_Number(1)) <= epsilon;
304 }
305
316 {
318 << "Cannot compute x for horizontal line (slope = 0)";
319 return (y - y0) / m;
320 }
321
343 [[nodiscard]] std::pair<Geom_Number, Geom_Number> intersection(const LineEq & l,
344 const Geom_Number & epsilon = LINE_EPSILON) const
345 {
347 << "Cannot compute intersection of parallel lines: "
348 << "slope1 = " << m << ", slope2 = " << l.m;
349
350 Geom_Number x = (y0 - l.y0) / (l.m - m);
351 return {x, (*this)(x)};
352 }
353
366 {
368 << "Cannot compute perpendicular to horizontal line (would be vertical)";
369
370 const Geom_Number perp_slope = Geom_Number(-1) / m;
371 return {px, py, perp_slope};
372 }
373
383 [[nodiscard]] Geom_Number distance_to(const Geom_Number & px, const Geom_Number & py) const noexcept
384 {
385 const Geom_Number diff = py - (y0 + m * px);
386 // Use mpfr for sqrt, then convert back to rational
387 const mpfr_class denominator = sqrt(mpfr_class(1) + mpfr_class(m) * mpfr_class(m));
388 return abs(diff) / Geom_Number(denominator);
389 }
390
400 const Geom_Number & epsilon = LINE_EPSILON) const noexcept
401 {
402 return abs(py - (*this)(px)) <= epsilon;
403 }
404
411 [[nodiscard]] Geom_Number distance_to(const Point & p) const noexcept
412 {
413 return distance_to(p.get_x(), p.get_y());
414 }
415
424 {
425 return perpendicular_through(p.get_x(), p.get_y());
426 }
427
435 [[nodiscard]] bool contains_point(const Point & p,
436 const Geom_Number & epsilon = LINE_EPSILON) const noexcept
437 {
438 return contains_point(p.get_x(), p.get_y(), epsilon);
439 }
440
457 const Geom_Number & epsilon = LINE_EPSILON) const
458 {
459 auto [x, y] = intersection(l, epsilon);
460 return {x, y};
461 }
462
471 [[nodiscard]] bool operator==(const LineEq & l) const noexcept
472 {
473 return y0 == l.y0 and m == l.m;
474 }
475
482 [[nodiscard]] bool operator!=(const LineEq & l) const noexcept
483 {
484 return not (*this == l);
485 }
486
497 [[nodiscard]] bool approx_equal(const LineEq & l, const Geom_Number & epsilon) const noexcept
498 {
499 return abs(y0 - l.y0) <= epsilon and abs(m - l.m) <= epsilon;
500 }
501
507 [[nodiscard]] std::string to_string() const
508 {
509 std::ostringstream s;
510 s << "y = " << y0 << " + " << m << " * x";
511 return s.str();
512 }
513
521 friend std::ostream & operator<<(std::ostream & out, const LineEq & l)
522 {
523 return out << l.to_string();
524 }
525};
526
527} // namespace Aleph
528
529// Global namespace compatibility
530using Aleph::LineEq;
532
533# 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
Represents a point with rectangular coordinates in a 2D plane.
Definition point.H:229
const Geom_Number & get_x() const noexcept
Gets the x-coordinate value.
Definition point.H:457
const Geom_Number & get_y() const noexcept
Gets the y-coordinate value.
Definition point.H:466
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_y1_function > > y1(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4103
__gmp_expr< mpfr_t, mpfr_t > mpfr_class
Definition gmpfrxx.h:2446
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_sqrt_function > > sqrt(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4058
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_abs_function > > abs(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4051
static mpfr_t y
Definition mpfr_mul_d.c:3
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
and
Check uniqueness with explicit hash + equality functors.
const Geom_Number LINE_EPSILON(0)
Default epsilon for geometric comparisons.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
mpq_class Geom_Number
Numeric type used by the geometry module.
Definition point.H:115
2D point and geometric utilities.
2D infinite line in slope-intercept form.
Definition line.H:126
bool operator!=(const LineEq &l) const noexcept
Test inequality of two lines.
Definition line.H:482
std::pair< Geom_Number, Geom_Number > intersection(const LineEq &l, const Geom_Number &epsilon=LINE_EPSILON) const
Compute the intersection point with another line.
Definition line.H:343
LineEq perpendicular_through(const Geom_Number &px, const Geom_Number &py) const
Compute perpendicular line through a point.
Definition line.H:365
bool approx_equal(const LineEq &l, const Geom_Number &epsilon) const noexcept
Test approximate equality of two lines.
Definition line.H:497
Geom_Number operator()(const Geom_Number &x) const noexcept
Evaluate line at given x-coordinate.
Definition line.H:249
bool is_horizontal(const Geom_Number &epsilon=LINE_EPSILON) const noexcept
Check if the line is horizontal (slope = 0).
Definition line.H:271
constexpr LineEq() noexcept=default
Default constructor creates line y = x.
friend std::ostream & operator<<(std::ostream &out, const LineEq &l)
Output stream operator.
Definition line.H:521
LineEq perpendicular_through(const Point &p) const
Compute a perpendicular line through a Point.
Definition line.H:423
bool contains_point(const Point &p, const Geom_Number &epsilon=LINE_EPSILON) const noexcept
Check if a Point lies on this line.
Definition line.H:435
const Geom_Number & y_intercept() const noexcept
Get the y-intercept of the line.
Definition line.H:264
Geom_Number x_at(const Geom_Number &y) const
Compute x-coordinate for a given y-coordinate.
Definition line.H:315
Point intersection_point(const LineEq &l, const Geom_Number &epsilon=LINE_EPSILON) const
Compute the intersection Point with another line.
Definition line.H:456
std::string to_string() const
Convert line to a string representation.
Definition line.H:507
Geom_Number distance_to(const Geom_Number &px, const Geom_Number &py) const noexcept
Compute distance from a point to this line.
Definition line.H:383
Geom_Number distance_to(const Point &p) const noexcept
Compute distance from a Point to this line.
Definition line.H:411
LineEq(const Geom_Number &x1, const Geom_Number &y1, const Geom_Number &x2, const Geom_Number &y2)
Construct a line through two points.
Definition line.H:192
bool is_perpendicular_to(const LineEq &l, const Geom_Number &epsilon=LINE_EPSILON) const noexcept
Check if this line is perpendicular to another.
Definition line.H:300
const Geom_Number & slope() const noexcept
Get the slope of the line.
Definition line.H:258
LineEq(const Point &p, const Geom_Number &__m) noexcept
Construct a line through a Point with a given slope.
Definition line.H:215
Geom_Number y0
Y-intercept (where line crosses y-axis)
Definition line.H:127
LineEq(const Point &p1, const Point &p2)
Construct line through two Points.
Definition line.H:232
LineEq(const Geom_Number &x1, const Geom_Number &y1, const Geom_Number &__m) noexcept
Construct line through a point with given slope.
Definition line.H:168
Geom_Number m
Slope (dy/dx)
Definition line.H:128
bool operator==(const LineEq &l) const noexcept
Test equality of two lines.
Definition line.H:471
bool is_parallel_to(const LineEq &l, const Geom_Number &epsilon=LINE_EPSILON) const noexcept
Check if this line is parallel to another.
Definition line.H:285
bool contains_point(const Geom_Number &px, const Geom_Number &py, const Geom_Number &epsilon=LINE_EPSILON) const noexcept
Check if a point lies on this line.
Definition line.H:399
DynList< int > l