All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.ru.casperix.math.axis_aligned.int32.Box3i.kt Maven / Gradle / Ivy

package ru.casperix.math.axis_aligned.int32

import ru.casperix.math.axis_aligned.Box
import ru.casperix.math.iteration.Box3Iterator
import ru.casperix.math.vector.int32.Vector3i
import kotlinx.serialization.Serializable

@Serializable
data class Box3i(override val min: Vector3i, override val max: Vector3i) : Box {
	override val center = (max + min) / 2
	override val dimension: Vector3i = Vector3i.ONE + max - min
	override val volume: Int get() = dimension.x * dimension.y * dimension.z


	fun grow(value: Int): Box3i {
		return Box3i(min - Vector3i(value), max + Vector3i(value))
	}

	companion object {
		fun createOrNull(min: Vector3i, max: Vector3i): Box3i? {
			if (!(Vector3i.ONE + max - min).greaterOrEq(Vector3i.ZERO)) return null
			return Box3i(min, max)
		}

		fun byRadius(center: Vector3i, radius: Vector3i): Box3i {
			return Box3i(center - radius, center + radius)
		}

		fun byCorners(A: Vector3i, B: Vector3i): Box3i {
			val min = A.lower(B)
			val max = A.upper(B)
			return Box3i(min, max)
		}

		fun byDimension(pos: Vector3i, size: Vector3i): Box3i {
			return Box3i(pos, pos + size - Vector3i.ONE)
		}
	}

	init {
		if (!dimension.greaterOrEq(Vector3i.ZERO)) throw Error("Invalid box dimension $dimension");
	}

	override fun isInside(point: Vector3i): Boolean {
		return point.greaterOrEq(min) && point.lessOrEq(max)
	}

	fun isSide(pos: Vector3i): Boolean {
		return pos.x == min.x || pos.x == max.x || pos.y == min.y || pos.y == max.y || pos.z == min.z || pos.z == max.z
	}

	fun subdivide(): List? {
		val next = (max + Vector3i.ONE - min) / 2

		if (!min.less(next) || !next.less(max)) return null

		val xRanges = arrayOf(Pair(min.x, next.x - 1), Pair(next.x, max.x))
		val yRanges = arrayOf(Pair(min.y, next.y - 1), Pair(next.y, max.y))
		val zRanges = arrayOf(Pair(min.z, next.z - 1), Pair(next.z, max.z))

		val result = mutableListOf()

		for (x in 0..1) {
			for (y in 0..1) {
				for (z in 0..1) {
					val xRange = xRanges[x]
					val yRange = yRanges[y]
					val zRange = zRanges[z]
					result.add(Box3i(Vector3i(xRange.first, yRange.first, zRange.first), Vector3i(xRange.second, yRange.second, zRange.second)))
				}
			}
		}
		return result
	}

	operator fun iterator(): Iterator {
		return Box3Iterator(this)
	}

	override fun toString(): String {
		return "AABBox3i(min=$min, max=$max)"
	}

	operator fun plus(offset: Vector3i): Box3i {
		return Box3i(min + offset, max + offset)
	}

	fun intersection(other: Box3i): Box3i? {
		val nextMin = min.upper(other.min)
		val nextMax = max.lower(other.max)
		if (nextMin.lessOrEq(nextMax)) {
			return Box3i(nextMin, nextMax)
		}
		return null
	}

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy