Files
renovate-sh-app[bot]GitHubrenovate-sh-app[bot] <219655108+renovate-sh-app[bot]@users.noreply.github.com>
6a21dc7e6d fix(deps): update module github.com/parquet-go/parquet-go to v0.27.0 (#6243)
| datasource | package                          | from    | to      |
| ---------- | -------------------------------- | ------- | ------- |
| go         | github.com/parquet-go/parquet-go | v0.26.4 | v0.27.0 |

Signed-off-by: renovate-sh-app[bot] <219655108+renovate-sh-app[bot]@users.noreply.github.com>
Co-authored-by: renovate-sh-app[bot] <219655108+renovate-sh-app[bot]@users.noreply.github.com>
2026-01-16 23:38:26 +00:00

179 lines
4.6 KiB
Go

package geom
import "math"
// A Bounds represents a multi-dimensional bounding box.
type Bounds struct {
layout Layout
min Coord
max Coord
}
// NewBounds creates a new Bounds.
func NewBounds(layout Layout) *Bounds {
stride := layout.Stride()
minValue, maxValue := make(Coord, stride), make(Coord, stride)
for i := range stride {
minValue[i], maxValue[i] = math.Inf(1), math.Inf(-1)
}
return &Bounds{
layout: layout,
min: minValue,
max: maxValue,
}
}
// Clone returns a deep copy of b.
func (b *Bounds) Clone() *Bounds {
return deriveCloneBounds(b)
}
// Extend extends b to include geometry g.
func (b *Bounds) Extend(g T) *Bounds {
b.extendLayout(g.Layout())
if b.layout == XYZM && g.Layout() == XYM {
return b.extendXYZMFlatCoordsWithXYM(g.FlatCoords(), 0, len(g.FlatCoords()))
}
return b.extendFlatCoords(g.FlatCoords(), 0, len(g.FlatCoords()), g.Stride())
}
// IsEmpty returns true if b is empty.
func (b *Bounds) IsEmpty() bool {
if b.layout == NoLayout {
return true
}
for i, stride := 0, b.layout.Stride(); i < stride; i++ {
if b.max[i] < b.min[i] {
return true
}
}
return false
}
// Layout returns b's layout.
func (b *Bounds) Layout() Layout {
return b.layout
}
// Max returns the maximum value in dimension dim.
func (b *Bounds) Max(dim int) float64 {
return b.max[dim]
}
// Min returns the minimum value in dimension dim.
func (b *Bounds) Min(dim int) float64 {
return b.min[dim]
}
// Overlaps returns true if b overlaps b2 in layout.
func (b *Bounds) Overlaps(layout Layout, b2 *Bounds) bool {
for i, stride := 0, layout.Stride(); i < stride; i++ {
if b.min[i] > b2.max[i] || b.max[i] < b2.min[i] {
return false
}
}
return true
}
// Polygon returns b as a two-dimensional Polygon.
func (b *Bounds) Polygon() *Polygon {
if b.IsEmpty() {
return NewPolygonFlat(XY, nil, nil)
}
x1, y1 := b.min[0], b.min[1]
x2, y2 := b.max[0], b.max[1]
flatCoords := []float64{
x1, y1,
x1, y2,
x2, y2,
x2, y1,
x1, y1,
}
return NewPolygonFlat(XY, flatCoords, []int{len(flatCoords)})
}
// Set sets the minimum and maximum values. args must be an even number of
// values: the first half are the minimum values for each dimension and the
// second half are the maximum values for each dimension. If necessary, the
// layout of b will be extended to cover all the supplied dimensions implied by
// args.
func (b *Bounds) Set(args ...float64) *Bounds {
if len(args)&1 != 0 {
panic("geom: even number of arguments required")
}
stride := len(args) / 2
b.extendStride(stride)
for i := range stride {
b.min[i], b.max[i] = args[i], args[i+stride]
}
return b
}
// SetCoords sets the minimum and maximum values of the Bounds.
func (b *Bounds) SetCoords(minCoord, maxCoord Coord) *Bounds {
b.min = Coord(make([]float64, b.layout.Stride()))
b.max = Coord(make([]float64, b.layout.Stride()))
for i := range b.layout.Stride() {
b.min[i] = math.Min(minCoord[i], maxCoord[i])
b.max[i] = math.Max(minCoord[i], maxCoord[i])
}
return b
}
// OverlapsPoint determines if the bounding box overlaps the point (point is
// within or on the border of the bounds).
func (b *Bounds) OverlapsPoint(layout Layout, point Coord) bool {
for i, stride := 0, layout.Stride(); i < stride; i++ {
if b.min[i] > point[i] || b.max[i] < point[i] {
return false
}
}
return true
}
func (b *Bounds) extendFlatCoords(flatCoords []float64, offset, end, stride int) *Bounds {
b.extendStride(stride)
for i := offset; i < end; i += stride {
for j := range stride {
b.min[j] = math.Min(b.min[j], flatCoords[i+j])
b.max[j] = math.Max(b.max[j], flatCoords[i+j])
}
}
return b
}
func (b *Bounds) extendLayout(layout Layout) {
switch {
case b.layout == XYZ && layout == XYM:
b.min = append(b.min, math.Inf(1))
b.max = append(b.max, math.Inf(-1))
b.layout = XYZM
case b.layout == XYM && (layout == XYZ || layout == XYZM):
b.min = append(b.min[:2], math.Inf(1), b.min[2])
b.max = append(b.max[:2], math.Inf(-1), b.max[2])
b.layout = XYZM
case b.layout < layout:
b.extendStride(layout.Stride())
b.layout = layout
}
}
func (b *Bounds) extendStride(stride int) {
for s := b.layout.Stride(); s < stride; s++ {
b.min = append(b.min, math.Inf(1))
b.max = append(b.max, math.Inf(-1))
}
}
func (b *Bounds) extendXYZMFlatCoordsWithXYM(flatCoords []float64, offset, end int) *Bounds {
for i := offset; i < end; i += 3 {
b.min[0] = math.Min(b.min[0], flatCoords[i+0])
b.max[0] = math.Max(b.max[0], flatCoords[i+0])
b.min[1] = math.Min(b.min[1], flatCoords[i+1])
b.max[1] = math.Max(b.max[1], flatCoords[i+1])
b.min[3] = math.Min(b.min[3], flatCoords[i+2])
b.max[3] = math.Max(b.max[3], flatCoords[i+2])
}
return b
}