/** * 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; } }