AlgART Home
net.algart.math.functions

## Class ProjectiveOperator

• All Implemented Interfaces:
CoordinateTransformationOperator, Operator
Direct Known Subclasses:
LinearOperator

```public class ProjectiveOperator
extends AbstractCoordinateTransformationOperator
implements CoordinateTransformationOperator```

Projective operator (projective transformation): O f(x) = f(y), yi = (aix + bi) / (cx + d) (ai means the line i of the matrix A), where the numeric n x n matrix A, the n-dimensional vectors b and c and the number d are parameters of the transformation. In other words, the argument of the function, the vector x, is mapped to the following vector y:

 y = y0y1...yn−1 = (A0x + b0) / (cx + d) (A1x + b1) / (cx + d) ... (An−1x + bn−1) / (cx + d) = (a00x0 + a01x1 + ... + a0,n−1xn−1 + b0) / (c0x0 + c1x1 + ... + cn−1xn−1 + d) (a10x0 + a11x1 + ... + a1,n−1xn−1 + b1) / (c0x0 + c1x1 + ... + cn−1xn−1 + d) ... (an−1,0x0 + an−1,1x1 + ... + an−1,n−1xn−1 + bn−1) / (c0x0 + c1x1 + ... + cn−1xn−1 + d)

All calculations are performed in strictfp mode, so the result is absolutely identical on all platforms.

However, please note: we do not guarantee that the divisions in the formulas above are performed strictly by "c=a/b" Java operator. They are possibly performed via the following code: "temp=1.0/b; c=a*temp;" The difference here is very little and not important for most practical needs.

Please note: if c vector is zero (all ci=0) — in other words, if this transformation is really affine — then an instance of this class is always an instance of its inheritor `LinearOperator`. This rule is provided by the instantiation methods `getInstance(double[], double[], double[], double)` getInstance} and `getInstanceByPoints(net.algart.math.Point[], net.algart.math.Point[])` getInstanceByPoints}.

This class is immutable and thread-safe: there are no ways to modify settings of the created instance.

Since:
JDK 1.5
Version:
1.2
Author:
Daniel Alievsky
`LinearOperator`

• ### Fields inherited from interface net.algart.math.functions.Operator

`IDENTITY`
• ### Method Summary

All Methods
Modifier and Type Method and Description
`double[]` `a()`
Returns an array containing A matrix.
`double[]` `b()`
Returns an array containing b vector.
`double[]` `c()`
Returns an array containing c vector.
`double` `d()`
Returns the d parameter.
`double[]` `diagonal()`
Returns an array containing the main diagonal of A matrix.
`boolean` `equals(java.lang.Object obj)`
Indicates whether some other object is also a `coordinate transformation operator`, performing the same coordinate transformation as this one.
`static ProjectiveOperator` ```getInstance(double[] a, double[] b, double[] c, double d)```
Returns an instance of this class, describing the projective operator with the specified matrix A, the vectors b and c and the number d.
`static ProjectiveOperator` ```getInstanceByPoints(Point[] q, Point[] p)```
Returns the n-dimensional projective operator, that transforms (maps) the given n+2 points p0, p1, ..., pn+1 to the given another n+2 points q0, q1, ..., qn+1 of the n-dimensional space.
`int` `hashCode()`
Returns the hash code of this object.
`boolean` `isDiagonal()`
Returns true if and only if A matrix is diagonal, i.e. if aij=0.0 when i!=j.
`boolean` `isShift()`
Returns true if and only if A matrix is identity (i.e. if aij=0.0 when i!=j and aij=1.0 when i==j) and c vector is zero.
`boolean` `isZeroB()`
Returns true if and only if the b vector is zero, i.e. if bi=0.0 for all i.
`void` ```map(double[] destPoint, double[] srcPoint)```
This implementation calculates destPoint by the formula yi = (aix + bi) / (cx + d), where x=srcPoint and y=destPoint.
`int` `n()`
Returns the number of dimensions.
`java.lang.String` `toString()`
Returns a brief string description of this object.
• ### Methods inherited from class net.algart.math.functions.AbstractCoordinateTransformationOperator

