/** * Copyright 2012 Jason Sorensen (sorensenj@smert.net) * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ package net.smert.frameworkgl.math; import java.nio.FloatBuffer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Jason Sorensen <sorensenj@smert.net> */ public class Vector2f { private static Logger log = LoggerFactory.getLogger(Vector2f.class); public static Vector2f WORLD_X_AXIS = new Vector2f(1f, 0f); public static Vector2f WORLD_Y_AXIS = new Vector2f(0f, 1f); float x; float y; // Constructors public Vector2f() { zero(); } public Vector2f(float x, float y) { this.x = x; this.y = y; } public Vector2f(Vector2f vector) { x = vector.x; y = vector.y; } // Boolean Results public boolean trim(float length) { float magnitude = magnitude(); if (magnitude <= length) { return false; } multiply(1f / magnitude); multiply(length); return true; } public boolean trimSquared(float length) { float magnitudeSquared = magnitudeSquared(); if (magnitudeSquared <= (length * length)) { return false; } multiply(1f / MathHelper.Sqrt(magnitudeSquared)); multiply(length); return true; } // Conversion Operations public void toFloatBuffer(FloatBuffer fbOut) { fbOut.put(x); fbOut.put(y); } // Scalar Results public float distance(Vector2f vector) { float d0 = x - vector.x; float d1 = y - vector.y; return MathHelper.Sqrt(d0 * d0 + d1 * d1); } public float distanceSquared(Vector2f vector) { float d0 = x - vector.x; float d1 = y - vector.y; return d0 * d0 + d1 * d1; } public float dot(Vector2f vector) { return x * vector.x + y * vector.y; } public float getElement(int index) { switch (index) { case 0: return x; case 1: return y; } throw new IllegalArgumentException("Invalid index: " + index); } public float getX() { return x; } public float getY() { return y; } public float magnitude() { return MathHelper.Sqrt(x * x + y * y); } public float magnitudeSquared() { return x * x + y * y; } public int maxAxis() { return (x < y) ? 1 : 0; } public int minAxis() { return (x < y) ? 0 : 1; } // Vector Results public Vector2f abs() { x = Math.abs(x); y = Math.abs(y); return this; } public Vector2f add(float x, float y) { this.x += x; this.y += y; return this; } public Vector2f add(Vector2f vector) { x += vector.x; y += vector.y; return this; } public Vector2f addScaled(Vector2f vector, float scale) { x += vector.x * scale; y += vector.y * scale; return this; } public Vector2f addX(float x) { this.x += x; return this; } public Vector2f addY(float y) { this.y += y; return this; } public Vector2f invert() { x = -x; y = -y; return this; } public Vector2f multiply(float value) { x *= value; y *= value; return this; } public Vector2f normalize() { float mag = magnitude(); if (mag < MathHelper.ZERO_EPSILON) { log.warn("Divide By Zero. Magnitude: {} x: {} y: {}", mag, x, y); x = 1f; y = 0f; return this; } return multiply(1f / mag); } public Vector2f set(float x, float y) { this.x = x; this.y = y; return this; } public Vector2f set(Vector2f vector) { assert (this != vector); x = vector.x; y = vector.y; return this; } public void setElement(int index, float value) { switch (index) { case 0: x = value; return; case 1: y = value; return; } throw new IllegalArgumentException("Invalid index: " + index); } public Vector2f setInvert(Vector2f vector) { x = -vector.x; y = -vector.y; return this; } public Vector2f setInterpolate(Vector2f vector0, Vector2f vector1, float f) { float s = 1f - f; x = vector0.x * s + vector1.x * f; y = vector0.y * s + vector1.y * f; return this; } public Vector2f setMax(float x, float y, float z) { if (x > this.x) { this.x = x; } if (y > this.y) { this.y = y; } return this; } public Vector2f setMax(Vector2f vector) { if (vector.x > x) { x = vector.x; } if (vector.y > y) { y = vector.y; } return this; } public Vector2f setMin(float x, float y, float z) { if (x < this.x) { this.x = x; } if (y < this.y) { this.y = y; } return this; } public Vector2f setMin(Vector2f vector) { if (vector.x < x) { x = vector.x; } if (vector.y < y) { y = vector.y; } return this; } public Vector2f setNormal(float x, float y, float z) { this.x = x; this.y = y; return normalize(); } public Vector2f setX(float x) { this.x = x; return this; } public Vector2f setY(float y) { this.y = y; return this; } public Vector2f subtract(Vector2f vector) { x -= vector.x; y -= vector.y; return this; } public final Vector2f zero() { x = 0f; y = 0f; return this; } @Override public int hashCode() { int hash = 7; hash = 29 * hash + Float.floatToIntBits(this.x); hash = 29 * hash + Float.floatToIntBits(this.y); return hash; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Vector2f other = (Vector2f) obj; if (Float.floatToIntBits(this.x) != Float.floatToIntBits(other.x)) { return false; } return Float.floatToIntBits(this.y) == Float.floatToIntBits(other.y); } @Override public String toString() { return "(x: " + x + " y: " + y + ")"; } }