buildBox<R extends Box> static method
R
buildBox<R extends Box>(})
Builds a bounding box of R
from coords
starting from offset
.
A bounding box instance is created using the factory function to
.
Supported coordinate value combinations by coordinate type:
Type | Expected values |
---|---|
xy | minX, minY, maxX, maxY |
xyz | minX, minY, minZ, maxX, maxY, maxZ |
xym | minX, minY, minM, maxX, maxY, maxM |
xyzm | minX, minY, minZ, minM, maxX, maxY, maxZ, maxM |
Use an optional type
to explicitely set the coordinate type. If not
provided and coords
has 6 items, then xyz coordinates are assumed.
Throws FormatException if coordinates are invalid.
Implementation
static R buildBox<R extends Box>(
Iterable<num> coords, {
required CreateBox<R> to,
int offset = 0,
Coords? type,
}) {
if (coords is List<num>) {
final len = coords.length - offset;
final coordsType = type ?? Coords.fromDimension(math.min(4, len ~/ 2));
final dim = coordsType.coordinateDimension;
if (len < 2 * dim) {
throw invalidCoordinates;
}
final mIndex = coordsType.indexForM;
return to.call(
minX: coords[offset],
minY: coords[offset + 1],
minZ: coordsType.is3D ? coords[offset + 2] : null,
minM: mIndex != null ? coords[offset + mIndex] : null,
maxX: coords[offset + dim],
maxY: coords[offset + dim + 1],
maxZ: coordsType.is3D ? coords[offset + dim + 2] : null,
maxM: mIndex != null ? coords[offset + dim + mIndex] : null,
);
} else {
// resolve iterator for source coordinates
final Iterator<num> iter;
if (offset == 0) {
iter = coords.iterator;
} else if (coords.length >= offset + 4) {
iter = coords.skip(offset).iterator;
} else {
throw invalidCoordinates;
}
// must contain at least four numbers
if (!iter.moveNext()) throw invalidCoordinates;
final c0 = iter.current;
if (!iter.moveNext()) throw invalidCoordinates;
final c1 = iter.current;
if (!iter.moveNext()) throw invalidCoordinates;
final c2 = iter.current;
if (!iter.moveNext()) throw invalidCoordinates;
final c3 = iter.current;
// rest 4 are optional, get first of them
final c4 = iter.moveNext() ? iter.current : null;
// if xy coordinates (4 items), then return already now
if (type == Coords.xy || (c4 == null && type == null)) {
return to.call(minX: c0, minY: c1, maxX: c2, maxY: c3);
}
// then get also last 3 of the optional
final c5 = iter.moveNext() ? iter.current : null;
final c6 = iter.moveNext() ? iter.current : null;
final c7 = iter.moveNext() ? iter.current : null;
// resolve coordinate type
final Coords coordType;
if (type != null) {
// explicitely
coordType = type;
} else {
// implicitely
if (c4 != null && c5 != null) {
coordType = c6 != null && c7 != null ? Coords.xyzm : Coords.xyz;
} else {
coordType = Coords.xy;
}
}
// create bounding box depending on coordinate type
switch (coordType) {
case Coords.xy:
if (c4 == null) {
return to.call(minX: c0, minY: c1, maxX: c2, maxY: c3);
}
break;
case Coords.xyz:
if (c4 != null && c5 != null && c6 == null) {
return to.call(
minX: c0,
minY: c1,
minZ: c2,
maxX: c3,
maxY: c4,
maxZ: c5,
);
}
break;
case Coords.xym:
if (c4 != null && c5 != null && c6 == null) {
return to.call(
minX: c0,
minY: c1,
minM: c2,
maxX: c3,
maxY: c4,
maxM: c5,
);
}
break;
case Coords.xyzm:
if (c4 != null && c5 != null && c6 != null && c7 != null) {
return to.call(
minX: c0,
minY: c1,
minZ: c2,
minM: c3,
maxX: c4,
maxY: c5,
maxZ: c6,
maxM: c7,
);
}
break;
}
throw invalidCoordinates;
}
}