commonMain.ru.casperix.math.iteration.Line2Iterator.kt Maven / Gradle / Ivy
package ru.casperix.math.iteration
import ru.casperix.math.vector.float64.Vector2d
import ru.casperix.math.geometry.Line2d
import ru.casperix.math.vector.int32.Vector2i
import kotlin.math.abs
import kotlin.math.floor
object Line2Iterator {
fun iterate(line: Line2d, onStep: (Vector2i) -> Boolean) {
iterateLineBresenham4o(line.v0, line.v1, onStep)
}
private fun iterateLineBresenham4o(v0: Vector2d, v1: Vector2d, onStep: (Vector2i) -> Boolean) {
val x0: Int = floor(v0.x).toInt()
val y0: Int = floor(v0.y).toInt()
val x1: Int = floor(v1.x).toInt()
val y1: Int = floor(v1.y).toInt()
val deltaX = (v1.x - v0.x)
val deltaY = (v1.y - v0.y)
val deltaXAbs = abs(deltaX)
val deltaYAbs = abs(deltaY)
val idX = abs(x1 - x0)
val idY = abs(y1 - y0)
val signX: Int = if (v0.x < v1.x) 1 else -1
val signY: Int = if (v0.y < v1.y) 1 else -1
val fractionalX = v0.x - x0 - 0.5
val fractionalY = v0.y - y0 - 0.5
var lastError = fractionalY * deltaXAbs * signY - fractionalX * deltaYAbs * signX
var x: Int = x0
var y: Int = y0
for (i in 0..(idX + idY)) {
if (!onStep(Vector2i(x, y))) return
val eX = lastError - deltaXAbs
val eY = lastError + deltaYAbs
if (abs(eY) < abs(eX)) {
x += signX
lastError = eY
} else {
y += signY
lastError = eX
}
}
}
}