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 = y0
y1
...
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)

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.

Author:
Daniel Alievsky
See Also:
  • Field Summary

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

    IDENTITY
  • Method Summary

    Modifier and Type
    Method
    Description
    final double[]
    a()
    Returns an array containing A matrix.
    final double[]
    b()
    Returns an array containing b vector.
    final double[]
    c()
    Returns an array containing c vector.
    final double
    d()
    Returns the d parameter.
    final double[]
    Returns an array containing the main diagonal of A matrix.
    boolean
    Indicates whether some other object is also a coordinate transformation operator, performing the same coordinate transformation as this one.
    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.
    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
    Returns the hash code of this object.
    final boolean
    Returns true if and only if A matrix is diagonal, i.e. if aij=0.0 when i!=j.
    final boolean
    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.
    final boolean
    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.
    final int
    n()
    Returns the number of dimensions.
    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 Details

    • 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:
      NullPointerException - if one of the arguments of the method is null.
      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)
      = qk0
      qk1
      ...
      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:
      NullPointerException - if one of arguments of this method or one of elements of p and q arrays null.
      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.
      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:
      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:
      NullPointerException - if one of the arguments is null.
      IllegalArgumentException - if destPoint.length or srcPoint.length is not equal to the number of dimensions.
    • toString

      public String toString()
      Returns a brief string description of this object.
      Overrides:
      toString in class 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 Object
      Returns:
      the hash code of this operator.
    • equals

      public boolean equals(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 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.