Added Vector and friends, and Transform interface.
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
//
|
||||
// Pythagoras - a collection of geometry classes
|
||||
// http://github.com/samskivert/pythagoras
|
||||
|
||||
package pythagoras.f;
|
||||
|
||||
import pythagoras.util.Platform;
|
||||
|
||||
/**
|
||||
* Provides most of the implementation of {@link IVector}, obtaining only x and y from the derived
|
||||
* class.
|
||||
*/
|
||||
public abstract class AbstractVector implements IVector
|
||||
{
|
||||
@Override // from interface IVector
|
||||
public float dot (IVector other) {
|
||||
return getX()*other.getX() + getY()*other.getY();
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector negate () {
|
||||
return negate(new Vector());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector negate (Vector result) {
|
||||
return result.set(-getX(), -getY());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector normalize () {
|
||||
return normalize(new Vector());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector normalize (Vector result) {
|
||||
return mult(1f / length(), result);
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public float angle (IVector other) {
|
||||
float cos = dot(other) / (length() * other.length());
|
||||
return cos >= 1f ? 0f : FloatMath.acos(cos);
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public float direction (IVector other) {
|
||||
return FloatMath.atan2(other.getY() - getY(), other.getX() - getX());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public float length () {
|
||||
return FloatMath.sqrt(lengthSq());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public float lengthSq () {
|
||||
float x = getX(), y = getY();
|
||||
return (x*x + y*y);
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public float distance (IVector other) {
|
||||
return FloatMath.sqrt(distanceSq(other));
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public float distanceSq (IVector other) {
|
||||
float dx = getX() - other.getX(), dy = getY() - other.getY();
|
||||
return dx*dx + dy*dy;
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector mult (float v) {
|
||||
return mult(v, new Vector());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector mult (float v, Vector result) {
|
||||
return result.set(getX()*v, getY()*v);
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector mult (IVector other) {
|
||||
return mult(other, new Vector());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector mult (IVector other, Vector result) {
|
||||
return result.set(getX()*other.getX(), getY()*other.getY());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector add (IVector other) {
|
||||
return add(other, new Vector());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector add (IVector other, Vector result) {
|
||||
return add(other.getX(), other.getY(), result);
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector subtract (IVector other) {
|
||||
return subtract(other, new Vector());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector subtract (IVector other, Vector result) {
|
||||
return add(-other.getX(), -other.getY(), result);
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector add (float x, float y) {
|
||||
return add(x, y, new Vector());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector add (float x, float y, Vector result) {
|
||||
return result.set(getX() + x, getY() + y);
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector addScaled (IVector other, float v) {
|
||||
return addScaled(other, v, new Vector());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector addScaled (IVector other, float v, Vector result) {
|
||||
return result.set(getX() + other.getX()*v, getY() + other.getY()*v);
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector rotate (float angle) {
|
||||
return rotate(angle, new Vector());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector rotate (float angle, Vector result) {
|
||||
float x = getX(), y = getY();
|
||||
float sina = FloatMath.sin(angle), cosa = FloatMath.cos(angle);
|
||||
return result.set(x*cosa - y*sina, x*sina + y*cosa);
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector rotateAndAdd (float angle, IVector add, Vector result) {
|
||||
float x = getX(), y = getY();
|
||||
float sina = FloatMath.sin(angle), cosa = FloatMath.cos(angle);
|
||||
return result.set(x*cosa - y*sina + add.getX(), x*sina + y*cosa + add.getY());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector rotateScaleAndAdd (float angle, float scale, IVector add, Vector result) {
|
||||
float x = getX(), y = getY();
|
||||
float sina = FloatMath.sin(angle), cosa = FloatMath.cos(angle);
|
||||
return result.set((x*cosa - y*sina)*scale + add.getX(),
|
||||
(x*sina + y*cosa)*scale + add.getY());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector lerp (IVector other, float t) {
|
||||
return lerp(other, t, new Vector());
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector lerp (IVector other, float t, Vector result) {
|
||||
float x = getX(), y = getY();
|
||||
float dx = other.getX() - x, dy = other.getY() - y;
|
||||
return result.set(x + t*dx, y + t*dy);
|
||||
}
|
||||
|
||||
@Override // from interface IVector
|
||||
public Vector clone () {
|
||||
return new Vector(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals (Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof AbstractVector) {
|
||||
AbstractVector p = (AbstractVector)obj;
|
||||
return getX() == p.getX() && getY() == p.getY();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode () {
|
||||
return Platform.hashCode(getX()) ^ Platform.hashCode(getY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString () {
|
||||
return Vectors.vectorToString(getX(), getY());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
//
|
||||
// Pythagoras - a collection of geometry classes
|
||||
// http://github.com/samskivert/pythagoras
|
||||
|
||||
package pythagoras.f;
|
||||
|
||||
/**
|
||||
* Provides read-only access to a {@link Vector}.
|
||||
*/
|
||||
public interface IVector
|
||||
{
|
||||
/** Returns the x-component of this vector. */
|
||||
float getX ();
|
||||
|
||||
/** Returns the y-component of this vector. */
|
||||
float getY ();
|
||||
|
||||
/** Computes and returns the dot product of this and the specified other vector. */
|
||||
float dot (IVector other);
|
||||
|
||||
/** Negates this vector.
|
||||
* @return a new vector containing the result. */
|
||||
Vector negate ();
|
||||
|
||||
/** Negates this vector, storing the result in the supplied object.
|
||||
* @return a reference to the result, for chaining. */
|
||||
Vector negate (Vector result);
|
||||
|
||||
/** Normalizes this vector.
|
||||
* @return a new vector containing the result. */
|
||||
Vector normalize ();
|
||||
|
||||
/** Normalizes this vector, storing the result in the object supplied.
|
||||
* @return a reference to the result, for chaining. */
|
||||
Vector normalize (Vector result);
|
||||
|
||||
/** Returns the angle between this vector and the specified other vector. */
|
||||
float angle (IVector other);
|
||||
|
||||
/** Returns the direction of a vector pointing from this point to the specified other point. */
|
||||
float direction (IVector other);
|
||||
|
||||
/** Returns the length of this vector. */
|
||||
float length ();
|
||||
|
||||
/** Returns the squared length of this vector. */
|
||||
float lengthSq ();
|
||||
|
||||
/** Returns the distance from this vector to the specified other vector. */
|
||||
float distance (IVector other);
|
||||
|
||||
/** Returns the squared distance from this vector to the specified other. */
|
||||
float distanceSq (IVector other);
|
||||
|
||||
/** Multiplies this vector by a scalar.
|
||||
* @return a new vector containing the result. */
|
||||
Vector mult (float v);
|
||||
|
||||
/** Multiplies this vector by a scalar and places the result in the supplied object.
|
||||
* @return a reference to the result, for chaining. */
|
||||
Vector mult (float v, Vector result);
|
||||
|
||||
/** Multiplies this vector by another.
|
||||
* @return a new vector containing the result. */
|
||||
Vector mult (IVector other);
|
||||
|
||||
/** Multiplies this vector by another, storing the result in the object provided.
|
||||
* @return a reference to the result vector, for chaining. */
|
||||
Vector mult (IVector other, Vector result);
|
||||
|
||||
/** Adds a vector to this one.
|
||||
* @return a new vector containing the result. */
|
||||
Vector add (IVector other);
|
||||
|
||||
/** Adds a vector to this one, storing the result in the object provided.
|
||||
* @return a reference to the result, for chaining. */
|
||||
Vector add (IVector other, Vector result);
|
||||
|
||||
/** Adds a vector to this one.
|
||||
* @return a new vector containing the result. */
|
||||
Vector add (float x, float y);
|
||||
|
||||
/** Adds a vector to this one and stores the result in the object provided.
|
||||
* @return a reference to the result, for chaining. */
|
||||
Vector add (float x, float y, Vector result);
|
||||
|
||||
/** Adds a scaled vector to this one.
|
||||
* @return a new vector containing the result. */
|
||||
Vector addScaled (IVector other, float v);
|
||||
|
||||
/** Adds a scaled vector to this one and stores the result in the supplied vector.
|
||||
* @return a reference to the result, for chaining. */
|
||||
Vector addScaled (IVector other, float v, Vector result);
|
||||
|
||||
/** Subtracts a vector from this one.
|
||||
* @return a new vector containing the result. */
|
||||
Vector subtract (IVector other);
|
||||
|
||||
/** Subtracts a vector from this one and places the result in the supplied object.
|
||||
* @return a reference to the result, for chaining. */
|
||||
Vector subtract (IVector other, Vector result);
|
||||
|
||||
/** Rotates this vector by the specified angle.
|
||||
* @return a new vector containing the result. */
|
||||
Vector rotate (float angle);
|
||||
|
||||
/** Rotates this vector by the specified angle, storing the result in the vector provided.
|
||||
* @return a reference to the result vector, for chaining. */
|
||||
Vector rotate (float angle, Vector result);
|
||||
|
||||
/** Rotates this vector by the specified angle and adds another vector to it, placing the
|
||||
* result in the object provided.
|
||||
* @return a reference to the result, for chaining. */
|
||||
Vector rotateAndAdd (float angle, IVector add, Vector result);
|
||||
|
||||
/** Rotates this vector by the specified angle, applies a uniform scale, and adds another
|
||||
* vector to it, placing the result in the object provided.
|
||||
* @return a reference to the result, for chaining. */
|
||||
Vector rotateScaleAndAdd (float angle, float scale, IVector add, Vector result);
|
||||
|
||||
/** Linearly interpolates between this and the specified other vector by the supplied amount.
|
||||
* @return a new vector containing the result. */
|
||||
Vector lerp (IVector other, float t);
|
||||
|
||||
/** Linearly interpolates between this and the supplied other vector by the supplied amount,
|
||||
* storing the result in the supplied object.
|
||||
* @return a reference to the result, for chaining. */
|
||||
Vector lerp (IVector other, float t, Vector result);
|
||||
|
||||
/** Returns a mutable copy of this vector. */
|
||||
Vector clone ();
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
//
|
||||
// Pythagoras - a collection of geometry classes
|
||||
// http://github.com/samskivert/pythagoras
|
||||
|
||||
package pythagoras.f;
|
||||
|
||||
/**
|
||||
* Represents a geometric transform. Specialized implementations exist for identity, rigid body,
|
||||
* uniform, affine and general transforms.
|
||||
*/
|
||||
public interface Transform
|
||||
{
|
||||
/** Sets the translation component of this transform.
|
||||
* @throws UnsupportedOperationException if the transform is not rigid body or greater. */
|
||||
void setTranslation (float tx, float ty);
|
||||
|
||||
/** Sets the x-component of this transform's translation.
|
||||
* @throws UnsupportedOperationException if the transform is not rigid body or greater. */
|
||||
void setTx (float tx);
|
||||
|
||||
/** Sets the y-component of this transform's translation.
|
||||
* @throws UnsupportedOperationException if the transform is not rigid body or greater. */
|
||||
void setTy (float ty);
|
||||
|
||||
/** Sets the rotation component of this transform.
|
||||
* @throws UnsupportedOperationException if the transform is not rigid body or greater. */
|
||||
void setRotation (float angle);
|
||||
|
||||
/** Sets the uniform scale of this transform.
|
||||
* @throws UnsupportedOperationException if the transform is not uniform or greater. */
|
||||
void setScale (float scale);
|
||||
|
||||
/** Sets the x and y scale of this transform.
|
||||
* @throws UnsupportedOperationException if the transform is not affine or greater. */
|
||||
void setScale (float scaleX, float scaleY);
|
||||
|
||||
/** Sets the x scale of this transform.
|
||||
* @throws UnsupportedOperationException if the transform is not affine or greater. */
|
||||
void setScaleX (float scaleX);
|
||||
|
||||
/** Sets the y scale of this transform.
|
||||
* @throws UnsupportedOperationException if the transform is not affine or greater. */
|
||||
void setScaleY (float scaleY);
|
||||
|
||||
/** Sets the affine transform matrix.
|
||||
* @throws UnsupportedOperationException if the transform is not affine or greater. */
|
||||
void setTransform (float m00, float m01, float m10, float m11,
|
||||
float tx, float ty);
|
||||
|
||||
/** Sets the general transform matrix.
|
||||
* @throws UnsupportedOperationException if the transform is not general. */
|
||||
void setTransform (float m00, float m01, float m02,
|
||||
float m10, float m11, float m12,
|
||||
float m20, float m21, float m22);
|
||||
|
||||
/** Returns the x-coordinate of the translation component. */
|
||||
float getTx ();
|
||||
|
||||
/** Returns the y-coordinate of the translation component. */
|
||||
float getTy ();
|
||||
|
||||
/** Returns the rotation applied by this transform. Note that the rotation is extracted and
|
||||
* therefore approximate for affine and general transforms. */
|
||||
float getRotation (); // will be extracted from affine+
|
||||
|
||||
/** Returns the uniform scale applied by this transform. Note that the uniform scale will be
|
||||
* approximated for non-uniform transforms (affine and general). */
|
||||
float getScale (); // will be extracted/approximated for affine+
|
||||
|
||||
/** Returns the x-component of the scale applied by this transform. */
|
||||
float getScaleX (); // will be extracted from affine+
|
||||
|
||||
/** Returns the y-component of the scale applied by this transform. */
|
||||
float getScaleY (); // will be extracted from affine+
|
||||
|
||||
/** Returns the inverse of this transform.
|
||||
* @throws NoninvertibleTransformException if the transform is not invertible. */
|
||||
Transform invert ();
|
||||
|
||||
/** Composes this transform with the supplied transform (i.e. {@code this x other}). */
|
||||
Transform compose (Transform other);
|
||||
|
||||
/** Returns the linear interpolation between this transform and the specified other. */
|
||||
Transform lerp (Transform other, float t);
|
||||
|
||||
/** Transforms the supplied point, writing the result into {@code into}, which may reference
|
||||
* the same object as {@code p}. */
|
||||
void transform (IPoint p, Point into);
|
||||
|
||||
/** Inverse transforms the supplied point, writing the result into {@code into}, which may
|
||||
* reference the same object as {@code p}.
|
||||
* @throws NoninvertibleTransformException if the transform is not invertible. */
|
||||
void inverseTransform (IPoint p, Point into);
|
||||
|
||||
/** Transforms the supplied vector, writing the result into {@code into}, which may reference
|
||||
* the same object as {@code v}. */
|
||||
void transform (IVector v, Vector into);
|
||||
|
||||
/** Inverse transforms the supplied vector, writing the result into {@code into}, which may
|
||||
* reference the same object as {@code v}.
|
||||
* @throws NoninvertibleTransformException if the transform is not invertible. */
|
||||
void inverseTransform (IVector v, Vector into);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// Pythagoras - a collection of geometry classes
|
||||
// http://github.com/samskivert/pythagoras
|
||||
|
||||
package pythagoras.f;
|
||||
|
||||
/**
|
||||
* Represents a vector in a plane.
|
||||
*/
|
||||
public class Vector extends AbstractVector
|
||||
{
|
||||
/** The x-component of the vector. */
|
||||
public float x;
|
||||
|
||||
/** The y-component of the vector. */
|
||||
public float y;
|
||||
|
||||
/** Creates a vector with the specified x and y components. */
|
||||
public Vector (float x, float y) {
|
||||
set(x, y);
|
||||
}
|
||||
|
||||
/** Creates a vector equal to {@code other}. */
|
||||
public Vector (IVector other) {
|
||||
set(other);
|
||||
}
|
||||
|
||||
/** Creates a vector with zero x and y components. */
|
||||
public Vector () {
|
||||
}
|
||||
|
||||
@Override // from AbstractVector
|
||||
public float getX () {
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override // from AbstractVector
|
||||
public float getY () {
|
||||
return y;
|
||||
}
|
||||
|
||||
/** Negates this vector in-place.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector negateLocal () {
|
||||
return negate(this);
|
||||
}
|
||||
|
||||
/** Normalizes this vector in-place.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector normalizeLocal () {
|
||||
return normalize(this);
|
||||
}
|
||||
|
||||
/** Multiplies this vector in-place by a scalar.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector multLocal (float v) {
|
||||
return mult(v, this);
|
||||
}
|
||||
|
||||
/** Multiplies this vector in-place by another.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector multLocal (IVector other) {
|
||||
return mult(other, this);
|
||||
}
|
||||
|
||||
/** Adds a vector in-place to this one.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector addLocal (IVector other) {
|
||||
return add(other, this);
|
||||
}
|
||||
|
||||
/** Subtracts a vector in-place from this one.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector subtractLocal (IVector other) {
|
||||
return subtract(other, this);
|
||||
}
|
||||
|
||||
/** Adds a vector in-place to this one.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector addLocal (float x, float y) {
|
||||
return add(x, y, this);
|
||||
}
|
||||
|
||||
/** Adds a scaled vector in-place to this one.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector addScaledLocal (IVector other, float v) {
|
||||
return addScaled(other, v, this);
|
||||
}
|
||||
|
||||
/** Rotates this vector in-place by the specified angle.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector rotateLocal (float angle) {
|
||||
return rotate(angle, this);
|
||||
}
|
||||
|
||||
/** Linearly interpolates between this and {@code other} in-place by the supplied amount.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector lerpLocal (IVector other, float t) {
|
||||
return lerp(other, t, this);
|
||||
}
|
||||
|
||||
/** Copies the elements of another vector.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector set (IVector other) {
|
||||
return set(other.getX(), other.getY());
|
||||
}
|
||||
|
||||
/** Copies the elements of an array.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector set (float[] values) {
|
||||
return set(values[0], values[1]);
|
||||
}
|
||||
|
||||
/** Sets all of the elements of the vector.
|
||||
* @return a reference to this vector, for chaining. */
|
||||
public Vector set (float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Pythagoras - a collection of geometry classes
|
||||
// http://github.com/samskivert/pythagoras
|
||||
|
||||
package pythagoras.f;
|
||||
|
||||
/**
|
||||
* Vector-related utility methods.
|
||||
*/
|
||||
public class Vectors
|
||||
{
|
||||
/** A unit vector in the X+ direction. */
|
||||
public static final IVector UNIT_X = new Vector(1f, 0f);
|
||||
|
||||
/** A unit vector in the Y+ direction. */
|
||||
public static final IVector UNIT_Y = new Vector(0f, 1f);
|
||||
|
||||
/** The zero vector. */
|
||||
public static final IVector ZERO = new Vector(0f, 0f);
|
||||
|
||||
/** A vector containing the minimum floating point value for all components
|
||||
* (note: the components are -{@link Float#MAX_VALUE}, not {@link Float#MIN_VALUE}). */
|
||||
public static final IVector MIN_VALUE = new Vector(-Float.MAX_VALUE, -Float.MAX_VALUE);
|
||||
|
||||
/** A vector containing the maximum floating point value for all components. */
|
||||
public static final IVector MAX_VALUE = new Vector(Float.MAX_VALUE, Float.MAX_VALUE);
|
||||
|
||||
/**
|
||||
* Returns a string describing the supplied vector, of the form <code>+x+y</code>,
|
||||
* <code>+x-y</code>, <code>-x-y</code>, etc.
|
||||
*/
|
||||
public static String vectorToString (float x, float y) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if (x >= 0) buf.append("+");
|
||||
buf.append(x);
|
||||
if (y >= 0) buf.append("+");
|
||||
buf.append(y);
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user