@@ -2015,38 +2015,36 @@ absl::optional<std::pair<int, int>> FindOneIntersectionIfPresent(
20152015 return a.x_min < b.x_min ;
20162016 }));
20172017
2018- // Current y-coordinate intervals that are intersecting the sweep line.
2019- // Note that the interval_set only contains disjoint intervals .
2020- struct Interval {
2021- int index;
2018+ // Set of box intersection the sweep line. We only store y_min, other
2019+ // coordinates can be accessed via rectangles[index].coordinate .
2020+ struct Element {
2021+ mutable int index;
20222022 IntegerValue y_min;
2023- IntegerValue y_max;
2024-
2025- // IMPORTANT: For correctness, we need later insert to be first!
2026- bool operator <(const Interval& other) const {
2027- if (y_min == other.y_min ) return index > other.index ;
2028- return y_min < other.y_min ;
2029- }
2030-
2031- std::string to_string () const {
2032- return absl::StrCat (" [" , y_min.value (), " ," , y_max.value (), " ](" , index,
2033- " )" );
2034- }
2023+ bool operator <(const Element& other) const { return y_min < other.y_min ; }
20352024 };
2036-
2037- // TODO(user): Use fixed binary tree instead, it should be faster.
2038- // We just need insert/erase/previous/next API.
2039- std::set<Interval> interval_set;
2025+ std::set<Element> interval_set;
20402026
20412027 for (int i = 0 ; i < rectangles.size (); ++i) {
20422028 const IntegerValue x = rectangles[i].x_min ;
2029+ const IntegerValue y_min = rectangles[i].y_min ;
2030+ const IntegerValue y_max = rectangles[i].y_max ;
2031+
2032+ // TODO(user): We can handle that, but it require some changes below.
2033+ DCHECK_LE (y_min, y_max);
20432034
2044- // Try to add the y part of this rectangle to the set, if there is an
2045- // intersection, lazily remove it if its x_max is already passed, otherwise
2046- // report the intersection.
2047- const Interval to_insert = {i, rectangles[i].y_min , rectangles[i].y_max };
2048- auto [it, inserted] = interval_set.insert (to_insert);
2049- DCHECK (inserted);
2035+ // Try to add this rectangle to the set, if there is an intersection, lazily
2036+ // remove it if its x_max is already passed, otherwise report the
2037+ // intersection.
2038+ auto [it, inserted] = interval_set.insert ({i, y_min});
2039+ if (!inserted) {
2040+ if (rectangles[it->index ].x_max <= x) {
2041+ // We just replace if the rectangle at position i is stale.
2042+ it->index = i;
2043+ } else {
2044+ // Intersection.
2045+ return {{it->index , i}};
2046+ }
2047+ }
20502048
20512049 // Note that the intersection is either before 'it', or just after it.
20522050 if (it != interval_set.begin ()) {
@@ -2057,8 +2055,9 @@ absl::optional<std::pair<int, int>> FindOneIntersectionIfPresent(
20572055 if (rectangles[it_before->index ].x_max <= x) {
20582056 interval_set.erase (it_before);
20592057 } else {
2060- DCHECK_LE (it_before->y_min , to_insert.y_min );
2061- if (it_before->y_max > to_insert.y_min ) {
2058+ DCHECK_LE (it_before->y_min , y_min);
2059+ const IntegerValue y_max_before = rectangles[it_before->index ].y_max ;
2060+ if (y_max_before > y_min) {
20622061 // Intersection.
20632062 return {{it_before->index , i}};
20642063 }
@@ -2073,8 +2072,8 @@ absl::optional<std::pair<int, int>> FindOneIntersectionIfPresent(
20732072 continue ;
20742073 }
20752074
2076- DCHECK_LE (to_insert. y_min , it->y_min );
2077- if (to_insert. y_max > it->y_min ) {
2075+ DCHECK_LE (y_min, it->y_min );
2076+ if (y_max > it->y_min ) {
20782077 // Intersection.
20792078 return {{it->index , i}};
20802079 }
0 commit comments