func CellUnionFromIntersection()

in s2/cellunion.go [61:110]


func CellUnionFromIntersection(x, y CellUnion) CellUnion {
	var cu CellUnion

	// This is a fairly efficient calculation that uses binary search to skip
	// over sections of both input vectors. It takes constant time if all the
	// cells of x come before or after all the cells of y in CellID order.
	var i, j int
	for i < len(x) && j < len(y) {
		iMin := x[i].RangeMin()
		jMin := y[j].RangeMin()
		if iMin > jMin {
			// Either j.Contains(i) or the two cells are disjoint.
			if x[i] <= y[j].RangeMax() {
				cu = append(cu, x[i])
				i++
			} else {
				// Advance j to the first cell possibly contained by x[i].
				j = y.lowerBound(j+1, len(y), iMin)
				// The previous cell y[j-1] may now contain x[i].
				if x[i] <= y[j-1].RangeMax() {
					j--
				}
			}
		} else if jMin > iMin {
			// Identical to the code above with i and j reversed.
			if y[j] <= x[i].RangeMax() {
				cu = append(cu, y[j])
				j++
			} else {
				i = x.lowerBound(i+1, len(x), jMin)
				if y[j] <= x[i-1].RangeMax() {
					i--
				}
			}
		} else {
			// i and j have the same RangeMin(), so one contains the other.
			if x[i] < y[j] {
				cu = append(cu, x[i])
				i++
			} else {
				cu = append(cu, y[j])
				j++
			}
		}
	}

	// The output is generated in sorted order.
	cu.Normalize()
	return cu
}