/*
* Bee foraging simulation. Copyright by Joerg Hoehne.
* For suggestions or questions email me at hoehne@thinktel.de
*/
package de.thinktel.utils;
import javax.vecmath.Tuple3d;
import javax.vecmath.Vector3d;
/**
* 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 {
/**
* A constant holding the value of -pi.
*/
public static final double MINUS_PI = -Math.PI;
/**
* A constant holding the value of pi/2.
*/
public static final double PI_HALF = Math.PI / 2;
/**
* A constant holding the value of pi/2.
*/
public static final double MINUS_PI_HALF = -PI_HALF;
/**
* A constant holding the value of 2pi.
*/
public static final double PI2 = Math.PI * 2;
/**
* A constant holding the value of -2pi.
*/
public static final double MINUS_PI2 = -PI2;
/**
* Compute the angle between the origin and the given point. This method
* calls {@link #azimuth(Tuple3d, Tuple3d)}. FIXME this is still the 2d
* version
*
* @param a
* First point.
* @return The angle (azimuth) in radians.
*/
public static double azimuth(Tuple3d a) {
return Math.atan2(a.y, a.x);
}
/**
* Compute the angle between the first and second point. FIXME this is still
* the 2d version
*
* @param a
* First point.
* @param b
* Second point.
* @return The angle (azimuth) in radians.
*/
public static final double azimuth(Tuple3d a, Tuple3d b) {
double dx = b.x - a.x;
double dy = b.y - a.y;
return Math.atan2(dy, dx);
}
public static J3dPolar toPolar(double x, double y, double z) {
return J3dPolar.createFrom(x, y, z);
}
/**
* 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;
angle += 360;
}
return angle;
}
/**
* Clamp the given angle from -PI to PI radians (-180 to 180 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 clampAngleRadians(double angle) {
if (angle >= Math.PI) {
angle %= PI2;
if (angle > Math.PI)
angle -= PI2;
} else {
if (angle < 0.0) {
angle %= PI2;
if (angle < MINUS_PI)
angle += PI2;
}
}
return angle;
}
/**
* Compute the distance between to points given by two {@link Tuple3d}
* arguments.
*
* @param p1
* The first point.
* @param p2
* The second point.
* @return The distance.
*/
public static final double distance(Tuple3d p1, Tuple3d p2) {
double dx = p1.x - p2.x;
double dy = p1.y - p2.y;
double dz = p1.z - p2.z;
return Math.sqrt(dx * dx + dy * dy + dz * dz);
}
/**
* 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);
}
}