Transformation3D.java
/*
* Copyright (C) 2012 Alberto Irurueta Carro (alberto@irurueta.com)
*
* Licensed 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 com.irurueta.geometry;
import com.irurueta.algebra.AlgebraException;
import com.irurueta.algebra.Matrix;
import java.util.ArrayList;
import java.util.List;
/**
* This class performs transformations on 3D space.
* Transformations can be applied to any 3D geometric figure.
*/
public abstract class Transformation3D {
/**
* Empty constructor.
*/
protected Transformation3D() {
}
/**
* Transforms provided point using this transformation and returns a new
* one.
*
* @param inputPoint point to be transformed.
* @return a new transformed point.
*/
public Point3D transformAndReturnNew(final Point3D inputPoint) {
final var outputPoint = Point3D.create();
transform(inputPoint, outputPoint);
return outputPoint;
}
/**
* Transforms and updates provided point.
*
* @param point point to be transformed and updated.
*/
public void transform(final Point3D point) {
transform(point, point);
}
/**
* Transforms input point using this transformation and stores the result in
* provided output points.
*
* @param inputPoint point to be transformed.
* @param outputPoint instance where transformed point data will be stored.
*/
public abstract void transform(final Point3D inputPoint, final Point3D outputPoint);
/**
* Transforms provided list of points using this transformation.
*
* @param inputPoints points to be transformed.
* @return new transformed points.
*/
public List<Point3D> transformPointsAndReturnNew(final List<Point3D> inputPoints) {
final var outputPoints = new ArrayList<Point3D>(inputPoints.size());
transformPoints(inputPoints, outputPoints);
return outputPoints;
}
/**
* Transforms provided list of points using this transformation and stores
* the result in provided output list of points.
* Notice that any previous content in output list will be removed when
* calling this method.
*
* @param inputPoints points to be transformed.
* @param outputPoints transformed points.
*/
public void transformPoints(final List<Point3D> inputPoints, final List<Point3D> outputPoints) {
outputPoints.clear();
for (final var point : inputPoints) {
outputPoints.add(transformAndReturnNew(point));
}
}
/**
* Transforms provided list of points using this transformation and
* overwriting their previous values.
*
* @param points points to be transformed and overwritten.
*/
public void transformAndOverwritePoints(final List<Point3D> points) {
for (final var point : points) {
transform(point, point);
}
}
/**
* Transforms a quadric using this transformation and returns a new one.
*
* @param inputQuadric quadric to be transformed.
* @return a new transformed quadric.
* @throws NonSymmetricMatrixException raised if due to numerical precision
* the resulting output quadric matrix is not considered to be symmetric.
* @throws AlgebraException raised if transform cannot be computed because of
* numerical instabilities.
*/
public Quadric transformAndReturnNew(final Quadric inputQuadric) throws NonSymmetricMatrixException,
AlgebraException {
final var outputQuadric = new Quadric();
transform(inputQuadric, outputQuadric);
return outputQuadric;
}
/**
* Transforms and updates provided quadric.
*
* @param quadric quadric to be transformed.
* @throws NonSymmetricMatrixException raised if due to numerical precision
* the resulting quadric matrix is not considered to be symmetric.
* @throws AlgebraException raised if transform cannot be computed because of
* numerical instabilities.
*/
public void transform(final Quadric quadric) throws NonSymmetricMatrixException, AlgebraException {
transform(quadric, quadric);
}
/**
* Transforms a quadric using this transformation and stores the result into
* provided output quadric.
*
* @param inputQuadric quadric to be transformed.
* @param outputQuadric instance where data of transformed quadric will be
* stored.
* @throws NonSymmetricMatrixException raised if due to numerical precision
* the resulting output quadric matrix is not considered to be symmetric.
* @throws AlgebraException raised if transform cannot be computed because of
* numerical instabilities.
*/
public abstract void transform(final Quadric inputQuadric, final Quadric outputQuadric)
throws NonSymmetricMatrixException, AlgebraException;
/**
* Transforms a dual quadric using this transformation and returns a new
* one.
*
* @param inputDualQuadric dual quadric to be transformed.
* @return a new transformed dual quadric.
* @throws NonSymmetricMatrixException raised if due to numerical precision
* the resulting output dual quadric matrix is not considered to be
* symmetric.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public DualQuadric transformAndReturnNew(final DualQuadric inputDualQuadric)
throws NonSymmetricMatrixException, AlgebraException {
final var outputDualQuadric = new DualQuadric();
transform(inputDualQuadric, outputDualQuadric);
return outputDualQuadric;
}
/**
* Transforms and updates a dual quadric using this transformation.
*
* @param dualQuadric dual quadric to be transformed.
* @throws NonSymmetricMatrixException raised if due to numerical precision
* the resulting output dual quadric matrix is not considered to be
* symmetric.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public void transform(final DualQuadric dualQuadric) throws NonSymmetricMatrixException, AlgebraException {
transform(dualQuadric, dualQuadric);
}
/**
* Transforms a dual quadric using this transformation and stores the result
* into provided output dual quadric.
*
* @param inputDualQuadric dual quadric to be transformed.
* @param outputDualQuadric instance where data of transformed dual quadric
* will be stored.
* @throws NonSymmetricMatrixException Raised if due to numerical precision
* the resulting output dual quadric matrix is not considered to be
* symmetric.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public abstract void transform(final DualQuadric inputDualQuadric, final DualQuadric outputDualQuadric)
throws NonSymmetricMatrixException, AlgebraException;
/**
* Transforms provided plane using this transformation and returns a new
* one.
*
* @param inputPlane plane to be transformed.
* @return a new transformed plane.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public Plane transformAndReturnNew(final Plane inputPlane) throws AlgebraException {
final var outputPlane = new Plane();
transform(inputPlane, outputPlane);
return outputPlane;
}
/**
* Transforms and updates provided plane using this transformation.
*
* @param plane plane to be transformed.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public void transform(final Plane plane) throws AlgebraException {
transform(plane, plane);
}
/**
* Transforms provided input plane using this transformation and stores the
* result into provided output plane instance.
*
* @param inputPlane plane to be transformed.
* @param outputPlane instance where data of transformed plane will be
* stored.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public abstract void transform(final Plane inputPlane, final Plane outputPlane) throws AlgebraException;
/**
* Transforms provided list of planes using this transformation.
*
* @param inputPlanes planes to be transformed.
* @return transformed planes.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public List<Plane> transformPlanesAndReturnNew(final List<Plane> inputPlanes) throws AlgebraException {
final var outputPlanes = new ArrayList<Plane>(inputPlanes.size());
transformPlanes(inputPlanes, outputPlanes);
return outputPlanes;
}
/**
* Transforms provided list of planes using this transformation and stores
* the result in provided output list of planes.
* Notice that any previous content in output list will be removed when
* calling this method.
*
* @param inputPlanes planes to be transformed.
* @param outputPlanes transformed planes.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public void transformPlanes(final List<Plane> inputPlanes, final List<Plane> outputPlanes) throws AlgebraException {
outputPlanes.clear();
for (final var plane : inputPlanes) {
outputPlanes.add(transformAndReturnNew(plane));
}
}
/**
* Transforms provided list of planes using this transformation and
* overwriting their previous values.
*
* @param planes planes to be transformed and overwritten.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public void transformAndOverwritePlanes(final List<Plane> planes) throws AlgebraException {
for (final var plane : planes) {
transform(plane, plane);
}
}
/**
* Transforms provided line using this transformation and returns a new one.
*
* @param inputLine line to be transformed.
* @return transformed line.
* @throws CoincidentPlanesException raised if transformation is degenerate
* and results in planes forming a line being coincident.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public Line3D transformAndReturnNew(final Line3D inputLine) throws CoincidentPlanesException, AlgebraException {
final var plane1 = transformAndReturnNew(inputLine.getPlane1());
final var plane2 = transformAndReturnNew(inputLine.getPlane2());
return new Line3D(plane1, plane2);
}
/**
* Transforms and updates provided line using this transformation.
*
* @param line line to be transformed.
* @throws CoincidentPlanesException raised if transformation is degenerate
* and results in planes forming a line being coincident.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public void transform(final Line3D line) throws CoincidentPlanesException, AlgebraException {
transform(line, line);
}
/**
* Transforms provided input line using this transformation and stores the
* result into provided output line instance.
*
* @param inputLine line to be transformed.
* @param outputLine instance where data of transformed line will be stored.
* @throws CoincidentPlanesException Raised if transformation is degenerate
* and results in planes forming a line being coincident.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public void transform(final Line3D inputLine, final Line3D outputLine) throws CoincidentPlanesException,
AlgebraException {
final var plane1 = transformAndReturnNew(inputLine.getPlane1());
final var plane2 = transformAndReturnNew(inputLine.getPlane2());
outputLine.setPlanes(plane1, plane2);
}
/**
* Transforms provided list of lines using this transformation.
*
* @param inputLines lines to be transformed.
* @return transformed lines.
* @throws CoincidentPlanesException raised if transformation is degenerate
* and results in planes forming a line being coincident.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public List<Line3D> transformLines(final List<Line3D> inputLines) throws CoincidentPlanesException,
AlgebraException {
final var outputLines = new ArrayList<Line3D>(inputLines.size());
transformLines(inputLines, outputLines);
return outputLines;
}
/**
* Transforms provided list of lines using this transformation and stores
* the result in provided output list of lines.
* Notice that any previous content in output list will be removed when
* calling this method.
*
* @param inputLines lines to be transformed.
* @param outputLines transformed lines.
* @throws CoincidentPlanesException raised if transformation is degenerate
* and results in planes forming a line being coincident.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public void transformLines(
final List<Line3D> inputLines, final List<Line3D> outputLines) throws CoincidentPlanesException,
AlgebraException {
outputLines.clear();
for (final var line : inputLines) {
outputLines.add(transformAndReturnNew(line));
}
}
/**
* Transforms provided list of lines using this transformation and
* overwriting their previous values.
*
* @param lines lines to be transformed and overwritten.
* @throws CoincidentPlanesException raised if transformation is degenerate
* and results in planes forming a line being coincident.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public void transformAndOverwriteLines(final List<Line3D> lines) throws CoincidentPlanesException,
AlgebraException {
for (final var line : lines) {
transform(line, line);
}
}
/**
* Transforms provided polygon using this transformation and returns a new
* one.
*
* @param inputPolygon polygon to be transformed.
* @return a new transformed polygon.
*/
public Polygon3D transformAndReturnNew(final Polygon3D inputPolygon) {
final var outVertices = transformPointsAndReturnNew(inputPolygon.getVertices());
try {
return new Polygon3D(outVertices);
} catch (final NotEnoughVerticesException ignore) {
// this will never happen because all existing polygons have enough
// vertices
return null;
}
}
/**
* Transforms and updates provided polygon using this transformation.
*
* @param polygon polygon to be transformed.
*/
public void transform(final Polygon3D polygon) {
transformAndOverwritePoints(polygon.getVertices());
}
/**
* Transforms provided input polygon using this transformation and stores
* the result into provided output polygon instance.
*
* @param inputPolygon polygon to be transformed.
* @param outputPolygon Instance where transformed polygon data will be
* stored.
*/
public void transform(final Polygon3D inputPolygon, final Polygon3D outputPolygon) {
try {
outputPolygon.setVertices(transformPointsAndReturnNew(inputPolygon.getVertices()));
} catch (final NotEnoughVerticesException ignore) {
// this will never happen because all existing polygons have enough
// vertices
}
}
/**
* Transforms provided triangle using this transformation and returns a new
* one.
*
* @param inputTriangle triangle to be transformed.
* @return a new transformed triangle.
*/
public Triangle3D transformAndReturnNew(final Triangle3D inputTriangle) {
final var vertex1 = transformAndReturnNew(inputTriangle.getVertex1());
final var vertex2 = transformAndReturnNew(inputTriangle.getVertex2());
final var vertex3 = transformAndReturnNew(inputTriangle.getVertex3());
return new Triangle3D(vertex1, vertex2, vertex3);
}
/**
* Transforms and updates provided input triangle using this transformation.
*
* @param triangle triangle to be transformed.
*/
public void transform(final Triangle3D triangle) {
transform(triangle, triangle);
}
/**
* Transforms provided input triangle using this transformation and stores
* the result into provided output triangle instance.
*
* @param inputTriangle triangle to be transformed.
* @param outputTriangle instance where transformed triangle data will be
* stored.
*/
public void transform(final Triangle3D inputTriangle, final Triangle3D outputTriangle) {
transform(inputTriangle.getVertex1(), outputTriangle.getVertex1());
transform(inputTriangle.getVertex2(), outputTriangle.getVertex2());
transform(inputTriangle.getVertex3(), outputTriangle.getVertex3());
}
/**
* Represents this transformation as a 4x4 matrix.
* A point can be transformed as T * p, where T is the transformation matrix
* and p is a point expressed as an homogeneous vector.
*
* @return this transformation in matrix form.
*/
public abstract Matrix asMatrix();
/**
* Represents this transformation as a 4x4 matrix and stores the result in
* provided instance.
*
* @param m instance where transformation matrix will be stored.
* @throws IllegalArgumentException raised if provided instance is not a 3x3
* matrix.
*/
public abstract void asMatrix(final Matrix m);
/**
* Transforms a camera using this transformation.
*
* @param camera camera to be transformed.
* @return transformed quadric.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public PinholeCamera transformAndReturnNew(final PinholeCamera camera) throws AlgebraException {
final var outputCamera = new PinholeCamera();
transform(camera, outputCamera);
return outputCamera;
}
/**
* Transforms and updates provided camera using this transformation.
*
* @param camera camera to be transformed.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public void transform(final PinholeCamera camera) throws AlgebraException {
transform(camera, camera);
}
/**
* Transforms a camera using this transformation and stores the result into
* provided output camera.
*
* @param inputCamera camera to be transformed.
* @param outputCamera instance where data of transformed camera will be
* stored.
* @throws AlgebraException raised if transform cannot be computed because
* of numerical instabilities.
*/
public abstract void transform(final PinholeCamera inputCamera, final PinholeCamera outputCamera)
throws AlgebraException;
}