/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.geometry.euclidean.threed;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Objects;

import org.apache.commons.geometry.core.Transform;
import org.apache.commons.geometry.core.partitioning.AbstractHyperplane;
import org.apache.commons.geometry.core.partitioning.EmbeddingHyperplane;
import org.apache.commons.geometry.core.partitioning.Hyperplane;
import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
import org.apache.commons.geometry.euclidean.oned.Vector1D;
import org.apache.commons.geometry.euclidean.threed.rotation.QuaternionRotation;
import org.apache.commons.geometry.euclidean.twod.AffineTransformMatrix2D;
import org.apache.commons.geometry.euclidean.twod.ConvexArea;
import org.apache.commons.geometry.euclidean.twod.Vector2D;

/** Class representing a plane in 3 dimensional Euclidean space.
 */
public final class Plane extends AbstractHyperplane<Vector3D>
    implements EmbeddingHyperplane<Vector3D, Vector2D> {
    /** First normalized vector of the plane frame (in plane). */
    private final Vector3D u;

    /** Second normalized vector of the plane frame (in plane). */
    private final Vector3D v;

    /** Normalized plane normal. */
    private final Vector3D w;

    /** Offset of the origin with respect to the plane. */
    private final double originOffset;

    /**
     * Constructor to build a new plane with the given values.
     * Made private to prevent inheritance.
     * @param u u vector (on plane)
     * @param v v vector (on plane)
     * @param w unit normal vector
     * @param originOffset offset of the origin with respect to the plane.
     * @param precision precision context used to compare floating point values
     */
    private Plane(final Vector3D u, final Vector3D v, final Vector3D w, double originOffset,
            final DoublePrecisionContext precision) {

        super(precision);

        this.u = u;
        this.v = v;
        this.w = w;

        this.originOffset = originOffset;
    }

    /**
     * Get the orthogonal projection of the 3D-space origin in the plane.
     * @return the origin point of the plane frame (point closest to the 3D-space
     *         origin)
     */
    public Vector3D getOrigin() {
        return w.multiply(-originOffset);
    }

    /**
     *  Get the offset of the spatial origin ({@code 0, 0, 0}) with respect to the plane.
     *
     *  @return the offset of the origin with respect to the plane.
     */
    public double getOriginOffset() {
        return originOffset;
    }

    /**
     * Get the plane first canonical vector.
     * <p>
     * The frame defined by ({@link #getU getU}, {@link #getV getV},
     * {@link #getNormal getNormal}) is a right-handed orthonormalized frame).
     * </p>
     *
     * @return normalized first canonical vector
     * @see #getV
     * @see #getNormal
     */
    public Vector3D getU() {
        return u;
    }

    /**
     * Get the plane second canonical vector.
     * <p>
     * The frame defined by ({@link #getU getU}, {@link #getV getV},
     * {@link #getNormal getNormal}) is a right-handed orthonormalized frame).
     * </p>
     *
     * @return normalized second canonical vector
     * @see #getU
     * @see #getNormal
     */
    public Vector3D getV() {
        return v;
    }

    /**
     * Get the normalized normal vector.
     * <p>
     * The frame defined by {@link #getU()}, {@link #getV()},
     * {@link #getW()} is a right-handed orthonormalized frame.
     * </p>
     *
     * @return normalized normal vector
     * @see #getU()
     * @see #getV()
     * @see #getNormal()
     */
    public Vector3D getW() {
        return w;
    }

    /**
     * Get the normalized normal vector. This method is an alias
     * for {@link #getW()}.
     * <p>
     * The frame defined by {@link #getU()}, {@link #getV()},
     * {@link #getW()} is a right-handed orthonormalized frame.
     * </p>
     *
     * @return normalized normal vector
     * @see #getU()
     * @see #getV()
     * @see #getW()
     */
    public Vector3D getNormal() {
        return getW();
    }

    /** {@inheritDoc} */
    @Override
    public Vector3D project(final Vector3D point) {
        return toSpace(toSubspace(point));
    }

    /**
     * Project a 3D line onto the plane.
     * @param line the line to project
     * @return the projection of the given line onto the plane.
     */
    public Line3D project(final Line3D line) {
        Vector3D direction = line.getDirection();
        Vector3D projection = w.multiply(direction.dot(w) * (1 / w.normSq()));

        Vector3D projectedLineDirection = direction.subtract(projection);
        Vector3D p1 = project(line.getOrigin());
        Vector3D p2 = p1.add(projectedLineDirection);

        return Line3D.fromPoints(p1, p2, getPrecision());
    }

    /**
     * Build a new reversed version of this plane, with opposite orientation.
     * <p>
     * The new plane frame is chosen in such a way that a 3D point that had
     * {@code (x, y)} in-plane coordinates and {@code z} offset with respect to the
     * plane and is unaffected by the change will have {@code (y, x)} in-plane
     * coordinates and {@code -z} offset with respect to the new plane. This means
     * that the {@code u} and {@code v} vectors returned by the {@link #getU} and
     * {@link #getV} methods are exchanged, and the {@code w} vector returned by the
     * {@link #getNormal} method is reversed.
     * </p>
     * @return a new reversed plane
     */
    @Override
    public Plane reverse() {
        return new Plane(v, u, w.negate(), -originOffset, getPrecision());
    }

    /**
     * Transform a 3D space point into an in-plane point.
     *
     * @param point point of the space (must be a {@link Vector3D} instance)
     * @return in-plane point
     * @see #toSpace
     */
    @Override
    public Vector2D toSubspace(final Vector3D point) {
        return Vector2D.of(point.dot(u), point.dot(v));
    }

    /**
     * Transform an in-plane point into a 3D space point.
     *
     * @param point in-plane point (must be a {@link Vector2D} instance)
     * @return 3D space point
     * @see #toSubspace(Vector3D)
     */
    @Override
    public Vector3D toSpace(final Vector2D point) {
        return Vector3D.linearCombination(point.getX(), u, point.getY(), v, -originOffset, w);
    }

    /** {@inheritDoc} */
    @Override
    public Plane transform(final Transform<Vector3D> transform) {
        final Vector3D origin = getOrigin();

        final Vector3D p1 = transform.apply(origin);
        final Vector3D p2 = transform.apply(origin.add(u));
        final Vector3D p3 = transform.apply(origin.add(v));

        return fromPoints(p1, p2, p3, getPrecision());
    }

    /** Get an object containing the current plane transformed by the argument along with a
     * 2D transform that can be applied to subspace points. The subspace transform transforms
     * subspace points such that their 3D location in the transformed plane is the same as their
     * 3D location in the original plane after the 3D transform is applied. For example, consider
     * the code below:
     * <pre>
     *      SubspaceTransform st = plane.subspaceTransform(transform);
     *
     *      Vector2D subPt = Vector2D.of(1, 1);
     *
     *      Vector3D a = transform.apply(plane.toSpace(subPt)); // transform in 3D space
     *      Vector3D b = st.getPlane().toSpace(st.getTransform().apply(subPt)); // transform in 2D space
     * </pre>
     * At the end of execution, the points {@code a} (which was transformed using the original
     * 3D transform) and {@code b} (which was transformed in 2D using the subspace transform)
     * are equivalent.
     *
     * @param transform the transform to apply to this instance
     * @return an object containing the transformed plane along with a transform that can be applied
     *      to subspace points
     * @see #transform(Transform)
     */
    public SubspaceTransform subspaceTransform(final Transform<Vector3D> transform) {
        final Vector3D origin = getOrigin();

        final Vector3D p1 = transform.apply(origin);
        final Vector3D p2 = transform.apply(origin.add(u));
        final Vector3D p3 = transform.apply(origin.add(v));

        final Plane tPlane = fromPoints(p1, p2, p3, getPrecision());

        final Vector2D tSubspaceOrigin = tPlane.toSubspace(p1);
        final Vector2D tSubspaceU = tSubspaceOrigin.vectorTo(tPlane.toSubspace(p2));
        final Vector2D tSubspaceV = tSubspaceOrigin.vectorTo(tPlane.toSubspace(p3));

        final AffineTransformMatrix2D subspaceTransform =
                AffineTransformMatrix2D.fromColumnVectors(tSubspaceU, tSubspaceV, tSubspaceOrigin);

        return new SubspaceTransform(tPlane, subspaceTransform);
    }

    /**
     * Rotate the plane around the specified point.
     * <p>
     * The instance is not modified, a new instance is created.
     * </p>
     *
     * @param center   rotation center
     * @param rotation 3-dimensional rotation
     * @return a new plane
     */
    public Plane rotate(final Vector3D center, final QuaternionRotation rotation) {
        final Vector3D delta = getOrigin().subtract(center);
        final Vector3D p = center.add(rotation.apply(delta));
        final Vector3D normal = rotation.apply(this.w);
        final Vector3D wTmp = normal.normalize();

        final double originOffsetTmp = -p.dot(wTmp);
        final Vector3D uTmp = rotation.apply(this.u);
        final Vector3D vTmp = rotation.apply(this.v);

        return new Plane(uTmp, vTmp, wTmp, originOffsetTmp, getPrecision());
    }

    /**
     * Translate the plane by the specified amount.
     * <p>
     * The instance is not modified, a new instance is created.
     * </p>
     *
     * @param translation translation to apply
     * @return a new plane
     */
    public Plane translate(final Vector3D translation) {
        Vector3D p = getOrigin().add(translation);
        Vector3D normal = this.w;
        Vector3D wTmp = normal.normalize();
        double originOffsetTmp = -p.dot(wTmp);

        return new Plane(this.u, this.v, wTmp, originOffsetTmp, getPrecision());
    }

    /**
     * Get one point from the 3D-space.
     *
     * @param inPlane desired in-plane coordinates for the point in the plane
     * @param offset  desired offset for the point
     * @return one point in the 3D-space, with given coordinates and offset relative
     *         to the plane
     */
    public Vector3D pointAt(final Vector2D inPlane, final double offset) {
        return Vector3D.linearCombination(inPlane.getX(), u, inPlane.getY(), v, offset - originOffset, w);
    }

    /**
     * Check if the instance contains another plane.
     * <p>
     * Planes are considered similar if they contain the same points. This does not
     * mean they are equal since they can have opposite normals.
     * </p>
     *
     * @param plane plane to which the instance is compared
     * @return true if the planes are similar
     */
    public boolean contains(final Plane plane) {
        final double angle = w.angle(plane.w);
        final DoublePrecisionContext precision = getPrecision();

        return ((precision.eqZero(angle)) && precision.eq(originOffset, plane.originOffset)) ||
                ((precision.eq(angle, Math.PI)) && precision.eq(originOffset, -plane.originOffset));
    }

    /**
     * Get the intersection of a line with the instance.
     *
     * @param line line intersecting the instance
     * @return intersection point between between the line and the instance (null if
     *         the line is parallel to the instance)
     */
    public Vector3D intersection(final Line3D line) {
        final Vector3D direction = line.getDirection();
        final double dot = w.dot(direction);
        if (getPrecision().eqZero(dot)) {
            return null;
        }
        final Vector3D point = line.toSpace(Vector1D.ZERO);
        final double k = -(originOffset + w.dot(point)) / dot;
        return Vector3D.linearCombination(1.0, point, k, direction);
    }

    /**
     * Get the line formed by the intersection of this instance with the given plane.
     * The returned line lies in both planes and points in the direction of
     * the cross product <code>n<sub>1</sub> x n<sub>2</sub></code>, where <code>n<sub>1</sub></code>
     * is the normal of the current instance and <code>n<sub>2</sub></code> is the normal
     * of the argument.
     *
     * <p>Null is returned if the planes are parallel.</p>
     *
     * @param other other plane
     * @return line at the intersection of the instance and the other plane, or null
     *      if no such line exists
     */
    public Line3D intersection(final Plane other) {
        final Vector3D direction = w.cross(other.w);
        if (getPrecision().eqZero(direction.norm())) {
            return null;
        }
        final Vector3D point = intersection(this, other, Plane.fromNormal(direction, getPrecision()));
        return Line3D.fromPointAndDirection(point, direction, getPrecision());
    }

    /**
     * Get the intersection point of three planes. Returns null if no unique intersection point
     * exists (ie, there are no intersection points or an infinite number).
     *
     * @param plane1 first plane1
     * @param plane2 second plane2
     * @param plane3 third plane2
     * @return intersection point of the three planes or null if no unique intersection point exists
     */
    public static Vector3D intersection(final Plane plane1, final Plane plane2, final Plane plane3) {

        // coefficients of the three planes linear equations
        final double a1 = plane1.w.getX();
        final double b1 = plane1.w.getY();
        final double c1 = plane1.w.getZ();
        final double d1 = plane1.originOffset;

        final double a2 = plane2.w.getX();
        final double b2 = plane2.w.getY();
        final double c2 = plane2.w.getZ();
        final double d2 = plane2.originOffset;

        final double a3 = plane3.w.getX();
        final double b3 = plane3.w.getY();
        final double c3 = plane3.w.getZ();
        final double d3 = plane3.originOffset;

        // direct Cramer resolution of the linear system
        // (this is still feasible for a 3x3 system)
        final double a23 = (b2 * c3) - (b3 * c2);
        final double b23 = (c2 * a3) - (c3 * a2);
        final double c23 = (a2 * b3) - (a3 * b2);
        final double determinant = (a1 * a23) + (b1 * b23) + (c1 * c23);

        // use the precision context of the first plane to determine equality
        if (plane1.getPrecision().eqZero(determinant)) {
            return null;
        }

        final double r = 1.0 / determinant;
        return Vector3D.of((-a23 * d1 - (c1 * b3 - c3 * b1) * d2 - (c2 * b1 - c1 * b2) * d3) * r,
                (-b23 * d1 - (c3 * a1 - c1 * a3) * d2 - (c1 * a2 - c2 * a1) * d3) * r,
                (-c23 * d1 - (b1 * a3 - b3 * a1) * d2 - (b2 * a1 - b1 * a2) * d3) * r);

    }

    /** {@inheritDoc} */
    @Override
    public ConvexSubPlane span() {
        return ConvexSubPlane.fromConvexArea(this, ConvexArea.full());
    }

    /**
     * Check if the instance contains a point.
     *
     * @param p point to check
     * @return true if p belongs to the plane
     */
    @Override
    public boolean contains(final Vector3D p) {
        return getPrecision().eqZero(offset(p));
    }

    /**
     * Check if the instance contains a line.
     * @param line line to check
     * @return true if line is contained in this plane
     */
    public boolean contains(final Line3D line) {
        return isParallel(line) && contains(line.getOrigin());
    }

    /** Check if the line is parallel to the instance.
     * @param line line to check.
     * @return true if the line is parallel to the instance, false otherwise.
     */
    public boolean isParallel(final Line3D line) {
        final double dot = w.dot(line.getDirection());

        return getPrecision().eqZero(dot);
    }

    /** Check, if the plane is parallel to the instance.
     * @param plane plane to check.
     * @return true if the plane is parallel to the instance, false otherwise.
     */
    public boolean isParallel(final Plane plane) {
        return getPrecision().eqZero(w.cross(plane.w).norm());
    }

    /**
     * Get the offset (oriented distance) of the given plane with respect to this instance. The value
     * closest to zero is returned, which will always be zero if the planes are not parallel.
     * @param plane plane to calculate the offset of
     * @return the offset of the plane with respect to this instance or 0.0 if the planes
     *      are not parallel.
     */
    public double offset(final Plane plane) {
        if (!isParallel(plane)) {
            return 0.0;
        }
        return originOffset + (similarOrientation(plane) ? -plane.originOffset : plane.originOffset);
    }

    /**
     * Get the offset (oriented distance) of the given line with respect to the plane. The value
     * closest to zero is returned, which will always be zero if the line is not parallel to the plane.
     * @param line line to calculate the offset of
     * @return the offset of the line with respect to the plane or 0.0 if the line
     *      is not parallel to the plane.
     */
    public double offset(final Line3D line) {
        if (!isParallel(line)) {
            return 0.0;
        }
        return offset(line.getOrigin());
    }

    /** {@inheritDoc} */
    @Override
    public double offset(final Vector3D point) {
        return point.dot(w) + originOffset;
    }

    /** {@inheritDoc} */
    @Override
    public boolean similarOrientation(final Hyperplane<Vector3D> other) {
        return (((Plane) other).w).dot(w) > 0;
    }


    /** Return true if this instance should be considered equivalent to the argument, using the
     * given precision context for comparison. Instances are considered equivalent if they
     * have equivalent {@code origin} points and {@code u} and {@code v} vectors.
     * @param other the point to compare with
     * @param precision precision context to use for the comparison
     * @return true if this instance should be considered equivalent to the argument
     * @see Vector3D#eq(Vector3D, DoublePrecisionContext)
     */
    public boolean eq(final Plane other, final DoublePrecisionContext precision) {
        return getOrigin().eq(other.getOrigin(), precision) &&
                u.eq(other.u, precision) &&
                v.eq(other.v, precision);
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return Objects.hash(u, v, w, originOffset, getPrecision());
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        } else if (!(obj instanceof Plane)) {
            return false;
        }

        Plane other = (Plane) obj;

        return Objects.equals(this.u, other.u) &&
                Objects.equals(this.v, other.v) &&
                Objects.equals(this.w, other.w) &&
                Double.compare(this.originOffset, other.originOffset) == 0 &&
                Objects.equals(this.getPrecision(), other.getPrecision());
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName())
            .append("[origin= ")
            .append(getOrigin())
            .append(", u= ")
            .append(u)
            .append(", v= ")
            .append(v)
            .append(", w= ")
            .append(w)
            .append(']');

        return sb.toString();
    }

    /**
     * Build a plane from a point and two (on plane) vectors.
     * @param p the provided point (on plane)
     * @param u u vector (on plane)
     * @param v v vector (on plane)
     * @param precision precision context used to compare floating point values
     * @return a new plane
     * @throws IllegalArgumentException if the norm of the given values is zero, NaN, or infinite.
     */
    public static Plane fromPointAndPlaneVectors(final Vector3D p, final Vector3D u, final Vector3D v,
            final DoublePrecisionContext precision) {
        Vector3D uNorm = u.normalize();
        Vector3D vNorm = uNorm.orthogonal(v);
        Vector3D wNorm = uNorm.cross(vNorm).normalize();
        double originOffset = -p.dot(wNorm);

        return new Plane(uNorm, vNorm, wNorm, originOffset, precision);
    }

    /**
     * Build a plane from a normal.
     * Chooses origin as point on plane.
     * @param normal    normal direction to the plane
     * @param precision precision context used to compare floating point values
     * @return a new plane
     * @throws IllegalArgumentException if the norm of the given values is zero, NaN, or infinite.
     */
    public static Plane fromNormal(final Vector3D normal, final DoublePrecisionContext precision) {
        return fromPointAndNormal(Vector3D.ZERO, normal, precision);
    }

    /**
     * Build a plane from a point and a normal.
     *
     * @param p         point belonging to the plane
     * @param normal    normal direction to the plane
     * @param precision precision context used to compare floating point values
     * @return a new plane
     * @throws IllegalArgumentException if the norm of the given values is zero, NaN, or infinite.
     */
    public static Plane fromPointAndNormal(final Vector3D p, final Vector3D normal,
            final DoublePrecisionContext precision) {
        Vector3D w = normal.normalize();
        double originOffset = -p.dot(w);

        Vector3D u = w.orthogonal();
        Vector3D v = w.cross(u);

        return new Plane(u, v, w, originOffset, precision);
    }

    /**
     * Build a plane from three points.
     * <p>
     * The plane is oriented in the direction of {@code (p2-p1) ^ (p3-p1)}
     * </p>
     *
     * @param p1        first point belonging to the plane
     * @param p2        second point belonging to the plane
     * @param p3        third point belonging to the plane
     * @param precision precision context used to compare floating point values
     * @return a new plane
     * @throws IllegalArgumentException if the points do not define a unique plane
     */
    public static Plane fromPoints(final Vector3D p1, final Vector3D p2, final Vector3D p3,
            final DoublePrecisionContext precision) {
        return Plane.fromPoints(Arrays.asList(p1, p2, p3), precision);
    }

    /** Construct a plane from a collection of points lying on the plane. The plane orientation is
     * determined by the overall orientation of the point sequence. For example, if the points wind
     * around the z-axis in a counter-clockwise direction, then the plane normal will point up the
     * +z axis. If the points wind in the opposite direction, then the plane normal will point down
     * the -z axis. The {@code u} vector for the plane is set to the first non-zero vector between
     * points in the sequence (ie, the first direction in the path).
     *
     * @param pts collection of sequenced points lying on the plane
     * @param precision precision context used to compare floating point values
     * @return a new plane containing the given points
     * @throws IllegalArgumentException if the given collection does not contain at least 3 points or the
     *      points do not define a unique plane
     */
    public static Plane fromPoints(final Collection<Vector3D> pts, final DoublePrecisionContext precision) {

        if (pts.size() < 3) {
            throw new IllegalArgumentException("At least 3 points are required to define a plane; " +
                    "argument contains only " + pts.size() + ".");
        }

        final Iterator<Vector3D> it = pts.iterator();

        Vector3D startPt = it.next();

        Vector3D u = null;
        Vector3D w = null;

        Vector3D currentPt;
        Vector3D prevPt = startPt;

        Vector3D currentVector = null;
        Vector3D prevVector = null;

        Vector3D cross = null;
        double crossNorm;
        double crossSumX = 0.0;
        double crossSumY = 0.0;
        double crossSumZ = 0.0;

        boolean nonPlanar = false;

        while (it.hasNext()) {
            currentPt = it.next();

            if (!currentPt.eq(prevPt, precision)) {
                currentVector = startPt.vectorTo(currentPt);

                if (u == null) {
                    // save the first non-zero vector as our u vector
                    u = currentVector.normalize();
                }
                if (prevVector != null) {
                    cross = prevVector.cross(currentVector);

                    crossSumX += cross.getX();
                    crossSumY += cross.getY();
                    crossSumZ += cross.getZ();

                    crossNorm = cross.norm();

                    if (!precision.eqZero(crossNorm)) {
                        // the cross product has non-zero magnitude
                        if (w == null) {
                            // save the first non-zero cross product as our normal
                            w = cross.normalize();
                        } else if (!precision.eq(1.0, Math.abs(w.dot(cross) / crossNorm))) {
                            // if the normalized dot product is not either +1 or -1, then
                            // the points are not coplanar
                            nonPlanar = true;
                            break;
                        }
                    }
                }

                prevVector = currentVector;
                prevPt = currentPt;
            }
        }

        if (u == null || w == null || nonPlanar) {
            throw new IllegalArgumentException("Points do not define a plane: " + pts);
        }

        if (w.dot(Vector3D.of(crossSumX, crossSumY, crossSumZ)) < 0) {
            w = w.negate();
        }

        final Vector3D v = w.cross(u);
        final double originOffset = -startPt.dot(w);

        return new Plane(u, v, w, originOffset, precision);
    }

    /** Class containing a transformed plane instance along with a subspace (2D) transform. The subspace
     * transform produces the equivalent of the 3D transform in 2D.
     */
    public static final class SubspaceTransform {
        /** The transformed plane. */
        private final Plane plane;

        /** The subspace transform instance. */
        private final AffineTransformMatrix2D transform;

        /** Simple constructor.
         * @param plane the transformed plane
         * @param transform 2D transform that can be applied to subspace points
         */
        public SubspaceTransform(final Plane plane, final AffineTransformMatrix2D transform) {
            this.plane = plane;
            this.transform = transform;
        }

        /** Get the transformed plane instance.
         * @return the transformed plane instance
         */
        public Plane getPlane() {
            return plane;
        }

        /** Get the 2D transform that can be applied to subspace points. This transform can be used
         * to perform the equivalent of the 3D transform in 2D space.
         * @return the subspace transform instance
         */
        public AffineTransformMatrix2D getTransform() {
            return transform;
        }
    }
}
