intervals/overlap.go

75 lines
2.0 KiB
Go

package interval
import (
"fmt"
"math"
)
func (intvls *intervals) HasOverlapped() bool {
intvls.Overlapped()
if intvls.OverlappedList != nil && len(intvls.OverlappedList) > 0 {
return true
}
return false
}
func (intvls *intervals) Overlapped() []*Interval {
if intvls.OverlappedList == nil {
intvls.OverlappedList = intvls.calculateOverlapped()
}
return intvls.OverlappedList
}
func (intvls *intervals) calculateOverlapped() []*Interval {
list := []*Interval{}
if len(intvls.Intervals) == 0 {
return list
}
// sort intervals (if necessary)
intvls.Sort()
lastMinLow := math.MaxInt64
lastMaxHigh := math.MinInt64
firstInitDone := false
for _, intvl := range intvls.Intervals {
// convert if necessary exclusive low/high values into inclusive ones
low, high, err := intvls.getInclusives(intvl.Low, intvl.High)
if err != nil {
fmt.Printf("calculateOverlapped - unable to get inclusives: %v", err)
continue
}
// for the first iteration make no sense those operations
if firstInitDone {
// check if the front or back side of the current segment overlaps with the previous one
lowInBetween := isLowInBetweenInclusive(lastMinLow, lastMaxHigh, low, high)
highInBetween := isHighInBetweenInclusive(lastMinLow, lastMaxHigh, low, high)
if lowInBetween || highInBetween {
// extract which part is overlapped, create a new interval and add it to the list
biggestLow := max(low, lastMinLow)
smallestHigh := min(high, lastMaxHigh)
list = append(list, &Interval{Low: biggestLow, High: smallestHigh})
}
}
// update control variables (if necessary)
if low < lastMinLow {
lastMinLow = low
}
if high > lastMaxHigh {
lastMaxHigh = high
}
firstInitDone = true
}
return list
}
func (intvls *intervals) valueIsOverlapping(value int, overlapped []*Interval) bool {
for _, ovrlp := range overlapped {
if inBetween(value, ovrlp.Low, ovrlp.High, intvls.LowInclusive, intvls.HighInclusive) {
return true
}
}
return false
}