`apply`
• ### Methods inherited from class java.lang.Object

`clone, finalize, getClass, notify, notifyAll, wait, wait, wait`
• ### Methods inherited from interface net.algart.math.functions.CoordinateTransformationOperator

`apply`
• ### Method Detail

• #### getInstance

```public static ProjectiveOperator getInstance(double[] a,
double[] b,
double[] c,
double d)```
Returns an instance of this class, describing the projective operator with the specified matrix A, the vectors b and c and the number d. See the `comments to this class` for more details. The coordinates of the vectors b and c must be listed in b and c arrays. The elements of the matrix A must be listed, row by row, in the a array: A={aij}, aij=a[i*n+j], i is the index of the row (0..n-1), j is the index of the column (0..n-1), n=b.length. The lengths of b and c arrays must be the same: b.length=c.length=n. The length a.length of the a array must be equal to its square n2. Empty arrays (n=0) are not allowed.

Please note: the returned operator can have another A, b, c, d parameters (returned by `a()`, `b()`, `c()`, `d()` methods), than specified in the arguments of this method. Namely, all these numbers can be multiplied by some constant: such modification does not change the projective transformation.

In particular, if the arguments of this method really describe an affine transformation (c=0), then this method returns an instance of `LinearOperator` class, where all elements of A matrix and b vector are divided by d number.

The passed a, b and c Java arrays are cloned by this method: no references to them are maintained by the created instance.

Parameters:
`a` - the elements of A matrix.
`b` - the coordinates of b vector.
`c` - the coordinates of c vector.
`d` - the d parameter.
Returns:
the projective operator described by these parameters.
Throws:
`java.lang.NullPointerException` - if one of the arguments of the method is null.
`java.lang.IllegalArgumentException` - if b.length==0, c.length==0, b.length!=c.length or a.length!=b.length2.
• #### getInstanceByPoints

```public static ProjectiveOperator getInstanceByPoints(Point[] q,
Point[] p)```
Returns the n-dimensional projective operator, that transforms (maps) the given n+2 points p0, p1, ..., pn+1 to the given another n+2 points q0, q1, ..., qn+1 of the n-dimensional space. The parameter d in the returned operator is 1.0. In other words, the matrix A, the vectors b, c and the parameter d in the returned operator fulfil the following conditions:
 d = 1.0; (A0pk + b0) / (cpk + 1) (A1pk + b1) / (cpk + 1) ... (An−1pk + bn−1) / (cpk + 1) = qk0qk1... qk,n−1 = qk for k = 0, 1, ..., n+1

(ai means the line i of the matrix A). It is possible that there is no such operator or there are many different solutions (degenerated cases). In this case, this method still returns some operator, but some coefficients of A matrix, b and c vectors in the returned operator will probably be Double.NaN, Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY.

All passed points must be n-dimensional, where n+2=p.length=q.length.

Parameters:
`q` - the destination points.
`p` - the source points.
Returns:
the n-dimensional projective operator, which maps pi to qi for all i=0,1,2,...,n+1.
Throws:
`java.lang.NullPointerException` - if one of arguments of this method or one of elements of p and q arrays null.
`java.lang.IllegalArgumentException` - if the lengths of the passed p and q arrays are not equal, or if for some k p[k].`coordCount()`!=p.length-2 or q[k].`coordCount()`!=p.length-2.
`java.lang.OutOfMemoryError` - if there is not enough Java memory for storing Java array double[n*(n+2)*n*(n+2)], where n+2=p.length, or if n*(n+2)*n*(n+2)>Integer.MAX_VALUE.
• #### a

`public final double[] a()`
Returns an array containing A matrix.

The returned array is always newly created: it is not a reference to some internal data stored in this object.

