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

it.unibo.alchemist.model.interfaces.geometry.Vector2D.kt Maven / Gradle / Ivy

There is a newer version: 20.0.1
Show newest version
/*
 * Copyright (C) 2010-2020, Danilo Pianini and contributors
 * listed in the main project's alchemist/build.gradle.kts file.
 *
 * This file is part of Alchemist, and is distributed under the terms of the
 * GNU General Public License, with a linking exception,
 * as described in the file LICENSE in the Alchemist distribution's top directory.
 */

package it.unibo.alchemist.model.interfaces.geometry

import kotlin.math.atan2
import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.sqrt

/**
 * Bidimensional vector with [x] and [y] coordinates.
 */
interface Vector2D

> : Vector

{ /** * x coordinate. */ @JvmDefault val x get() = this[0] /** * y coordinate. */ @JvmDefault val y get() = this[1] /** * Computes the angle with atan2(y, x). * * @return atan2(y, x) (in radians) */ @JvmDefault val asAngle: Double get() = atan2(y, x) /** * Dot product between bidimensional vectors. */ @JvmDefault override fun dot(other: P) = x * other.x + y * other.y /** * Checks whether the given point is inside a rectangular region described by an [origin] * point and [width] and [height] values (only positive). */ @JvmDefault fun isInRectangle(origin: Vector2D<*>, width: Double, height: Double): Boolean = x >= origin.x && y >= origin.y && x <= origin.x + width && y <= origin.y + height /** * Creates a new Vector2D with the same type of the current one with different [x] and [y]. */ fun newFrom(x: Double, y: Double): P /** * Allows subtraction with a [Pair]. */ @JvmDefault operator fun minus(other: Pair) = newFrom(x - other.first, y - other.second) /** * Normalizes the vector. */ @JvmDefault override fun normalized(): P = times(1.0 / sqrt(x * x + y * y)) /** * Allows summaction with a [Pair]. */ @JvmDefault operator fun plus(other: Pair) = newFrom(x + other.first, y + other.second) /** * Computes a point which is at a certain [distance] and [angle] (in radians) from this one. */ @JvmDefault fun surroundingPointAt(angle: Double, distance: Double) = newFrom(x + cos(angle) * distance, y + sin(angle) * distance) /** * Computes a point which is at a certain [distance] and angle (expressed as a [versor] centered in this node) * from this one. */ @JvmDefault fun surroundingPointAt(versor: P, distance: Double) = surroundingPointAt(versor.asAngle, distance) /** * Creates a list of [count] points equally spaced in the circle of given [radius] with center in this vector. * * @param radius * the distance each generated position must have from this. * @param count * the number of positions to generate. */ @JvmDefault // @JvmOverloads disabled due to https://youtrack.jetbrains.com/issue/KT-12224 fun surrounding(radius: Double, count: Int = 12): List

= (1..count) .map { @Suppress("UNCHECKED_CAST") surroundingPointAt(angle = it * Math.PI * 2 / count, distance = radius) } companion object { /** * Computes the z component of the cross product of the given vectors. */ fun zCross(v1: Vector2D<*>, v2: Vector2D<*>) = v1.x * v2.y - v1.y * v2.x } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy