de.jreality.math
Class Pn

java.lang.Object
  extended by de.jreality.math.Pn

public class Pn
extends Object

A set of static methods related to real n-dimensional real projective space RPn. In general, points and vectors are represented in homogeneous coordinates by arrays of length n+1. By duality, hyperplanes are represented in the same fashion. The last coordinate is considered to be the homogeneous coordinate (see for example dehomogenize(double[], double[])).

In addition to purely projective methods, this includes a number of methods related to the classical homogeneous metric spaces (euclidean, hyperbolic, and elliptic) which are based on a projective model for these spaces.

The methods related to metric geometries generally have a final argument which identifies the geometry. This can be one of the 3 pre-defined values HYPERBOLIC, EUCLIDEAN or ELLIPTIC. These correspond to spaces of constant negative, null, and positive curvature, resp.

(For the mathematical basis of the derivation of metric geometries from projective geometry -- which forms the foundation the functionality of this class -- see H.M.S. Coxeter, Non-Euclidean Geometry, 1965.)

Note: there may appear to be some duplication of functionality with methods in Rn. However, the methods here expect points to be specified with homogeneous coordinates, while those in Rn expect dehomogenized coordinates (in general -- but see Rn for exceptions), so there is usually only one correct choice for which method to use. But see normalize(double[], double[], int) for an example of some finer points.

See also Rn for more on method conventions. See also P2 and P3 for methods specific to two- and three-dimensional real projective geometry.

Author:
Charles Gunn

Field Summary
static int ELLIPTIC
           
static int EUCLIDEAN
           
static int HYPERBOLIC
           
static double[] originP3
           
static int PROJECTIVE
           
static double[] zDirectionP3
           
 
Method Summary
static double acosh(double x)
           
static double angleBetween(double[] u, double[] v, int metric)
          Calculate the angle between the points u and v with respect to the metric metric.
static double asinh(double x)
           
static double atanh(double x)
           
static double[][] calculateBounds(double[][] bounds, double[][] vlist)
          Like the method calculateBounds in class Rn, but dehomogenizes the points before computing the bound.
static double[] centroid(double[] average, double[][] points, int metric)
          Calculate the centroid of points with respect to metric.
static double coordForDistance(double d, int metric)
          Return the value z so that the point (0,0,z,1) lies a distance d from the origin (0,0,0,1) in the given metric.
static double cosh(double x)
          These hyperbolic trig functions fill in a gap in the Java math library!
static double[][] dehomogenize(double[][] dst, double[][] src)
          A vectorized version of dehomogenize(double[], double[]).
static double[] dehomogenize(double[] dst, double[] src)
          Dehomogenize the src array into the dst array.
static double distanceBetween(double[] u, double[] v, int metric)
          Calculate the distance between the two points u and v.
static double[] dragTangentVector(double[] dst, double[] ddir, double[] src, double[] sdir, double length, int metric)
          Drag a tangent vector sdir based at point src with initial direction given by sdir, a distance of length in the given metric.
static double[] dragTangentVector(double[] dstTangent, double[] sourcePoint, double[] sourceTangent, double[] dstPoint, int metric)
          Drag the tangent vector sourceTangent based at sourcePoint to a tangent vector based at dstPoint.
static double[] dragTowards(double[] result, double[] p0, double[] p1, double length, int metric)
          Calculate the point lying a distance length from p0 in the direction p1.
static double[][] homogenize(double[][] dst, double[][] src)
          A vector version of homogenize(double[], double[]).
static double[] homogenize(double[] dst, double[] src)
          Extend the coordinates of src by appending 1.0
static double innerProduct(double[] dst, double[] src, int metric)
          Returns the inner product of the two vectors for the given metric.
static double innerProductPlanes(double[] dst, double[] src, int metric)
          The euclidean metric is not completely self-dual so we need a special method to calculate inner product of planes
static double innerProductPoints(double[] dst, double[] src, int metric)
          An alias for innerProduct(double[], double[], int).
static boolean isValidCoordinate(double[] transVec, int dim, int metric)
           
static double[] linearInterpolation(double[] dst, double[] u, double[] v, double t, int metric)
          Linear interpolate respecting the given metric metric.
static double[] makeFlattenProjection(double[] dst, double[] center, double[] axis)
          Similar to P3#makeHarmonicHarmology(double[], double[], double[]) but maps all points onto the axis plane.
static double[] makeGeneralizedProjection(double[] dst, double[] center, double[] axis, double val)
          Create a projectivity that leaves center C invariant (planewise), axis A invariant (point-wise) and otherwise moves a general point P along the line l through P and the center depending on val.
static double[] makeHarmonicHarmology(double[] dst, double[] center, double[] axis)
          Construct a central projectivity with fixed point center and fixed plane axis.
