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

commonMain.ru.casperix.math.vector.float64.Vector2d.kt Maven / Gradle / Ivy

package ru.casperix.math.vector.float64

import ru.casperix.math.angle.float64.DegreeDouble
import ru.casperix.math.angle.float64.RadianDouble
import ru.casperix.math.axis_aligned.float64.Box2d
import ru.casperix.math.polar.float64.PolarCoordinateDouble
import ru.casperix.math.vector.api.AbstractVector2
import ru.casperix.math.vector.float32.Vector2f
import ru.casperix.math.vector.int32.Vector2i
import ru.casperix.misc.ceilToInt
import ru.casperix.misc.toPrecision
import kotlinx.serialization.Serializable
import kotlin.math.*


@Serializable
data class Vector2d(override val x: Double, override val y: Double) : AbstractVector2 {
    constructor() : this(0.0)

    constructor(i: Double) : this(i, i)

    companion object {
        val NaN = Vector2d(Double.NaN)
        val ZERO = Vector2d(0.0)
        val HALF = Vector2d(0.5)
        val ONE = Vector2d(1.0)
        val XY = ONE

        val X = Vector2d(1.0, 0.0)
        val Y = Vector2d(0.0, 1.0)
    }

    override val xAxis: Vector2d get() = Vector2d(x, 0.0)

    override val yAxis: Vector2d get() = Vector2d(0.0, y)

    fun rotate(angle: DegreeDouble): Vector2d {
        return rotate(angle.toRadian())
    }

    fun rotate(angle: RadianDouble): Vector2d {
        val polar = toPolar()
        return polar.copy(angle = polar.angle + angle).toDecart()
    }


    override fun axisProjection(useXAxis: Boolean): Vector2d {
        return if (useXAxis) xAxis else yAxis
    }

    override fun volume(): Double {
        return (x * y).absoluteValue
    }

    override fun distTo(other: Vector2d): Double {
        return (this - other).length()
    }

    override fun lengthOne(): Double {
        return abs(x) + abs(y)
    }

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

    override fun lengthInf(): Double {
        return max(abs(x), abs(y))
    }

    override fun lengthSquared(): Double {
        return x * x + y * y
    }

    override fun absoluteMinimum(): Double {
        return minOf(abs(x), abs(y))
    }

    override fun absoluteMaximum(): Double {
        return maxOf(abs(x), abs(y))
    }

    override val sign: Vector2d get() = Vector2d(x.sign, y.sign)

    override val absoluteValue: Vector2d get() = Vector2d(x.absoluteValue, y.absoluteValue)

    override fun dot(value: Vector2d): Double {
        return (this.x * value.x + this.y * value.y)
    }

    override fun mod(other: Vector2d): Vector2d {
        return Vector2d(x.mod(other.x), y.mod(other.y))
    }

    override fun upper(other: Vector2d): Vector2d {
        return Vector2d(max(x, other.x), max(y, other.y))
    }

    override fun lower(other: Vector2d): Vector2d {
        return Vector2d(min(x, other.x), min(y, other.y))
    }

    fun clamp(min: Vector2d, max: Vector2d): Vector2d {
        return upper(min).lower(max)
    }

    fun clamp(limit: Box2d): Vector2d {
        return clamp(limit.min, limit.max)
    }

    override operator fun plus(position: Vector2d): Vector2d {
        return Vector2d(x + position.x, y + position.y)
    }

    override operator fun minus(position: Vector2d): Vector2d {
        return Vector2d(x - position.x, y - position.y)
    }

    override operator fun div(value: Double): Vector2d {
        return Vector2d(x / value, y / value)
    }

    override operator fun div(value: Vector2d): Vector2d {
        return Vector2d(x / value.x, y / value.y)
    }

    override operator fun times(value: Double): Vector2d {
        return Vector2d(x * value, y * value)
    }

    override operator fun times(value: Vector2d): Vector2d {
        return Vector2d(x * value.x, y * value.y)
    }

    override operator fun unaryMinus(): Vector2d {
        return Vector2d(-x, -y)
    }

    override operator fun rem(value: Vector2d): Vector2d {
        return Vector2d(x % value.x, y % value.y)
    }

    override operator fun rem(value: Double): Vector2d {
        return Vector2d(x % value, y % value)
    }

    override fun greater(other: Vector2d): Boolean {
        return x > other.x && y > other.y
    }

    override fun greaterOrEq(other: Vector2d): Boolean {
        return x >= other.x && y >= other.y
    }

    override fun less(other: Vector2d): Boolean {
        return x < other.x && y < other.y
    }

    override fun lessOrEq(other: Vector2d): Boolean {
        return x <= other.x && y <= other.y
    }

    override fun normalize(): Vector2d {
        val len = length()
        return Vector2d(x / len, y / len)
    }

    override fun half(): Vector2d {
        return this * 0.5
    }

    override fun toVector2f(): Vector2f {
        return Vector2f(x.toFloat(), y.toFloat())
    }

    override fun toVector2i(): Vector2i {
        return Vector2i(x.toInt(), y.toInt())
    }

    override fun toVector2d(): Vector2d {
        return this
    }

    fun round(): Vector2d {
        return Vector2d(x.roundToInt().toDouble(), y.roundToInt().toDouble())
    }

    fun roundToVector2i(): Vector2i {
        return Vector2i(x.roundToInt(), y.roundToInt())
    }

    fun ceilToVector2i(): Vector2i {
        return Vector2i(x.ceilToInt(), y.ceilToInt())
    }

    fun cross(other: Vector2d): Double {
        return x * other.y - other.x * y
    }

    fun toPolar(): PolarCoordinateDouble {
        val range = length()
        val angle = RadianDouble.byDirection(this)
        return PolarCoordinateDouble(range, angle)
    }

    fun toPrecision(precision: Int): String {
        return "(${x.toPrecision(precision)}; ${y.toPrecision(precision)})"
    }

    fun isFinite(): Boolean {
        return x.isFinite() && y.isFinite()
    }

    fun addDimension(z: Double): Vector3d {
        return Vector3d(x, y, z)
    }

    fun expand(z: Double): Vector3d {
        return Vector3d(x, y, z)
    }

    override fun toString(): String {
        return "V2d(x=$x, y=$y)"
    }

    fun component(index: Int): Double {
        return when (index) {
            0 -> x
            1 -> y
            else -> throw Error("Only 2 components enabled")
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy