/* * Bee foraging simulation. Copyright by Joerg Hoehne. * For suggestions or questions email me at hoehne@thinktel.de */ package utils; import javax.vecmath.Point3d; import javax.vecmath.*; import foragingBee.IMovingAgent; /** * A class with some static utility methods. * <p> * Copyright 2009 Joerg Hoehne * * @author hoehne (<a href="mailto:hoehne@thinktel.de">Jörg Höhne</a>) * */ public class Geometric { /** * Compute the angle between the origin and the given point. This method * calls {@link #angle(Tuple3d, Tuple3d)}. * * @param a * First point. * @return The angle in radians. */ public static double angle(Tuple3d a) { return angle(new Point3d(), a); } /** * Compute the angle between the first and second point. * * @param a * First point. * @param b * Second point. * @return The angle in radians. */ public static double angle(Tuple3d a, Tuple3d b) { double dx = b.x - a.x; double dy = b.y - a.y; double angle = 0.0d; if (dx == 0.0) { if (dy == 0.0) angle = 0.0; else if (dy > 0.0) angle = Math.PI / 2.0; else angle = (Math.PI * 3.0) / 2.0; } else if (dy == 0.0) { if (dx > 0.0) angle = 0.0; else angle = Math.PI; } else { if (dx < 0.0) angle = Math.atan(dy / dx) + Math.PI; else if (dy < 0.0) angle = Math.atan(dy / dx) + (2 * Math.PI); else angle = Math.atan(dy / dx); } return angle; // return (angle * 180) / Math.PI; } /** * Clamp the given angle from 0 to 360 degrees. Please be aware the result * may be inaccurate due to the usage of the double type. * * @param angle * The angle to be clamped. * @return The clamped angle. */ public static final double clampAngleDegree(double angle) { if (angle >= 360.0) angle %= 360.0d; if (angle < 0.0) { angle %= 360.0d; if (angle < 0.0) angle += 360; } return angle; } /** * Return the normalized vector. Leave it unchanged if the vector is of * length 0. * * @param v * The vector to be normalized. */ public static final void normalize(Vector3d v) { if ((v.x == 0.0) && (v.y == 0.0) && (v.z == 0.0)) return; normalize(v, v.length()); } /** * Return the normalized vector. Leave it unchanged if the vector is of * length 0. The vector will be scaled to the given length. * * @param v * The vector to be normalized and set to the given length. * @param length * The pre-computed length of the vector. */ public static final void normalize(Vector3d v, double length) { if ((v.x == 0.0) && (v.y == 0.0) && (v.z == 0.0)) return; v.scale(1 / length); } /** * Rotate the give vector of type {@link Vector3d} by the given angle. Only * the x and y value of the vector are modified. * * @param v * The vector to rotate. * @param angle * The angle in radians to rotate the vector. */ public static void rotateBy(Vector3d v, double angle) { double sina = Math.sin(angle); double cosa = Math.cos(angle); double x = v.x; double y = v.y; v.x = x * cosa - y * sina; v.y = x * sina + y * cosa; } /** * Rotate a vector to a given angle in radians. * * @param v * The vector to rotate. * @param angle * The angle in radians. */ public static void rotateTo(Vector3d v, double angle) { double length = v.length(); v.x = length * Math.cos(angle); v.y = length * Math.sin(angle); } }