static double[] midPlane(double[] midp, double[] pl1, double[] pl2, int metric)
          Find the plane which lies, metrically, half-way between the two given planes.
static double norm(double[] src, int metric)
          Calculates the norm of the vector in the given metric metric.
static double[][] normalize(double[][] dst, double[][] src, int metric)
          A vectorized version of normalize(double[], double[], int).
static double[] normalize(double[] dst, double[] dvec, double[] src, double[] svec, int metric)
          Normalize a point-tangent pair (src, svec) so that both members have unit length and, the tangent vector lies in the polar plane of the point.
static double[] normalize(double[] dst, double[] src, int metric)
          Normalizes the vector src to have unit length (either 1 or i), or, if metric is EUCLIDEAN, then the input vector is dehomogenized.
static double[] normalizePlane(double[] dst, double[] src, int metric)
          For the euclidean special case: Normalize a hyper-plane (represented as a vector of length n) so that the direction vector (the first n-1 coordinates) has euclidean length 1 but represents the same projective hyper-plane.
static double[] normalizePoint(double[] dst, double[] src, int metric)
          An alias for normalize(double[], double[], int).
static double normSquared(double[] src, int metric)
           
static double[][] polarize(double[][] polar, double[][] p, int metric)
          A vectorized version of polarize(double[], double[], int).
static double[] polarize(double[] polar, double[] p, int metric)
          Polarize the input point p with respect to the quadradic form associated to metric.
static double[] polarizePlane(double[] dst, double[] plane, int metric)
          This just calls polarize(double[], double[], int) since the polar plane of a point is just Q.point, where Q is the absolute quadric
static double[] polarizePoint(double[] dst, double[] point, int metric)
          This has to handle the exception euclidean case, that the polar of any point is the ideal plane.
static double[] projectOnto(double[] result, double[] master, double[] victim, int metric)
          Determine the projection of the point victim onto the point master.
static double[] projectOntoComplement(double[] result, double[] master, double[] victim, int metric)
          Project victim onto the othogonal complement of master (all with respect to the given metric).
static double[] projectToTangentSpace(double[] result, double[] point, double[] tangentToBe, int metric)
           
static double[][] setToLength(double[][] dst, double[][] src, double d, int metric)
          A vectorized version of setToLength(double[], double[], double, int).
static double[] setToLength(double[] dst, double[] src, double length, int metric)
          Create a multiple of src with has length length.
static double sinh(double x)
           
static double tanh(double x)
           
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ELLIPTIC

public static final int ELLIPTIC
See Also:
Constant Field Values

EUCLIDEAN

public static final int EUCLIDEAN
See Also:
Constant Field Values

HYPERBOLIC

public static final int HYPERBOLIC
See Also:
Constant Field Values

originP3

public static double[] originP3

PROJECTIVE

public static final int PROJECTIVE
See Also:
Constant Field Values

zDirectionP3

public static double[] zDirectionP3
Method Detail

cosh

public static double cosh(double x)
These hyperbolic trig functions fill in a gap in the Java math library!

Parameters:
arg -
Returns:
inverse sinh of arg

sinh

public static double sinh(double x)

tanh

public static double tanh(double x)

acosh

public static double acosh(double x)

asinh

public static double asinh(double x)

atanh

public static double atanh(double x)

angleBetween

public static double angleBetween(double[] u,
                                  double[] v,
                                  int metric)
Calculate the angle between the points u and v with respect to the metric metric.

Parameters:
u -
v -
metric -
Returns:

calculateBounds

public static double[][] calculateBounds(double[][] bounds,
                                         double[][] vlist)
Like the method calculateBounds in class Rn, but dehomogenizes the points before computing the bound.

Parameters:
bounds - double[2][3]
vlist - double[][3] or double[][4]
Returns:
bounds

centroid

public static double[] centroid(double[] average,
                                double[][] points,
                                int metric)
Calculate the centroid of points with respect to metric. This basically involves normalizing the points to have unit length with respect to the given metric before averaging them.

Parameters:
average -
points -
metric -
Returns:

dehomogenize

public static double[] dehomogenize(double[] dst,
                                    double[] src)
Dehomogenize the src array into the dst array. Both must be the same length. The src array is copied to the destination array if the last element of src is 0.0 or 1.0; otherwise each element of src is divided by the last element of src and written to the destination.

Parameters:
dst -
src -
Returns:
dst

coordForDistance

public static double coordForDistance(double d,
                                      int metric)
Return the value z so that the point (0,0,z,1) lies a distance d from the origin (0,0,0,1) in the given metric.

Parameters:
d -
metric -
Returns:

dehomogenize

public static double[][] dehomogenize(double[][] dst,
                                      double[][] src)
A vectorized version of dehomogenize(double[], double[]).

