ball, raw injector float -> double

Former-commit-id: 19e44a1a5400bcf423a9cbb0c076eda48a1313d8
Former-commit-id: 73b3c09b0949f7b463de45b7f436b986445554f6
This commit is contained in:
Song Minjae
2016-05-01 20:05:39 +09:00
parent 05b374bfa7
commit f3050736be
5 changed files with 877 additions and 782 deletions

View File

@@ -71,8 +71,9 @@ open class ActorWithBody constructor() : Actor(), Visible {
var scale: Double
get() = actorValue.getAsDouble(AVKey.SCALE) ?: 1.0
set(value) = actorValue.set(AVKey.SCALE, value)
val mass: Double
var mass: Double
get() = actorValue.getAsDouble(AVKey.BASEMASS) ?: MASS_DEFAULT * Math.pow(scale, 3.0)
set(value) = actorValue.set(AVKey.BASEMASS, value)
@Transient private val MASS_LOWEST = 2.0
/** Valid range: [0, 1] */
var elasticity = 0.0

View File

@@ -27,19 +27,19 @@ object CreatureRawInjector {
val jsonObj = JsonFetcher.readJson(JSONPATH + jsonFileName)
val elementsString = arrayOf(AVKey.RACENAME, AVKey.RACENAMEPLURAL)
val elementsFloat = arrayOf(AVKey.BASEHEIGHT, AVKey.BASEMASS, AVKey.ACCEL, AVKey.TOOLSIZE, AVKey.ENCUMBRANCE)
val elementsFloatVariable = arrayOf(AVKey.STRENGTH, AVKey.SPEED, AVKey.JUMPPOWER, AVKey.SCALE, AVKey.SPEED)
val elementsDouble = arrayOf(AVKey.BASEHEIGHT, AVKey.BASEMASS, AVKey.ACCEL, AVKey.TOOLSIZE, AVKey.ENCUMBRANCE)
val elementsDoubleVariable = arrayOf(AVKey.STRENGTH, AVKey.SPEED, AVKey.JUMPPOWER, AVKey.SCALE, AVKey.SPEED)
val elementsBoolean = arrayOf(AVKey.INTELLIGENT)
// val elementsMultiplyFromOne = arrayOf()
setAVStrings(actorValueRef, elementsString, jsonObj)
setAVFloats(actorValueRef, elementsFloat, jsonObj)
setAVFloatsVariable(actorValueRef, elementsFloatVariable, jsonObj)
setAVDoubles(actorValueRef, elementsDouble, jsonObj)
setAVDoublesVariable(actorValueRef, elementsDoubleVariable, jsonObj)
// setAVMultiplyFromOne(actorValueRef, elementsMultiplyFromOne, jsonObj)
setAVBooleans(actorValueRef, elementsBoolean, jsonObj)
actorValueRef[AVKey.ACCEL] = Player.WALK_ACCEL_BASE
actorValueRef[AVKey.ACCELMULT] = 1f
actorValueRef[AVKey.ACCELMULT] = 1.0
}
/**
@@ -50,17 +50,17 @@ object CreatureRawInjector {
* *
* @param jsonObject
*/
private fun setAVFloatsVariable(avRef: ActorValue, elemSet: Array<String>, jsonObject: JsonObject) {
private fun setAVDoublesVariable(avRef: ActorValue, elemSet: Array<String>, jsonObject: JsonObject) {
for (s in elemSet) {
val baseValue = jsonObject.get(s).asFloat
val baseValue = jsonObject.get(s).asDouble
// roll fudge dice and get value [-3, 3] as [0, 6]
val varSelected = Fudge3(SecureRandom()).rollForArray()
// get multiplier from json. Assuming percentile
val multiplier = jsonObject.get(s + MULTIPLIER_RAW_ELEM_SUFFIX).asJsonArray.get(varSelected).asInt
val realValue = baseValue * multiplier / 100f
val realValue = baseValue * multiplier / 100.0
avRef[s] = realValue
avRef[s + MULTIPLIER_RAW_ELEM_SUFFIX] = 1.0f // use multiplied value as 'base' for all sort of things
avRef[s + MULTIPLIER_RAW_ELEM_SUFFIX] = 1.0 // use multiplied value as 'base' for all sort of things
}
}
@@ -80,16 +80,16 @@ object CreatureRawInjector {
}
/**
* Fetch and set float actor values
* Fetch and set double actor values
* @param avRef
* *
* @param elemSet
* *
* @param jsonObject
*/
private fun setAVFloats(avRef: ActorValue, elemSet: Array<String>, jsonObject: JsonObject) {
private fun setAVDoubles(avRef: ActorValue, elemSet: Array<String>, jsonObject: JsonObject) {
for (s in elemSet) {
avRef[s] = jsonObject.get(s).asFloat
avRef[s] = jsonObject.get(s).asDouble
}
}
@@ -104,12 +104,12 @@ object CreatureRawInjector {
*/
private fun setAVMultiplyFromOne(avRef: ActorValue, elemSet: Array<String>, jsonObject: JsonObject) {
for (s in elemSet) {
val baseValue = 1f
val baseValue = 1.0
// roll fudge dice and get value [-3, 3] as [0, 6]
val varSelected = Fudge3(SecureRandom()).rollForArray()
// get multiplier from json. Assuming percentile
val multiplier = jsonObject.get(s).asJsonArray.get(varSelected).asInt
val realValue = baseValue * multiplier / 100f
val realValue = baseValue * multiplier / 100.0
avRef[s] = realValue
}

View File

@@ -15,7 +15,7 @@ class PhysTestBall : ActorWithBody {
constructor(): super() {
setHitboxDimension(16, 16, 0, 0)
isVisible = true
actorValue[AVKey.BASEMASS] = 10f
actorValue[AVKey.BASEMASS] = 10.0
color = RoguelikeRandomiser.composeColourFrom(RoguelikeRandomiser.POTION_PRIMARY_COLSET)
}

View File

@@ -1,766 +0,0 @@
/*
* Copyright (c) 2010-2015 William Bittle http://www.dyn4j.org/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.dyn4j.geometry;
import org.dyn4j.Epsilon;
/**
* This class represents a vector or point in 2D space.
* <p>
* The operations {@link Vector2#setMagnitude(double)}, {@link Vector2#getNormalized()},
* {@link Vector2#project(Vector2)}, and {@link Vector2#normalize()} require the {@link Vector2}
* to be non-zero in length.
* <p>
* Some methods also return the vector to facilitate chaining. For example:
* <pre>
* Vector a = new Vector();
* a.zero().add(1, 2).multiply(2);
* </pre>
* @author William Bittle
* @version 3.1.11
* @since 1.0.0
*/
public class Vector2 {
/** A vector representing the x-axis; this vector should not be changed at runtime; used internally */
static final Vector2 X_AXIS = new Vector2(1.0, 0.0);
/** A vector representing the y-axis; this vector should not be changed at runtime; used internally */
static final Vector2 Y_AXIS = new Vector2(0.0, 1.0);
/** The magnitude of the x component of this {@link Vector2} */
public double x;
/** The magnitude of the y component of this {@link Vector2} */
public double y;
/** Default constructor. */
public Vector2() {}
/**
* Copy constructor.
* @param vector the {@link Vector2} to copy from
*/
public Vector2(Vector2 vector) {
this.x = vector.x;
this.y = vector.y;
}
/**
* Optional constructor.
* @param x the x component
* @param y the y component
*/
public Vector2(double x, double y) {
this.x = x;
this.y = y;
}
/**
* Creates a {@link Vector2} from the first point to the second point.
* @param x1 the x coordinate of the first point
* @param y1 the y coordinate of the first point
* @param x2 the x coordinate of the second point
* @param y2 the y coordinate of the second point
*/
public Vector2(double x1, double y1, double x2, double y2) {
this.x = x2 - x1;
this.y = y2 - y1;
}
/**
* Creates a {@link Vector2} from the first point to the second point.
* @param p1 the first point
* @param p2 the second point
*/
public Vector2(Vector2 p1, Vector2 p2) {
this.x = p2.x - p1.x;
this.y = p2.y - p1.y;
}
/**
* Creates a unit length vector in the given direction.
* @param direction the direction in radians
* @since 3.0.1
*/
public Vector2(double direction) {
this.x = Math.cos(direction);
this.y = Math.sin(direction);
}
/**
* Returns a new {@link Vector2} given the magnitude and direction.
* @param magnitude the magnitude of the {@link Vector2}
* @param direction the direction of the {@link Vector2} in radians
* @return {@link Vector2}
*/
public static Vector2 create(double magnitude, double direction) {
double x = magnitude * Math.cos(direction);
double y = magnitude * Math.sin(direction);
return new Vector2(x, y);
}
/**
* Returns a copy of this {@link Vector2}.
* @return {@link Vector2}
*/
public Vector2 copy() {
return new Vector2(this.x, this.y);
}
/**
* Returns the distance from this point to the given point.
* @param x the x coordinate of the point
* @param y the y coordinate of the point
* @return double
*/
public double distance(double x, double y) {
//return Math.hypot(this.x - x, this.y - y);
double dx = this.x - x;
double dy = this.y - y;
return Math.sqrt(dx * dx + dy * dy);
}
/**
* Returns the distance from this point to the given point.
* @param point the point
* @return double
*/
public double distance(Vector2 point) {
//return Math.hypot(this.x - point.x, this.y - point.y);
double dx = this.x - point.x;
double dy = this.y - point.y;
return Math.sqrt(dx * dx + dy * dy);
}
/**
* Returns the distance from this point to the given point squared.
* @param x the x coordinate of the point
* @param y the y coordinate of the point
* @return double
*/
public double distanceSquared(double x, double y) {
//return (this.x - x) * (this.x - x) + (this.y - y) * (this.y - y);
double dx = this.x - x;
double dy = this.y - y;
return dx * dx + dy * dy;
}
/**
* Returns the distance from this point to the given point squared.
* @param point the point
* @return double
*/
public double distanceSquared(Vector2 point) {
//return (this.x - point.x) * (this.x - point.x) + (this.y - point.y) * (this.y - point.y);
double dx = this.x - point.x;
double dy = this.y - point.y;
return dx * dx + dy * dy;
}
/**
* The triple product of {@link Vector2}s is defined as:
* <pre>
* a x (b x c)
* </pre>
* However, this method performs the following triple product:
* <pre>
* (a x b) x c
* </pre>
* this can be simplified to:
* <pre>
* -a * (b &middot; c) + b * (a &middot; c)
* </pre>
* or:
* <pre>
* b * (a &middot; c) - a * (b &middot; c)
* </pre>
* @param a the a {@link Vector2} in the above equation
* @param b the b {@link Vector2} in the above equation
* @param c the c {@link Vector2} in the above equation
* @return {@link Vector2}
*/
public static Vector2 tripleProduct(Vector2 a, Vector2 b, Vector2 c) {
// expanded version of above formula
Vector2 r = new Vector2();
// perform a.dot(c)
double ac = a.x * c.x + a.y * c.y;
// perform b.dot(c)
double bc = b.x * c.x + b.y * c.y;
// perform b * a.dot(c) - a * b.dot(c)
r.x = b.x * ac - a.x * bc;
r.y = b.y * ac - a.y * bc;
return r;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(x);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(y);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (obj == this) return true;
if (obj instanceof Vector2) {
Vector2 vector = (Vector2)obj;
return this.x == vector.x && this.y == vector.y;
}
return false;
}
/**
* Returns true if the x and y components of this {@link Vector2}
* are the same as the given {@link Vector2}.
* @param vector the {@link Vector2} to compare to
* @return boolean
*/
public boolean equals(Vector2 vector) {
if (vector == null) return false;
if (this == vector) {
return true;
} else {
return this.x == vector.x && this.y == vector.y;
}
}
/**
* Returns true if the x and y components of this {@link Vector2}
* are the same as the given x and y components.
* @param x the x coordinate of the {@link Vector2} to compare to
* @param y the y coordinate of the {@link Vector2} to compare to
* @return boolean
*/
public boolean equals(double x, double y) {
return this.x == x && this.y == y;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("(")
.append(this.x)
.append(", ")
.append(this.y)
.append(")");
return sb.toString();
}
/**
* Sets this {@link Vector2} to the given {@link Vector2}.
* @param vector the {@link Vector2} to set this {@link Vector2} to
* @return {@link Vector2} this vector
*/
public Vector2 set(Vector2 vector) {
this.x = vector.x;
this.y = vector.y;
return this;
}
/**
* Sets this {@link Vector2} to the given {@link Vector2}.
* @param x the x component of the {@link Vector2} to set this {@link Vector2} to
* @param y the y component of the {@link Vector2} to set this {@link Vector2} to
* @return {@link Vector2} this vector
*/
public Vector2 set(double x, double y) {
this.x = x;
this.y = y;
return this;
}
/**
* Returns the x component of this {@link Vector2}.
* @return {@link Vector2}
*/
public Vector2 getXComponent() {
return new Vector2(this.x, 0.0);
}
/**
* Returns the y component of this {@link Vector2}.
* @return {@link Vector2}
*/
public Vector2 getYComponent() {
return new Vector2(0.0, this.y);
}
/**
* Returns the magnitude of this {@link Vector2}.
* @return double
*/
public double getMagnitude() {
// the magnitude is just the pathagorean theorem
return Math.sqrt(this.x * this.x + this.y * this.y);
}
/**
* Returns the magnitude of this {@link Vector2} squared.
* @return double
*/
public double getMagnitudeSquared() {
return this.x * this.x + this.y * this.y;
}
/**
* Sets the magnitude of the {@link Vector2}.
* @param magnitude the magnitude
* @return {@link Vector2} this vector
*/
public Vector2 setMagnitude(double magnitude) {
// check the given magnitude
if (Math.abs(magnitude) <= Epsilon.E) {
this.x = 0.0;
this.y = 0.0;
return this;
}
// is this vector a zero vector?
if (this.isZero()) {
return this;
}
// get the magnitude
double mag = Math.sqrt(this.x * this.x + this.y * this.y);
// normalize and multiply by the new magnitude
mag = magnitude / mag;
this.x *= mag;
this.y *= mag;
return this;
}
/**
* Returns the direction of this {@link Vector2}
* as an angle in radians.
* @return double angle in radians [-&pi;, &pi;]
*/
public double getDirection() {
return Math.atan2(this.y, this.x);
}
/**
* Sets the direction of this {@link Vector2}.
* @param angle angle in radians
* @return {@link Vector2} this vector
*/
public Vector2 setDirection(double angle) {
//double magnitude = Math.hypot(this.x, this.y);
double magnitude = Math.sqrt(this.x * this.x + this.y * this.y);
this.x = magnitude * Math.cos(angle);
this.y = magnitude * Math.sin(angle);
return this;
}
/**
* Adds the given {@link Vector2} to this {@link Vector2}.
* @param vector the {@link Vector2}
* @return {@link Vector2} this vector
*/
public Vector2 add(Vector2 vector) {
this.x += vector.x;
this.y += vector.y;
return this;
}
/**
* Adds the given {@link Vector2} to this {@link Vector2}.
* @param x the x component of the {@link Vector2}
* @param y the y component of the {@link Vector2}
* @return {@link Vector2} this vector
*/
public Vector2 add(double x, double y) {
this.x += x;
this.y += y;
return this;
}
/**
* Adds this {@link Vector2} and the given {@link Vector2} returning
* a new {@link Vector2} containing the result.
* @param vector the {@link Vector2}
* @return {@link Vector2}
*/
public Vector2 sum(Vector2 vector) {
return new Vector2(this.x + vector.x, this.y + vector.y);
}
/**
* Adds this {@link Vector2} and the given {@link Vector2} returning
* a new {@link Vector2} containing the result.
* @param x the x component of the {@link Vector2}
* @param y the y component of the {@link Vector2}
* @return {@link Vector2}
*/
public Vector2 sum(double x, double y) {
return new Vector2(this.x + x, this.y + y);
}
/**
* Subtracts the given {@link Vector2} from this {@link Vector2}.
* @param vector the {@link Vector2}
* @return {@link Vector2} this vector
*/
public Vector2 subtract(Vector2 vector) {
this.x -= vector.x;
this.y -= vector.y;
return this;
}
/**
* Subtracts the given {@link Vector2} from this {@link Vector2}.
* @param x the x component of the {@link Vector2}
* @param y the y component of the {@link Vector2}
* @return {@link Vector2} this vector
*/
public Vector2 subtract(double x, double y) {
this.x -= x;
this.y -= y;
return this;
}
/**
* Subtracts the given {@link Vector2} from this {@link Vector2} returning
* a new {@link Vector2} containing the result.
* @param vector the {@link Vector2}
* @return {@link Vector2}
*/
public Vector2 difference(Vector2 vector) {
return new Vector2(this.x - vector.x, this.y - vector.y);
}
/**
* Subtracts the given {@link Vector2} from this {@link Vector2} returning
* a new {@link Vector2} containing the result.
* @param x the x component of the {@link Vector2}
* @param y the y component of the {@link Vector2}
* @return {@link Vector2}
*/
public Vector2 difference(double x, double y) {
return new Vector2(this.x - x, this.y - y);
}
/**
* Creates a {@link Vector2} from this {@link Vector2} to the given {@link Vector2}.
* @param vector the {@link Vector2}
* @return {@link Vector2}
*/
public Vector2 to(Vector2 vector) {
return new Vector2(vector.x - this.x, vector.y - this.y);
}
/**
* Creates a {@link Vector2} from this {@link Vector2} to the given {@link Vector2}.
* @param x the x component of the {@link Vector2}
* @param y the y component of the {@link Vector2}
* @return {@link Vector2}
*/
public Vector2 to(double x, double y) {
return new Vector2(x - this.x, y - this.y);
}
/**
* Multiplies this {@link Vector2} by the given scalar.
* @param scalar the scalar
* @return {@link Vector2} this vector
*/
public Vector2 multiply(double scalar) {
this.x *= scalar;
this.y *= scalar;
return this;
}
/**
* Multiplies this {@link Vector2} by the given scalar returning
* a new {@link Vector2} containing the result.
* @param scalar the scalar
* @return {@link Vector2}
*/
public Vector2 product(double scalar) {
return new Vector2(this.x * scalar, this.y * scalar);
}
/**
* Returns the dot product of the given {@link Vector2}
* and this {@link Vector2}.
* @param vector the {@link Vector2}
* @return double
*/
public double dot(Vector2 vector) {
return this.x * vector.x + this.y * vector.y;
}
/**
* Returns the dot product of the given {@link Vector2}
* and this {@link Vector2}.
* @param x the x component of the {@link Vector2}
* @param y the y component of the {@link Vector2}
* @return double
*/
public double dot(double x, double y) {
return this.x * x + this.y * y;
}
/**
* Returns the cross product of the this {@link Vector2} and the given {@link Vector2}.
* @param vector the {@link Vector2}
* @return double
*/
public double cross(Vector2 vector) {
return this.x * vector.y - this.y * vector.x;
}
/**
* Returns the cross product of the this {@link Vector2} and the given {@link Vector2}.
* @param x the x component of the {@link Vector2}
* @param y the y component of the {@link Vector2}
* @return double
*/
public double cross(double x, double y) {
return this.x * y - this.y * x;
}
/**
* Returns the cross product of this {@link Vector2} and the z value of the right {@link Vector2}.
* @param z the z component of the {@link Vector2}
* @return {@link Vector2}
*/
public Vector2 cross(double z) {
return new Vector2(-1.0 * this.y * z, this.x * z);
}
/**
* Returns true if the given {@link Vector2} is orthogonal (perpendicular)
* to this {@link Vector2}.
* <p>
* If the dot product of this vector and the given vector is
* zero then we know that they are perpendicular
* @param vector the {@link Vector2}
* @return boolean
*/
public boolean isOrthogonal(Vector2 vector) {
return Math.abs(this.x * vector.x + this.y * vector.y) <= Epsilon.E ? true : false;
}
/**
* Returns true if the given {@link Vector2} is orthogonal (perpendicular)
* to this {@link Vector2}.
* <p>
* If the dot product of this vector and the given vector is
* zero then we know that they are perpendicular
* @param x the x component of the {@link Vector2}
* @param y the y component of the {@link Vector2}
* @return boolean
*/
public boolean isOrthogonal(double x, double y) {
return Math.abs(this.x * x + this.y * y) <= Epsilon.E ? true : false;
}
/**
* Returns true if this {@link Vector2} is the zero {@link Vector2}.
* @return boolean
*/
public boolean isZero() {
return Math.abs(this.x) <= Epsilon.E && Math.abs(this.y) <= Epsilon.E;
}
/**
* Negates this {@link Vector2}.
* @return {@link Vector2} this vector
*/
public Vector2 negate() {
this.x *= -1.0;
this.y *= -1.0;
return this;
}
/**
* Returns a {@link Vector2} which is the negative of this {@link Vector2}.
* @return {@link Vector2}
*/
public Vector2 getNegative() {
return new Vector2(-this.x, -this.y);
}
/**
* Sets the {@link Vector2} to the zero {@link Vector2}
* @return {@link Vector2} this vector
*/
public Vector2 zero() {
this.x = 0.0;
this.y = 0.0;
return this;
}
/**
* Rotates about the origin.
* @param theta the rotation angle in radians
* @return {@link Vector2} this vector
*/
public Vector2 rotate(double theta) {
double cos = Math.cos(theta);
double sin = Math.sin(theta);
double x = this.x;
double y = this.y;
this.x = x * cos - y * sin;
this.y = x * sin + y * cos;
return this;
}
/**
* Rotates the {@link Vector2} about the given coordinates.
* @param theta the rotation angle in radians
* @param x the x coordinate to rotate about
* @param y the y coordinate to rotate about
* @return {@link Vector2} this vector
*/
public Vector2 rotate(double theta, double x, double y) {
this.x -= x;
this.y -= y;
this.rotate(theta);
this.x += x;
this.y += y;
return this;
}
/**
* Rotates the {@link Vector2} about the given point.
* @param theta the rotation angle in radians
* @param point the point to rotate about
* @return {@link Vector2} this vector
*/
public Vector2 rotate(double theta, Vector2 point) {
return this.rotate(theta, point.x, point.y);
}
/**
* Projects this {@link Vector2} onto the given {@link Vector2}.
* @param vector the {@link Vector2}
* @return {@link Vector2} the projected {@link Vector2}
*/
public Vector2 project(Vector2 vector) {
double dotProd = this.dot(vector);
double denominator = vector.dot(vector);
if (denominator <= Epsilon.E) return new Vector2();
denominator = dotProd / denominator;
return new Vector2(denominator * vector.x, denominator * vector.y);
}
/**
* Returns the right-handed normal of this vector.
* @return {@link Vector2} the right hand orthogonal {@link Vector2}
*/
public Vector2 getRightHandOrthogonalVector() {
return new Vector2(-this.y, this.x);
}
/**
* Sets this vector to the right-handed normal of this vector.
* @return {@link Vector2} this vector
* @see #getRightHandOrthogonalVector()
*/
public Vector2 right() {
double temp = this.x;
this.x = -this.y;
this.y = temp;
return this;
}
/**
* Returns the left-handed normal of this vector.
* @return {@link Vector2} the left hand orthogonal {@link Vector2}
*/
public Vector2 getLeftHandOrthogonalVector() {
return new Vector2(this.y, -this.x);
}
/**
* Sets this vector to the left-handed normal of this vector.
* @return {@link Vector2} this vector
* @see #getLeftHandOrthogonalVector()
*/
public Vector2 left() {
double temp = this.x;
this.x = this.y;
this.y = -temp;
return this;
}
/**
* Returns a unit {@link Vector2} of this {@link Vector2}.
* <p>
* This method requires the length of this {@link Vector2} is not zero.
* @return {@link Vector2}
*/
public Vector2 getNormalized() {
double magnitude = this.getMagnitude();
if (magnitude <= Epsilon.E) return new Vector2();
magnitude = 1.0 / magnitude;
return new Vector2(this.x * magnitude, this.y * magnitude);
}
/**
* Converts this {@link Vector2} into a unit {@link Vector2} and returns
* the magnitude before normalization.
* <p>
* This method requires the length of this {@link Vector2} is not zero.
* @return double
*/
public double normalize() {
double magnitude = Math.sqrt(this.x * this.x + this.y * this.y);
if (magnitude <= Epsilon.E) return 0;
double m = 1.0 / magnitude;
this.x *= m;
this.y *= m;
//return 1.0 / m;
return magnitude;
}
/**
* Returns the smallest angle between the given {@link Vector2}s.
* <p>
* Returns the angle in radians in the range -&pi; to &pi;.
* @param vector the {@link Vector2}
* @return angle in radians [-&pi;, &pi;]
*/
public double getAngleBetween(Vector2 vector) {
double a = Math.atan2(vector.y, vector.x) - Math.atan2(this.y, this.x);
if (a > Math.PI) return a - 2.0 * Math.PI;
if (a < -Math.PI) return a + 2.0 * Math.PI;
return a;
}
}

View File

@@ -0,0 +1,860 @@
/*
* Copyright (c) 2010-2015 William Bittle http://www.dyn4j.org/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Kotlin translated and modified code Copyright (c) 2016 Torvald aka skyhi14.
*/
package org.dyn4j.geometry
import org.dyn4j.Epsilon
/**
* This class represents a vector or point in 2D space.
*
*
* The operations [Vector2.setMagnitude], [Vector2.getNormalized],
* [Vector2.project], and [Vector2.normalize] require the [Vector2]
* to be non-zero in length.
*
*
* Some methods also return the vector to facilitate chaining. For example:
*
* Vector a = new Vector();
* a.zero().plus(1, 2).times(2);
*
* In this Kotlin code, you can use regular operations like + - * /.
*
* |operator|function|
* |--------|--------|
* |a + b|a.plus(b)|
* |a - b|a.minus(b)|
* |a * b|a.times(b)|
* |a / b|a.div(b)|
* |a dot b|a.dot(b)|
* |a cross b|a.cross(b)|
* |!a|negate(a)|
* |a rotate th|a.rotate(th)|
*
* @author William Bittle
* *
* @version 3.1.11
* *
* @since 1.0.0
*/
class Vector2 {
/** The magnitude of the x component of this [Vector2] */
var x: Double = 0.toDouble()
/** The magnitude of the y component of this [Vector2] */
var y: Double = 0.toDouble()
/** Default constructor. */
constructor() {
}
/**
* Copy constructor.
* @param vector the [Vector2] to copy from
*/
constructor(vector: Vector2) {
this.x = vector.x
this.y = vector.y
}
/**
* Optional constructor.
* @param x the x component
* *
* @param y the y component
*/
constructor(x: Double, y: Double) {
this.x = x
this.y = y
}
/**
* Creates a [Vector2] from the first point to the second point.
* @param x1 the x coordinate of the first point
* *
* @param y1 the y coordinate of the first point
* *
* @param x2 the x coordinate of the second point
* *
* @param y2 the y coordinate of the second point
*/
constructor(x1: Double, y1: Double, x2: Double, y2: Double) {
this.x = x2 - x1
this.y = y2 - y1
}
/**
* Creates a [Vector2] from the first point to the second point.
* @param p1 the first point
* *
* @param p2 the second point
*/
constructor(p1: Vector2, p2: Vector2) {
this.x = p2.x - p1.x
this.y = p2.y - p1.y
}
/**
* Creates a unit length vector in the given direction.
* @param direction the direction in radians
* *
* @since 3.0.1
*/
constructor(direction: Double) {
this.x = Math.cos(direction)
this.y = Math.sin(direction)
}
/**
* Returns a copy of this [Vector2].
* @return [Vector2]
*/
fun copy(): Vector2 {
return Vector2(this.x, this.y)
}
/**
* Returns the distance from this point to the given point.
* @param x the x coordinate of the point
* *
* @param y the y coordinate of the point
* *
* @return double
*/
fun distance(x: Double, y: Double): Double {
//return Math.hypot(this.x - x, this.y - y);
val dx = this.x - x
val dy = this.y - y
return Math.sqrt(dx * dx + dy * dy)
}
/**
* Returns the distance from this point to the given point.
* @param point the point
* *
* @return double
*/
fun distance(point: Vector2): Double {
//return Math.hypot(this.x - point.x, this.y - point.y);
val dx = this.x - point.x
val dy = this.y - point.y
return Math.sqrt(dx * dx + dy * dy)
}
/**
* Returns the distance from this point to the given point squared.
* @param x the x coordinate of the point
* *
* @param y the y coordinate of the point
* *
* @return double
*/
fun distanceSquared(x: Double, y: Double): Double {
//return (this.x - x) * (this.x - x) + (this.y - y) * (this.y - y);
val dx = this.x - x
val dy = this.y - y
return dx * dx + dy * dy
}
/**
* Returns the distance from this point to the given point squared.
* @param point the point
* *
* @return double
*/
fun distanceSquared(point: Vector2): Double {
//return (this.x - point.x) * (this.x - point.x) + (this.y - point.y) * (this.y - point.y);
val dx = this.x - point.x
val dy = this.y - point.y
return dx * dx + dy * dy
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
override fun hashCode(): Int {
val prime = 31
var result = 1
var temp: Long
temp = java.lang.Double.doubleToLongBits(x)
result = prime * result + (temp xor temp.ushr(32)).toInt()
temp = java.lang.Double.doubleToLongBits(y)
result = prime * result + (temp xor temp.ushr(32)).toInt()
return result
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
override fun equals(obj: Any?): Boolean {
if (obj == null) return false
if (obj === this) return true
if (obj is Vector2) {
return this.x == obj.x && this.y == obj.y
}
return false
}
/**
* Returns true if the x and y components of this [Vector2]
* are the same as the given [Vector2].
* @param vector the [Vector2] to compare to
* *
* @return boolean
*/
fun equals(vector: Vector2?): Boolean {
if (vector == null) return false
if (this === vector) {
return true
}
else {
return this.x == vector.x && this.y == vector.y
}
}
/**
* Returns true if the x and y components of this [Vector2]
* are the same as the given x and y components.
* @param x the x coordinate of the [Vector2] to compare to
* *
* @param y the y coordinate of the [Vector2] to compare to
* *
* @return boolean
*/
fun equals(x: Double, y: Double): Boolean {
return this.x == x && this.y == y
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
override fun toString(): String {
val sb = StringBuilder()
sb.append("(").append(this.x).append(", ").append(this.y).append(")")
return sb.toString()
}
/**
* Sets this [Vector2] to the given [Vector2].
* @param vector the [Vector2] to set this [Vector2] to
* *
* @return [Vector2] this vector
*/
fun set(vector: Vector2): Vector2 {
this.x = vector.x
this.y = vector.y
return this
}
/**
* Sets this [Vector2] to the given [Vector2].
* @param x the x component of the [Vector2] to set this [Vector2] to
* *
* @param y the y component of the [Vector2] to set this [Vector2] to
* *
* @return [Vector2] this vector
*/
fun set(x: Double, y: Double): Vector2 {
this.x = x
this.y = y
return this
}
/**
* Returns the x component of this [Vector2].
* @return [Vector2]
*/
val xComponent: Vector2
get() = Vector2(this.x, 0.0)
/**
* Returns the y component of this [Vector2].
* @return [Vector2]
*/
val yComponent: Vector2
get() = Vector2(0.0, this.y)
/**
* Returns the magnitude of this [Vector2].
* @return double
*/
// the magnitude is just the pathagorean theorem
val magnitude: Double
get() = Math.sqrt(this.x * this.x + this.y * this.y)
/**
* Returns the magnitude of this [Vector2] squared.
* @return double
*/
val magnitudeSquared: Double
get() = this.x * this.x + this.y * this.y
/**
* Sets the magnitude of the [Vector2].
* @param magnitude the magnitude
* *
* @return [Vector2] this vector
*/
fun setMagnitude(magnitude: Double): Vector2 {
// check the given magnitude
if (Math.abs(magnitude) <= Epsilon.E) {
this.x = 0.0
this.y = 0.0
return this
}
// is this vector a zero vector?
if (this.isZero) {
return this
}
// get the magnitude
var mag = Math.sqrt(this.x * this.x + this.y * this.y)
// normalize and multiply by the new magnitude
mag = magnitude / mag
this.x *= mag
this.y *= mag
return this
}
/**
* Returns the direction of this [Vector2]
* as an angle in radians.
* @return double angle in radians [-, ]
*/
val direction: Double
get() = Math.atan2(this.y, this.x)
/**
* Sets the direction of this [Vector2].
* @param angle angle in radians
* *
* @return [Vector2] this vector
*/
fun setDirection(angle: Double): Vector2 {
//double magnitude = Math.hypot(this.x, this.y);
val magnitude = Math.sqrt(this.x * this.x + this.y * this.y)
this.x = magnitude * Math.cos(angle)
this.y = magnitude * Math.sin(angle)
return this
}
/**
* Adds the given [Vector2] to this [Vector2].
* @param vector the [Vector2]
* *
* @return [Vector2] this vector
*/
operator fun plus(vector: Vector2): Vector2 {
this.x += vector.x
this.y += vector.y
return this
}
/**
* Adds the given [Vector2] to this [Vector2].
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return [Vector2] this vector
*/
fun plus(x: Double, y: Double): Vector2 {
this.x += x
this.y += y
return this
}
/**
* Adds this [Vector2] and the given [Vector2] returning
* a new [Vector2] containing the result.
* @param vector the [Vector2]
* *
* @return [Vector2]
*/
fun sum(vector: Vector2): Vector2 {
return Vector2(this.x + vector.x, this.y + vector.y)
}
/**
* Adds this [Vector2] and the given [Vector2] returning
* a new [Vector2] containing the result.
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return [Vector2]
*/
fun sum(x: Double, y: Double): Vector2 {
return Vector2(this.x + x, this.y + y)
}
/**
* Subtracts the given [Vector2] from this [Vector2].
* @param vector the [Vector2]
* *
* @return [Vector2] this vector
*/
operator fun minus(vector: Vector2): Vector2 {
this.x -= vector.x
this.y -= vector.y
return this
}
/**
* Subtracts the given [Vector2] from this [Vector2].
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return [Vector2] this vector
*/
fun minus(x: Double, y: Double): Vector2 {
this.x -= x
this.y -= y
return this
}
/**
* Subtracts the given [Vector2] from this [Vector2] returning
* a new [Vector2] containing the result.
* @param vector the [Vector2]
* *
* @return [Vector2]
*/
fun difference(vector: Vector2): Vector2 {
return Vector2(this.x - vector.x, this.y - vector.y)
}
/**
* Subtracts the given [Vector2] from this [Vector2] returning
* a new [Vector2] containing the result.
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return [Vector2]
*/
fun difference(x: Double, y: Double): Vector2 {
return Vector2(this.x - x, this.y - y)
}
/**
* Creates a [Vector2] from this [Vector2] to the given [Vector2].
* @param vector the [Vector2]
* *
* @return [Vector2]
*/
fun to(vector: Vector2): Vector2 {
return Vector2(vector.x - this.x, vector.y - this.y)
}
/**
* Creates a [Vector2] from this [Vector2] to the given [Vector2].
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return [Vector2]
*/
fun to(x: Double, y: Double): Vector2 {
return Vector2(x - this.x, y - this.y)
}
/**
* Multiplies this [Vector2] by the given scalar.
* @param scalar the scalar
* *
* @return [Vector2] this vector
*/
operator fun times(scalar: Double): Vector2 {
this.x *= scalar
this.y *= scalar
return this
}
/**
* Multiplies this [Vector2] by the given scalar.
* @param scalar the scalar
* *
* @return [Vector2] this vector
*/
operator fun div(scalar: Double): Vector2 {
this.x /= scalar
this.y /= scalar
return this
}
/**
* Multiplies this [Vector2] by the given scalar returning
* a new [Vector2] containing the result.
* @param scalar the scalar
* *
* @return [Vector2]
*/
infix fun product(scalar: Double): Vector2 {
return Vector2(this.x * scalar, this.y * scalar)
}
/**
* Returns the dot product of the given [Vector2]
* and this [Vector2].
* @param vector the [Vector2]
* *
* @return double
*/
infix fun dot(vector: Vector2): Double {
return this.x * vector.x + this.y * vector.y
}
/**
* Returns the dot product of the given [Vector2]
* and this [Vector2].
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return double
*/
fun dot(x: Double, y: Double): Double {
return this.x * x + this.y * y
}
/**
* Returns the cross product of the this [Vector2] and the given [Vector2].
* @param vector the [Vector2]
* *
* @return double
*/
infix fun cross(vector: Vector2): Double {
return this.x * vector.y - this.y * vector.x
}
/**
* Returns the cross product of the this [Vector2] and the given [Vector2].
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return double
*/
fun cross(x: Double, y: Double): Double {
return this.x * y - this.y * x
}
/**
* Returns the cross product of this [Vector2] and the z value of the right [Vector2].
* @param z the z component of the [Vector2]
* *
* @return [Vector2]
*/
infix fun cross(z: Double): Vector2 {
return Vector2(-1.0 * this.y * z, this.x * z)
}
/**
* Returns true if the given [Vector2] is orthogonal (perpendicular)
* to this [Vector2].
*
*
* If the dot product of this vector and the given vector is
* zero then we know that they are perpendicular
* @param vector the [Vector2]
* *
* @return boolean
*/
fun isOrthogonal(vector: Vector2): Boolean {
return if (Math.abs(this.x * vector.x + this.y * vector.y) <= Epsilon.E) true else false
}
/**
* Returns true if the given [Vector2] is orthogonal (perpendicular)
* to this [Vector2].
*
*
* If the dot product of this vector and the given vector is
* zero then we know that they are perpendicular
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return boolean
*/
fun isOrthogonal(x: Double, y: Double): Boolean {
return if (Math.abs(this.x * x + this.y * y) <= Epsilon.E) true else false
}
/**
* Returns true if this [Vector2] is the zero [Vector2].
* @return boolean
*/
val isZero: Boolean
get() = Math.abs(this.x) <= Epsilon.E && Math.abs(this.y) <= Epsilon.E
/**
* Negates this [Vector2].
* @return [Vector2] this vector
*/
operator fun not() = negate()
/**
* Negates this [Vector2].
* @return [Vector2] this vector
*/
fun negate(): Vector2 {
this.x *= -1.0
this.y *= -1.0
return this
}
/**
* Returns a [Vector2] which is the negative of this [Vector2].
* @return [Vector2]
*/
val negative: Vector2
get() = Vector2(-this.x, -this.y)
/**
* Sets the [Vector2] to the zero [Vector2]
* @return [Vector2] this vector
*/
fun zero(): Vector2 {
this.x = 0.0
this.y = 0.0
return this
}
/**
* Rotates about the origin.
* @param theta the rotation angle in radians
* *
* @return [Vector2] this vector
*/
infix fun rotate(theta: Double): Vector2 {
val cos = Math.cos(theta)
val sin = Math.sin(theta)
val x = this.x
val y = this.y
this.x = x * cos - y * sin
this.y = x * sin + y * cos
return this
}
/**
* Rotates the [Vector2] about the given coordinates.
* @param theta the rotation angle in radians
* *
* @param x the x coordinate to rotate about
* *
* @param y the y coordinate to rotate about
* *
* @return [Vector2] this vector
*/
fun rotate(theta: Double, x: Double, y: Double): Vector2 {
this.x -= x
this.y -= y
this.rotate(theta)
this.x += x
this.y += y
return this
}
/**
* Rotates the [Vector2] about the given point.
* @param theta the rotation angle in radians
* *
* @param point the point to rotate about
* *
* @return [Vector2] this vector
*/
fun rotate(theta: Double, point: Vector2): Vector2 {
return this.rotate(theta, point.x, point.y)
}
/**
* Projects this [Vector2] onto the given [Vector2].
* @param vector the [Vector2]
* *
* @return [Vector2] the projected [Vector2]
*/
fun project(vector: Vector2): Vector2 {
val dotProd = this.dot(vector)
var denominator = vector.dot(vector)
if (denominator <= Epsilon.E) return Vector2()
denominator = dotProd / denominator
return Vector2(denominator * vector.x, denominator * vector.y)
}
/**
* Returns the right-handed normal of this vector.
* @return [Vector2] the right hand orthogonal [Vector2]
*/
val rightHandOrthogonalVector: Vector2
get() = Vector2(-this.y, this.x)
/**
* Sets this vector to the right-handed normal of this vector.
* @return [Vector2] this vector
* *
* @see .getRightHandOrthogonalVector
*/
fun right(): Vector2 {
val temp = this.x
this.x = -this.y
this.y = temp
return this
}
/**
* Returns the left-handed normal of this vector.
* @return [Vector2] the left hand orthogonal [Vector2]
*/
val leftHandOrthogonalVector: Vector2
get() = Vector2(this.y, -this.x)
/**
* Sets this vector to the left-handed normal of this vector.
* @return [Vector2] this vector
* *
* @see .getLeftHandOrthogonalVector
*/
fun left(): Vector2 {
val temp = this.x
this.x = this.y
this.y = -temp
return this
}
/**
* Returns a unit [Vector2] of this [Vector2].
*
*
* This method requires the length of this [Vector2] is not zero.
* @return [Vector2]
*/
val normalized: Vector2
get() {
var magnitude = this.magnitude
if (magnitude <= Epsilon.E) return Vector2()
magnitude = 1.0 / magnitude
return Vector2(this.x * magnitude, this.y * magnitude)
}
/**
* Converts this [Vector2] into a unit [Vector2] and returns
* the magnitude before normalization.
*
*
* This method requires the length of this [Vector2] is not zero.
* @return double
*/
fun normalize(): Double {
val magnitude = Math.sqrt(this.x * this.x + this.y * this.y)
if (magnitude <= Epsilon.E) return 0.0
val m = 1.0 / magnitude
this.x *= m
this.y *= m
//return 1.0 / m;
return magnitude
}
/**
* Returns the smallest angle between the given [Vector2]s.
*
*
* Returns the angle in radians in the range - to .
* @param vector the [Vector2]
* *
* @return angle in radians [-, ]
*/
fun getAngleBetween(vector: Vector2): Double {
val a = Math.atan2(vector.y, vector.x) - Math.atan2(this.y, this.x)
if (a > Math.PI) return a - 2.0 * Math.PI
if (a < -Math.PI) return a + 2.0 * Math.PI
return a
}
companion object {
/** A vector representing the x-axis; this vector should not be changed at runtime; used internally */
internal val X_AXIS = Vector2(1.0, 0.0)
/** A vector representing the y-axis; this vector should not be changed at runtime; used internally */
internal val Y_AXIS = Vector2(0.0, 1.0)
/**
* Returns a new [Vector2] given the magnitude and direction.
* @param magnitude the magnitude of the [Vector2]
* *
* @param direction the direction of the [Vector2] in radians
* *
* @return [Vector2]
*/
fun create(magnitude: Double, direction: Double): Vector2 {
val x = magnitude * Math.cos(direction)
val y = magnitude * Math.sin(direction)
return Vector2(x, y)
}
/**
* The triple product of [Vector2]s is defined as:
*
* a x (b x c)
*
* However, this method performs the following triple product:
*
* (a x b) x c
*
* this can be simplified to:
*
* -a * (b c) + b * (a c)
*
* or:
*
* b * (a c) - a * (b c)
*
* @param a the a [Vector2] in the above equation
* *
* @param b the b [Vector2] in the above equation
* *
* @param c the c [Vector2] in the above equation
* *
* @return [Vector2]
*/
fun tripleProduct(a: Vector2, b: Vector2, c: Vector2): Vector2 {
// expanded version of above formula
val r = Vector2()
// perform a.dot(c)
val ac = a.x * c.x + a.y * c.y
// perform b.dot(c)
val bc = b.x * c.x + b.y * c.y
// perform b * a.dot(c) - a * b.dot(c)
r.x = b.x * ac - a.x * bc
r.y = b.y * ac - a.y * bc
return r
}
}
}