Returns:
A matrix.
Throws:
`java.lang.OutOfMemoryError` - if this instance was created by some creation method of the `LinearOperator` class, besides `LinearOperator.getInstance(double[], double[])`, and the matrix is too large to be stored in Java memory or its size is greater than Integer.MAX_VALUE.
• #### b

`public final double[] b()`
Returns an array containing b vector.

The returned array is always newly created: it is not a reference to some internal data stored in this object.

Returns:
b vector.
• #### c

`public final double[] c()`
Returns an array containing c vector. In a case of `LinearOperator`, the result is always zero-filled.

The returned array is always newly created: it is not a reference to some internal data stored in this object.

Returns:
c vector.
• #### d

`public final double d()`
Returns the d parameter. In a case of `LinearOperator`, the result is always 0.0.
Returns:
d parameter.
• #### diagonal

`public final double[] diagonal()`
Returns an array containing the main diagonal of A matrix.

The returned array is always newly created: it is not a reference to some internal data stored in this object.

Returns:
the main diagonal of A matrix.
• #### n

`public final int n()`
Returns the number of dimensions. The result is equal to the number of components in the b and c vectors.
Returns:
the number of dimensions.
• #### isDiagonal

`public final boolean isDiagonal()`
Returns true if and only if A matrix is diagonal, i.e. if aij=0.0 when i!=j.
Returns:
true if and only if A matrix is diagonal.
• #### isShift

`public final boolean isShift()`
Returns true if and only if A matrix is identity (i.e. if aij=0.0 when i!=j and aij=1.0 when i==j) and c vector is zero. In this case, this operator corresponds to a parallel shift. In this case, this object is always an instance of `LinearOperator`.
Returns:
true if and only if this operator describes a parallel shift in the space.
• #### isZeroB

`public final boolean isZeroB()`
Returns true if and only if the b vector is zero, i.e. if bi=0.0 for all i. If `isZeroB()` && `isShift()`, this operator is identity: it doesn't change the passed function.
Returns:
true if and only if the b vector is zero.
• #### map

```public void map(double[] destPoint,
double[] srcPoint)```
This implementation calculates destPoint by the formula yi = (aix + bi) / (cx + d), where x=srcPoint and y=destPoint. See more details in the comments to `this class`.
Specified by:
`map` in interface `CoordinateTransformationOperator`
Specified by:
`map` in class `AbstractCoordinateTransformationOperator`
Parameters:
`destPoint` - the coordinates of the destinated point y, filled by this method.
`srcPoint` - the coordinates of the source point x.
Throws:
`java.lang.NullPointerException` - if one of the arguments is null.
`java.lang.IllegalArgumentException` - if destPoint.length or srcPoint.length is not equal to the `number of dimensions`.
• #### toString

`public java.lang.String toString()`
Returns a brief string description of this object.
Overrides:
`toString` in class `java.lang.Object`
Returns:
a brief string description of this object.
• #### hashCode

`public int hashCode()`
Description copied from interface: `CoordinateTransformationOperator`
Returns the hash code of this object. The result depends on all parameters, specifying coordinate transformation, performed by this operator.
Specified by:
`hashCode` in interface `CoordinateTransformationOperator`
Overrides:
`hashCode` in class `java.lang.Object`
Returns:
the hash code of this operator.
• #### equals

`public boolean equals(java.lang.Object obj)`
Description copied from interface: `CoordinateTransformationOperator`
Indicates whether some other object is also a `coordinate transformation operator`, performing the same coordinate transformation as this one.

There is high probability, but no guarantee that this method returns true if the passed operator specifies a transformation, identical to this one. There is a guarantee that this method returns false if the passed operator specifies a transformation, different than this one.

Specified by:
`equals` in interface `CoordinateTransformationOperator`
Overrides:
`equals` in class `java.lang.Object`
Parameters:
`obj` - the object to be compared for equality with this operator.
Returns:
true if the specified object is a coordinate transformation operator equal to this one.