Parameters:
dst -
src -
Returns:
dst

distanceBetween

public static double distanceBetween(double[] u,
                                     double[] v,
                                     int metric)
Calculate the distance between the two points u and v. In hyperbolic geometry distances may be imaginary; here we only return the absolute value of the distance. Note: This method does not attempt to handle all possible special cases correctly, as when for example the input points lie on the Absolute Quadric, etc. It does however handle correctly various cases in the hyperbolic case, when one or both of the points lie strictly outside the hyperbolic disk. For example, when the first lies inside and the second outside, the method returns the metricned distance of the first point to the polar line of the second (which is a hyperbolic line).

Parameters:
u -
v -
metric -
Returns:
the distance

dragTangentVector

public static double[] dragTangentVector(double[] dst,
                                         double[] ddir,
                                         double[] src,
                                         double[] sdir,
                                         double length,
                                         int metric)
Drag a tangent vector sdir based at point src with initial direction given by sdir, a distance of length in the given metric. The resulting point and tangent vector is returned in ddir and dst, respectively. Warning: the source point and tangent vector are assumed to be normalized. Use normalize(double[], double[], double[], double[], int) to perform this normalization before calling this method.

Parameters:
dst -
ddir -
src -
sdir -
length -
metric -
Returns:

dragTangentVector

public static double[] dragTangentVector(double[] dstTangent,
                                         double[] sourcePoint,
                                         double[] sourceTangent,
                                         double[] dstPoint,
                                         int metric)
Drag the tangent vector sourceTangent based at sourcePoint to a tangent vector based at dstPoint.

Parameters:
ds -
ds2 -
ds3 -
ds4 -
metric -
See Also:
#dragTangentVector(double[], double[], double[], double, int)

dragTowards

public static double[] dragTowards(double[] result,
                                   double[] p0,
                                   double[] p1,
                                   double length,
                                   int metric)
