xref: /aosp_15_r20/external/skia/modules/bentleyottmann/include/Segment.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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