1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
package coffee.liz.ecs
import kotlin.math.sqrt
/**
* Rectangle in cartesian space.
*/
data class Rect(
val topLeft: Vec2,
val dimensions: Vec2,
) {
fun contains(point: Vec2): Boolean =
point.x >= topLeft.x &&
point.x <= topLeft.x + dimensions.x &&
point.y >= topLeft.y &&
point.y <= topLeft.y + dimensions.y
fun overlaps(other: Rect): Boolean {
val xOverlap =
topLeft.x <= other.topLeft.x + other.dimensions.x &&
topLeft.x + dimensions.x >= other.topLeft.x
val yOverlap =
topLeft.y <= other.topLeft.y + other.dimensions.y &&
topLeft.y + dimensions.y >= other.topLeft.y
return xOverlap && yOverlap
}
fun split(newDimensions: Vec2): List<List<Rect>> = List(
(dimensions.y / newDimensions.y).toInt()
) { y ->
List(
(dimensions.x / newDimensions.x).toInt()
) { x ->
Rect(
topLeft = topLeft.plus(Vec2(x * newDimensions.x, y * newDimensions.y)),
dimensions = newDimensions,
)
}
}
}
/**
* Cartesian point.
*/
data class Vec2(
val x: Float,
val y: Float,
) {
fun plus(other: Vec2): Vec2 = Vec2(x + other.x, y + other.y)
fun minus(other: Vec2): Vec2 = Vec2(x - other.x, y - other.y)
fun scale(x: Float, y: Float): Vec2 = Vec2(this.x * x, this.y * y)
fun distanceTo(other: Vec2): Float = (this.minus(other)).length()
fun normalize(): Vec2 = this.scale(1 / length(), 1 / length())
fun length(): Float = sqrt(x * x + y * y)
}
/**
* Cardinal directions.
*/
enum class CardinalDirection(
val direction: Vec2,
) {
NORTH(Vec2(0f, -1f)),
SOUTH(Vec2(0f, 1f)),
WEST(Vec2(-1f, 0f)),
EAST(Vec2(1f, 0f)),
}
|