package com.jonathan.survivor.math;
import com.badlogic.gdx.math.MathUtils;
/*
* A 2D Vector. Performs basic vector operations.
*/
public class Vector2
{
public static float TO_RADIANS = (1 / 180.0f) * (float) Math.PI; //Multiply an angle in degrees by this constant to convert it to radians.
public static float TO_DEGREES = (1 / (float) Math.PI) * 180; //Multiply an angle in radians by this constant to convert it to degrees.
public float x, y; //Stores the x and y components of the 2d vector.
/** Contructs a 2d vector with an x and y component of zero. */
public Vector2()
{
}
/** Contructs a 2d vector with given x and y components. */
public Vector2(float x, float y)
{
this.x = x;
this.y = y;
}
/** Constructs a vector using another vector's x and y components. */
public Vector2(Vector2 other)
{
this.x = other.x;
this.y = other.y;
}
/** Sets the x and y components of the vector. Returns the instance of this vector for easy chaining. */
public Vector2 set(float x, float y)
{
//Updates the components of the vector.
this.x = x;
this.y = y;
//Returns a reference to this vector to perform operations on it with chained method calls.
return this;
}
/** Copies the x and y components of another vector into this vector. Returns the instance of this vector for chained operations. */
public Vector2 set(Vector2 other)
{
//Copies the x and y components of the vector argument into this vector.
this.x = other.x;
this.y = other.y;
//Returns the instance of this vector in order to apply multiplications to it via chained method calls.
return this;
}
/** Adds the given amount to the x and y components of this Vector. Returns a reference of this vector to use in method chaining for multiple operations. */
public Vector2 add(float amount)
{
//Adds the given amount to the vector's x and y components.
this.x += amount;
this.y += amount;
//Returns a reference to this Vector2.
return this;
}
/** Adds the x and y arguments to the x and y components of this Vector. Returns a reference of this vector to use in method chaining for multiple operations. */
public Vector2 add(float x, float y)
{
//Adds the x and y values passed in to the vector's x and y components.
this.x += x;
this.y += y;
//Returns a reference to this Vector2.
return this;
}
/** Adds a vector to this vector. Done by adding the x and y components of the other vector to this vector. Returns the instance of this vector for use in operation chaining. */
public Vector2 add(Vector2 other)
{
//Adds the x and y components of the other vector to this vector.
this.x += other.x;
this.y += other.y;
//Returns a reference to this Vector2.
return this;
}
/** Subtracts the given amount from the x and y components of this Vector. Returns a reference of this vector to use in method chaining for multiple operations. */
public Vector2 sub (float amount)
{
//Subtracts the given amount from the vector's x and y components.
this.x -= amount;
this.y -= amount;
//Returns a reference to this Vector2.
return this;
}
/** Subtracts the x and y arguments from the x and y components of this Vector. Returns a reference of this vector to use in method chaining for multiple operations. */
public Vector2 sub(float x, float y)
{
//Subtracts the x and y arguments from this vector's x and y components.
this.x -= x;
this.y -= y;
//Returns a reference to this Vector2.
return this;
}
/** Adds a vector form this vector. Done by subtracting the x and y components of the other vector from this vector's x and y components. Returns the instance of this vector
* for use in operation chaining. */
public Vector2 sub(Vector2 other)
{
//Takes this vector's x and y components, and subtracts them by the other vector's x and y components.
this.x -= other.x;
this.y -= other.y;
//Returns a reference to this Vector2 for use in operation chaining via method chaining.
return this;
}
/** Multiplies this vector by a scalar. Done by multiplying the x and y components of this vector by the given argument. Returns the instance of this vector for use in
* operation chaining. */
public Vector2 mul(float scalar)
{
//Multiplies the x and y components of this vector by the scalar argument.
this.x *= scalar;
this.y *= scalar;
//Returns a reference to this Vector2 for use in operation chaining via method chaining.
return this;
}
/** Returns the magnitude of this vector. */
public float magnitude()
{
//Returns the magnitude of the vector via the pythagorean theorem (i.e., sqrt(x*x + y*y)). Note that the FloatMath.sqrt() method is faster than the Math.sqrt() method.
return (float)Math.sqrt(x*x + y*y);
}
/** Normalizes the vector. This means that we convert this vector into a unit vector with magnitude one. We return a reference to the normalized vector for use in chaining
* operations via chained method calls. */
public Vector2 normalize()
{
//Stores the magnitude of the vector.
float magnitude = magnitude();
//If the magnitude is not zero, normalize the vector. Otherwise, the vector is zero and does not need normalizing. Prevents an ArithmeticException.
if(magnitude != 0)
{
//Normalizes the vector by dividing its x and y components by its magnitude.
this.x /= magnitude;
this.y /= magnitude;
}
//Returns a reference to this Vector2 for use in operation chaining via method chaining.
return this;
}
/** Returns the angle formed by the vector, counterclockwise from the +x axis. Angle is in degrees, ranging from 0 to 360. */
public float angle()
{
//Finds the angle formed by the vector. We do this by finding the arctangent of (y/x). In this case, we pass the y component as the first argument and the x component
//as the second argument. The returned angle is in radians. We convert it to degrees.
float angle = (float) MathUtils.atan2(y, x) * TO_DEGREES;
//The angle returned by the arctangent method is between -180 and 180. Thus, if the angle is negative, we add 360 degrees to the angle. This makes it so that there
//are no negative angles. The angles will range from 0 to 360, counterclockwise from the +x axis.
if(angle < 0)
{
//Adds 360 degrees to the negative angle to prevent a negative angle.
angle += 360;
}
//Returns the angle formed by the vector.
return angle;
}
/** Returns the distance between this vector and another vector. Note that the value returned is a scalar quantity. */
public float distance(Vector2 other)
{
//Finds the difference in x and y components between this vector and the other vector. This finds the vector which points from the other vector to this vector.
//It wouldn't make a difference if we reversed the subtraction, as the magnitude of the distance vector would remain the same.
float distX = this.x - other.x;
float distY = this.y - other.y;
//Returns the magnitude of the distance between both vectors. This is done via the pythagorean theorem, using sqrt(x*x + y*y).
return (float)Math.sqrt(distX*distX + distY*distY);
}
/** Returns the distance between this vector and the given x and y components, which form another vector. Note that the value returned is a scalar distance quantity. */
public float distance(float x, float y)
{
//Finds the x and y distance between both vectors by subtracting their x and y components. Note which vector is subtracted by which other vector is irrelevent,
//since the magnitude of the resulting vector will be the same.
float distX = this.x - x;
float distY = this.y - y;
//Returns the magnitude of the distance between both vectors. This is done via the pythagorean theorem, using sqrt(x*x + y*y).
return (float)Math.sqrt(distX*distX + distY*distY);
}
/** Returns the distance squared between this vector and another vector. Note that this avoids using a square root, making it more cost-efficient. Should be used
* instead of the Vector2.dist() method, as it prevents the costly square-root function. */
public float distSquared(Vector2 other)
{
//Finds the x and y distance between both vectors by subtracting their x and y components. Note which vector is subtracted by which other vector is irrelevent,
//since the magnitude of the resulting vector will be the same.
float distX = this.x - other.x;
float distY = this.y - other.y;
//Returns the distance square between both vectors. This is done via the pythagorean theorem, using sqrt(x*x + y*y). However, we return the distance squared
//by avoiding the square root. This is cost-efficient.
return distX*distX + distY*distY;
}
/** Returns the distance squared between this vector and another vector with position (x,y). Note that this avoids using a square root, making it more cost-efficient.
* Should be used instead of the Vector2.dist() method, as it prevents the costly square-root function. */
public float distSquared(float x, float y)
{
//Finds the x and y distance between both vectors by subtracting their x and y components. Note which vector is subtracted by which other vector is irrelevent,
//since the magnitude of the resulting vector will be the same.
float distX = this.x - x;
float distY = this.y - y;
//Returns the distance square between both vectors. This is done via the pythagorean theorem, using sqrt(x*x + y*y). However, we return the distance squared
//by avoiding the square root. This is cost-efficient.
return distX*distX + distY*distY;
}
public String toString()
{
return "(" + x + ", " + y + ")";
}
}