aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt
blob: f973a4e6a7f6f699c70863bd78a881f4fd144551 (plain)
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package at.hannibal2.skyhanni.utils

import net.minecraft.entity.Entity
import net.minecraft.util.BlockPos
import net.minecraft.util.Rotations
import net.minecraft.util.Vec3
import kotlin.math.*

data class LorenzVec(
    val x: Double,
    val y: Double,
    val z: Double,
) {

    constructor(x: Int, y: Int, z: Int) : this(x.toDouble(), y.toDouble(), z.toDouble())

    constructor(x: Float, y: Float, z: Float) : this(x.toDouble(), y.toDouble(), z.toDouble())

    fun toBlocPos(): BlockPos = BlockPos(x, y, z)

    fun toVec3(): Vec3 = Vec3(x, y, z)

    fun distanceIgnoreY(other: LorenzVec): Double = distanceIgnoreYSq(other).pow(0.5)

    fun distance(other: LorenzVec): Double = distanceSq(other).pow(0.5)

    fun distanceSq(x: Double, y: Double, z: Double): Double = distanceSq(LorenzVec(x, y, z))

    fun distance(x: Double, y: Double, z: Double): Double = distance(LorenzVec(x, y, z))

    fun distanceSq(other: LorenzVec): Double {
        val dx = (other.x - x)
        val dy = (other.y - y)
        val dz = (other.z - z)
        return (dx * dx + dy * dy + dz * dz)
    }

    fun distanceIgnoreYSq(other: LorenzVec): Double {
        val dx = (other.x - x)
        val dz = (other.z - z)
        return (dx * dx + dz * dz)
    }

    fun add(x: Double, y: Double, z: Double): LorenzVec = LorenzVec(this.x + x, this.y + y, this.z + z)

    fun add(x: Int, y: Int, z: Int): LorenzVec = LorenzVec(this.x + x, this.y + y, this.z + z)

    override fun toString(): String {
        return "LorenzVec{" +
                "x=" + x +
                ", y=" + y +
                ", z=" + z +
                '}'
    }

    fun multiply(d: Double): LorenzVec = LorenzVec(x multiplyZeroSave d, y multiplyZeroSave d, z multiplyZeroSave d)

    fun multiply(d: Int): LorenzVec =
        LorenzVec(x multiplyZeroSave d.toDouble(), y multiplyZeroSave d.toDouble(), z multiplyZeroSave d.toDouble())

    fun add(other: LorenzVec) = LorenzVec(x + other.x, y + other.y, z + other.z)

    fun subtract(other: LorenzVec) = LorenzVec(x - other.x, y - other.y, z - other.z)

    fun printWithAccuracy(accuracy: Int): String {
        val x = (round(x * accuracy) / accuracy)
        val y = (round(y * accuracy) / accuracy)
        val z = (round(z * accuracy) / accuracy)
        return LorenzVec(x, y, z).toCleanString()
    }

    private fun toCleanString(): String {
        return "$x $y $z"
    }

    fun length(): Double {
        return sqrt(x * x + y * y + z * z)
    }

    //TODO make this class json serializable
    fun encodeToString(): String {
        return "$x:$y:$z"
    }

    fun isZero(): Boolean = x == 0.0 && y == 0.0 && z == 0.0

    fun clone(): LorenzVec = LorenzVec(x, y, z)

    fun toDoubleArray(): Array<Double> {
        return arrayOf(x, y, z)
    }

    companion object {
        fun getFromYawPitch(yaw: Double, pitch: Double): LorenzVec {
            val yaw: Double = (yaw + 90) * Math.PI / 180
            val pitch: Double = (pitch + 90) * Math.PI / 180

            val x = sin(pitch) * cos(yaw)
            val y = sin(pitch) * sin(yaw)
            val z = cos(pitch)
            return LorenzVec(x, z, y)
        }

        //TODO make this class json serializable
        fun decodeFromString(string: String): LorenzVec {
            val split = string.split(":")
            val x = split[0].toDouble()
            val y = split[1].toDouble()
            val z = split[2].toDouble()
            return LorenzVec(x, y, z)
        }
    }
}

private infix fun Double.multiplyZeroSave(other: Double): Double {
    val result = this * other
    return if (result == -0.0) 0.0 else result
}

fun BlockPos.toLorenzVec(): LorenzVec = LorenzVec(x, y, z)

fun Entity.getLorenzVec(): LorenzVec = LorenzVec(posX, posY, posZ)

fun Vec3.toLorenzVec(): LorenzVec = LorenzVec(xCoord, yCoord, zCoord)

fun Rotations.toLorenzVec(): LorenzVec = LorenzVec(x, y, z)

fun Array<Double>.toLorenzVec(): LorenzVec {
    return LorenzVec(this[0], this[1], this[2])
}