/**
* Copyright 2008 - 2012
*
* 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.
*
* @project loon
* @author cping
* @email:javachenpeng@yahoo.com
* @version 0.3.3
*/
package loon.geom;
import loon.utils.MathUtils;
import loon.utils.TArray;
public class ShapeUtils {
public static Vector2f calculateVector(float angle, float magnitude) {
Vector2f v = new Vector2f();
v.x = MathUtils.sin(MathUtils.toRadians(angle));
v.x *= magnitude;
v.y = -MathUtils.cos(MathUtils.toRadians(angle));
v.y *= magnitude;
return v;
}
public static float calculateAngle(float x, float y, float x1, float y1) {
float angle = MathUtils.atan2(y - y1, x - x1);
return (MathUtils.toDegrees(angle) - 90);
}
public static float updateAngle(float currentAngle, float targetAngle,
float step) {
float pi = MathUtils.PI;
currentAngle = (currentAngle + pi * 2) % (pi * 2);
targetAngle = (targetAngle + pi * 2) % (pi * 2);
if (MathUtils.abs(currentAngle - targetAngle) < step) {
return targetAngle;
}
if (2 * pi - currentAngle + targetAngle < pi
|| 2 * pi - targetAngle + currentAngle < pi) {
if (currentAngle < targetAngle) {
currentAngle -= step;
} else {
currentAngle += step;
}
} else {
if (currentAngle < targetAngle) {
currentAngle += step;
} else {
currentAngle -= step;
}
}
return (2 * pi + currentAngle) % (2 * pi);
}
public static float updateLine(float value, float target, float step) {
if (MathUtils.abs(value - target) < step)
return target;
if (value > target) {
return value - step;
}
return value + step;
}
public static float getAngleDiff(float currentAngle, float targetAngle) {
float pi = MathUtils.PI;
currentAngle = (currentAngle + pi * 2) % (pi * 2);
targetAngle = (targetAngle + pi * 2) % (pi * 2);
float diff = MathUtils.abs(currentAngle - targetAngle);
float v = MathUtils.abs(2 * pi - currentAngle + targetAngle);
if (v < diff) {
diff = v;
}
v = MathUtils.abs(2 * pi - targetAngle + currentAngle);
if (v < diff) {
diff = v;
}
return diff;
}
public static Vector2f rotateVector(Vector2f v, Vector2f center, float angle) {
Vector2f result = new Vector2f();
float x = v.x - center.x;
float y = v.y - center.y;
result.x = MathUtils.cos(angle) * x - MathUtils.sin(angle) * y
+ center.x;
result.y = MathUtils.sin(angle) * x + MathUtils.cos(angle) * y
+ center.y;
return result;
}
public static Triangle triangulate(Vector2f[] vertices) {
return triangulate(new TriangleBasic(), vertices);
}
public static Triangle triangulate(Triangle triangulator,
Vector2f[] vertices) {
int size = vertices.length;
for (int i = 0; i < size; i++) {
triangulator.addPolyPoint(vertices[i].x, vertices[i].y);
}
triangulator.triangulate();
return triangulator;
}
public static void calculateCenter(Vector2f[] vertices, Vector2f center) {
center.x = 0f;
center.y = 0f;
for (int i = 0; i < vertices.length; i++) {
center.x += vertices[i].x;
center.y += vertices[i].y;
}
center.x /= vertices.length;
center.y /= vertices.length;
}
public static void translateVertices(Vector2f[] vertices, Vector2f tx) {
for (int i = 0; i < vertices.length; i++) {
vertices[i].addSelf(tx.x, tx.y);
}
}
public static void calculateBounds(Vector2f[] vertices, RectBox bounds) {
bounds.x = Float.MAX_VALUE;
bounds.y = Float.MAX_VALUE;
bounds.width = (int) -Float.MAX_VALUE;
bounds.height = (int) -Float.MAX_VALUE;
for (int i = 0; i < vertices.length; i++) {
Vector2f v = vertices[i];
if (v.x < bounds.x)
bounds.x = v.x;
if (v.y < bounds.y)
bounds.y = v.y;
if (v.x > bounds.x + bounds.width) {
bounds.width = (int) (v.x - bounds.x);
}
if (v.y > bounds.y + bounds.height) {
bounds.height = (int) (v.y - bounds.y);
}
}
}
public void rotate(Vector2f[] vertices, float angle) {
for (int i = 0; i < vertices.length; i++) {
vertices[i].rotate(angle);
}
}
public static void calculateConvexHull(TArray<Vector2f> points,
TArray<Vector2f> convexHullPoints) {
if (points.size <= 1) {
return;
}
Vector2f p;
Vector2f bot = points.get(0);
for (int i = 1; i < points.size; i++) {
Vector2f point = points.get(i);
if (point.y < bot.y)
bot = point;
}
convexHullPoints.add(bot);
p = bot;
do {
int i;
i = points.get(0) == p ? 1 : 0;
Vector2f cand = points.get(i);
for (i = i + 1; i < points.size; i++) {
Vector2f point = points.get(i);
if (point != p && area(p, cand, point) > 0)
cand = points.get(i);
}
convexHullPoints.add(cand);
p = cand;
} while (p != bot);
}
public static float area(Vector2f a, Vector2f b, Vector2f c) {
return area(a.x, a.y, b.x, b.y, c.x, c.y);
}
public static float area(float x0, float y0, float x1, float y1, float x2,
float y2) {
return x1 * y2 - y1 * x2 + x2 * y0 - y2 * x0 + x0 * y1 - y0 * x1;
}
}