1*c8dee2aaSAndroid Build Coastguard Worker // Copyright 2023 Google LLC 2*c8dee2aaSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 3*c8dee2aaSAndroid Build Coastguard Worker 4*c8dee2aaSAndroid Build Coastguard Worker #ifndef Segment_DEFINED 5*c8dee2aaSAndroid Build Coastguard Worker #define Segment_DEFINED 6*c8dee2aaSAndroid Build Coastguard Worker 7*c8dee2aaSAndroid Build Coastguard Worker #include "modules/bentleyottmann/include/Point.h" 8*c8dee2aaSAndroid Build Coastguard Worker 9*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 10*c8dee2aaSAndroid Build Coastguard Worker #include <optional> 11*c8dee2aaSAndroid Build Coastguard Worker #include <tuple> 12*c8dee2aaSAndroid Build Coastguard Worker 13*c8dee2aaSAndroid Build Coastguard Worker namespace bentleyottmann { 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker struct Segment { 16*c8dee2aaSAndroid Build Coastguard Worker Point p0; 17*c8dee2aaSAndroid Build Coastguard Worker Point p1; 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard Worker // Y is larger going down the y-axis. 20*c8dee2aaSAndroid Build Coastguard Worker // Get the higher point. It will be left most for horizontal segment. 21*c8dee2aaSAndroid Build Coastguard Worker Point upper() const; 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker // Get the lower point. It will be the right most for horizontal segment. 24*c8dee2aaSAndroid Build Coastguard Worker Point lower() const; 25*c8dee2aaSAndroid Build Coastguard Worker 26*c8dee2aaSAndroid Build Coastguard Worker std::tuple<int32_t, int32_t, int32_t, int32_t> bounds() const; 27*c8dee2aaSAndroid Build Coastguard Worker }; 28*c8dee2aaSAndroid Build Coastguard Worker 29*c8dee2aaSAndroid Build Coastguard Worker bool operator==(const Segment& s0, const Segment& s1); 30*c8dee2aaSAndroid Build Coastguard Worker bool operator<(const Segment& s0, const Segment& s1); 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker struct Crossing { 33*c8dee2aaSAndroid Build Coastguard Worker const Segment s0; 34*c8dee2aaSAndroid Build Coastguard Worker const Segment s1; 35*c8dee2aaSAndroid Build Coastguard Worker const Point crossing; 36*c8dee2aaSAndroid Build Coastguard Worker }; 37*c8dee2aaSAndroid Build Coastguard Worker 38*c8dee2aaSAndroid Build Coastguard Worker bool no_intersection_by_bounding_box(const Segment& s0, const Segment& s1); 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker // Finds the intersection of s0 and s1. Returns nullopt if there is no intersection. 41*c8dee2aaSAndroid Build Coastguard Worker // Note this intersection assumes that line segments do not include their end points. 42*c8dee2aaSAndroid Build Coastguard Worker std::optional<Point> intersect(const Segment& s0, const Segment& s1); 43*c8dee2aaSAndroid Build Coastguard Worker 44*c8dee2aaSAndroid Build Coastguard Worker // Compare two segments at the sweep line given by y. 45*c8dee2aaSAndroid Build Coastguard Worker // It is an error to pass segments that don't intersect the horizontal line at y. 46*c8dee2aaSAndroid Build Coastguard Worker bool less_than_at(const Segment& s0, const Segment& s1, int32_t y); 47*c8dee2aaSAndroid Build Coastguard Worker 48*c8dee2aaSAndroid Build Coastguard Worker // Given a horizontal line defined by p.y, is p.x < the x value where the horizontal line passes 49*c8dee2aaSAndroid Build Coastguard Worker // segment. 50*c8dee2aaSAndroid Build Coastguard Worker bool point_less_than_segment_in_x(Point p, const Segment& segment); 51*c8dee2aaSAndroid Build Coastguard Worker 52*c8dee2aaSAndroid Build Coastguard Worker // The following two routines are used to find the rounded comparison between a Point p and a 53*c8dee2aaSAndroid Build Coastguard Worker // segment s. s(y) is the x value of the segment at y. The rounding definition is: 54*c8dee2aaSAndroid Build Coastguard Worker // x < ⌊s(y) + ½⌋ 55*c8dee2aaSAndroid Build Coastguard Worker // Expanding the floor operation results in 56*c8dee2aaSAndroid Build Coastguard Worker // (x - ½) ≤ s(y) < (x + ½) 57*c8dee2aaSAndroid Build Coastguard Worker // The two functions are the two halves of the above inequality. 58*c8dee2aaSAndroid Build Coastguard Worker // The rounding lower bound is: (x - ½) ≤ s(y). The ordering of the parameters facilitates using 59*c8dee2aaSAndroid Build Coastguard Worker // std::lower_bound. 60*c8dee2aaSAndroid Build Coastguard Worker bool rounded_point_less_than_segment_in_x_lower(const Segment& s, Point p); 61*c8dee2aaSAndroid Build Coastguard Worker // The rounding upper bound is: s(y) < (x + ½) 62*c8dee2aaSAndroid Build Coastguard Worker bool rounded_point_less_than_segment_in_x_upper(const Segment& s, Point p); 63*c8dee2aaSAndroid Build Coastguard Worker 64*c8dee2aaSAndroid Build Coastguard Worker // Compare the slopes of two segments. If a slope is horizontal, then its slope is greater than 65*c8dee2aaSAndroid Build Coastguard Worker // all other slopes or equal of the other segment is also horizontal. The slope for 66*c8dee2aaSAndroid Build Coastguard Worker // non-horizontal segments monotonically increases from the smallest along the negative x-axis 67*c8dee2aaSAndroid Build Coastguard Worker // increasing counterclockwise to the largest along the positive x-axis. 68*c8dee2aaSAndroid Build Coastguard Worker // Returns: 69*c8dee2aaSAndroid Build Coastguard Worker // * -1 - slope(s0) < slope(s1) 70*c8dee2aaSAndroid Build Coastguard Worker // * 0 - slope(s0) == slope(s1) 71*c8dee2aaSAndroid Build Coastguard Worker // * 1 - slope(s0) > slope(s1) 72*c8dee2aaSAndroid Build Coastguard Worker int compare_slopes(const Segment& s0, const Segment& s1); 73*c8dee2aaSAndroid Build Coastguard Worker 74*c8dee2aaSAndroid Build Coastguard Worker } // namespace bentleyottmann 75*c8dee2aaSAndroid Build Coastguard Worker #endif // Segment_DEFINED 76