Calculate the point lying a distance length from p0 in the direction p1. p1 is first converted into a tangent vector (by projection) and then {@link #dragTangentVector(double[], double[], double[], double[], double, int) is then called.

Parameters:
result -
p0 -
p1 -
length -
metric -
Returns:

homogenize

public static double[] homogenize(double[] dst,
                                  double[] src)
Extend the coordinates of src by appending 1.0

Parameters:
dst -
src -
Returns:

homogenize

public static double[][] homogenize(double[][] dst,
                                    double[][] src)
A vector version of homogenize(double[], double[]).

Parameters:
dst -
src -
Returns:

innerProduct

public static double innerProduct(double[] dst,
                                  double[] src,
                                  int metric)
Returns the inner product of the two vectors for the given metric.

Parameters:
dst -
src -
metric -
Returns:
the inner product

innerProductPlanes

public static double innerProductPlanes(double[] dst,
                                        double[] src,
                                        int metric)
The euclidean metric is not completely self-dual so we need a special method to calculate inner product of planes

Parameters:
dst -
src -
metric -
Returns:

innerProductPoints

public static double innerProductPoints(double[] dst,
                                        double[] src,
                                        int metric)
An alias for innerProduct(double[], double[], int).

Parameters:
dst -
src -
metric -
Returns:

isValidCoordinate

public static boolean isValidCoordinate(double[] transVec,
                                        int dim,
                                        int metric)

linearInterpolation

public static double[] linearInterpolation(double[] dst,
                                           double[] u,
                                           double[] v,
                                           double t,
                                           int metric)
Linear interpolate respecting the given metric metric. That is, find the point p in the linear span of u and v such that the distance(u,p):distance(u,v) = t. For the euclidean case this is equivalent to an ordinary linear interpolation: dst = (1-t)u + tv .

Parameters:
dst -
u -
v -
t -
metric -
Returns:
dst
See Also:
Rn.linearCombination(double[], double, double[], double, double[]).

makeHarmonicHarmology

public static double[] makeHarmonicHarmology(double[] dst,
                                             double[] center,
                                             double[] axis)
Construct a central projectivity with fixed point center and fixed plane axis.

Parameters:
dst -
center -
axis -
metric -
Returns:

makeFlattenProjection

public static double[] makeFlattenProjection(double[] dst,
                                             double[] center,
                                             double[] axis)
Similar to P3#makeHarmonicHarmology(double[], double[], double[]) but maps all points onto the axis plane.

Parameters:
dst -
center -
axis -
Returns:

makeGeneralizedProjection

public static double[] makeGeneralizedProjection(double[] dst,
                                                 double[] center,
                                                 double[] axis,
                                                 double val)
Create a projectivity that leaves center C invariant (planewise), axis A invariant (point-wise) and otherwise moves a general point P along the line l through P and the center depending on val. To be exact, let Q be the intersection of l with the axis. Define projective coordinates on l by setting C,P,Q to 0,1,infinity respectively. Then the projective coordinate of f(P) is val.

Parameters:
dst -
center -
axis -
val -
Returns:

midPlane

public static double[] midPlane(double[] midp,
                                double[] pl1,
                                double[] pl2,
                                int metric)
Find the plane which lies, metrically, half-way between the two given planes.

Parameters:
midp -
pl1 -
pl2 -
metric -
Returns:

norm

public static double norm(double[] src,
                          int metric)
Calculates the norm of the vector in the given metric metric. Actually returns the absolute value of the norm, since hyperbolic points can have imaginary norm.

Parameters:
src -
metric -
Returns:
the norm

normalize

public static double[] normalize(double[] dst,
                                 double[] dvec,
                                 double[] src,
                                 double[] svec,
                                 int metric)
Normalize a point-tangent pair (src, svec) so that both members have unit length and, the tangent vector lies in the polar plane of the point.

Parameters:
dst -
dvec -
src -
svec -
metric -
Returns:

normalize

public static double[] normalize(double[] dst,
                                 double[] src,
                                 int metric)
Normalizes the vector src to have unit length (either 1 or i), or, if metric is EUCLIDEAN, then the input vector is dehomogenized. To set a Euclidean vector to length 1, use setToLength(double[], double[], double, int). This method is only valid for homogeneous coordinates. Use {@link de.jreality.math.Rn#normalize(double[], double[]) if you are using dehomogenous coordinates (e.g., representing points in R3 using 3-vectors). \

Parameters:
dst -
src -
metric -
Returns:
dst

normalize

public static double[][] normalize(double[][] dst,
                                   double[][] src,
                                   int metric)
A vectorized version of normalize(double[], double[], int).

Parameters:
dst -
src -
metric -
Returns:

normalizePlane

public static double[] normalizePlane(double[] dst,
                                      double[] src,
                                      int metric)
For the euclidean special case: Normalize a hyper-plane (represented as a vector of length n) so that the direction vector (the first n-1 coordinates) has euclidean length 1 but represents the same projective hyper-plane. Otherwise normalize to have unit length;

Parameters:
dst -
src -
Returns:

normalizePoint

public static double[] normalizePoint(double[] dst,
                                      double[] src,
                                      int metric)
An alias for normalize(double[], double[], int).

Parameters:
dst -
src -
metric -
Returns:

normSquared

public static double normSquared(double[] src,
                                 int metric)
Parameters:
src -
metric -
Returns:
square of norm

polarize

public static double[] polarize(double[] polar,
                                double[] p,
                                int metric)
Polarize the input point p with respect to the quadradic form associated to metric.

Parameters:
polar -
p -
metric -
Returns:

polarize

public static double[][] polarize(double[][] polar,
                                  double[][] p,
                                  int metric)
A vectorized version of polarize(double[], double[], int).

Parameters:
polar -
p -
metric -
Returns:

polarizePlane

public static double[] polarizePlane(double[] dst,
                                     double[] plane,
                                     int metric)
This just calls polarize(double[], double[], int) since the polar plane of a point is just Q.point, where Q is the absolute quadric

Parameters:
dst -
ds -
metric -
Returns:

polarizePoint

public static double[] polarizePoint(double[] dst,
                                     double[] point,
                                     int metric)
This has to handle the exception euclidean case, that the polar of any point is the ideal plane. Otherwise it just returns polarize(double[], double[], int).

Parameters:
object -
ds -
metric -
Returns:

projectOnto

public static double[] projectOnto(double[] result,
                                   double[] master,
                                   double[] victim,
                                   int metric)
Determine the projection of the point victim onto the point master. This is orthogonal projection with respect to the metric associated to metric.

Parameters:
result -
master -
victim -
metric -
Returns:

projectOntoComplement

public static double[] projectOntoComplement(double[] result,
                                             double[] master,
                                             double[] victim,
                                             int metric)
Project victim onto the othogonal complement of master (all with respect to the given metric). See projectOnto(double[], double[], double[], int).

Parameters:
result -
master -
victim -
metric -
Returns:

projectToTangentSpace

public static double[] projectToTangentSpace(double[] result,
                                             double[] point,
                                             double[] tangentToBe,
                                             int metric)
Parameters:
result -
point -
tangentToBe -
metric -
Returns:

setToLength

public static double[] setToLength(double[] dst,
                                   double[] src,
                                   double length,
                                   int metric)
Create a multiple of src with has length length.

Parameters:
dst -
src -
length -
metric -
Returns:

setToLength

public static double[][] setToLength(double[][] dst,
                                     double[][] src,
                                     double d,
                                     int metric)
A vectorized version of setToLength(double[], double[], double, int).

Parameters:
verts -
verts2 -
d -
euclidean2 -