1 /*
2 * @file
3 * This file contains implementation of
4 * com.irurueta.geometry.Transformation2D
5 *
6 * @author Alberto Irurueta (alberto@irurueta.com)
7 * @date October 25, 2012
8 */
9 package com.irurueta.geometry;
10
11 import com.irurueta.algebra.AlgebraException;
12 import com.irurueta.algebra.Matrix;
13
14 import java.util.ArrayList;
15 import java.util.List;
16
17 /**
18 * This class performs transformations on 2D space.
19 * Transformations can be applied to any 2D geometric figure.
20 */
21 public abstract class Transformation2D {
22
23 /**
24 * Empty constructor.
25 */
26 protected Transformation2D() {
27 }
28
29 /**
30 * Transforms provided point using this transformation.
31 *
32 * @param inputPoint point to be transformed.
33 * @return transformed point.
34 */
35 public Point2D transformAndReturnNew(final Point2D inputPoint) {
36 final var outputPoint = Point2D.create();
37 transform(inputPoint, outputPoint);
38 return outputPoint;
39 }
40
41 /**
42 * Transforms and updates provided point.
43 *
44 * @param point point to be transformed and updated.
45 */
46 public void transform(final Point2D point) {
47 transform(point, point);
48 }
49
50 /**
51 * Transforms input point using this transformation and stores the result in
52 * provided output points.
53 *
54 * @param inputPoint point to be transformed.
55 * @param outputPoint instance where transformed point data will be stored.
56 */
57 public abstract void transform(final Point2D inputPoint, final Point2D outputPoint);
58
59 /**
60 * Transforms provided list of points using this transformation and returns
61 * a new one.
62 *
63 * @param inputPoints points to be transformed.
64 * @return transformed points.
65 */
66 public List<Point2D> transformPointsAndReturnNew(final List<Point2D> inputPoints) {
67 final var outputPoints = new ArrayList<Point2D>(inputPoints.size());
68 transformPoints(inputPoints, outputPoints);
69 return outputPoints;
70 }
71
72 /**
73 * Transforms provided list of points using this transformation and stores
74 * the result in provided output list of points.
75 * Notice that any previous content in output list will be removed when
76 * calling this method.
77 *
78 * @param inputPoints points to be transformed.
79 * @param outputPoints transformed points.
80 */
81 public void transformPoints(final List<Point2D> inputPoints, final List<Point2D> outputPoints) {
82
83 outputPoints.clear();
84 for (final var point : inputPoints) {
85 outputPoints.add(Transformation2D.this.transformAndReturnNew(point));
86 }
87 }
88
89 /**
90 * Transforms provided list of points using this transformation and
91 * overwriting their previous values.
92 *
93 * @param points points to be transformed and overwritten.
94 */
95 public void transformAndOverwritePoints(final List<Point2D> points) {
96 for (final var point : points) {
97 transform(point, point);
98 }
99 }
100
101 /**
102 * Transforms a conic using this transformation and returns a new one.
103 *
104 * @param inputConic conic to be transformed.
105 * @return transformed conic.
106 * @throws NonSymmetricMatrixException raised if due to numerical precision
107 * the resulting output conic matrix is not considered to be symmetric.
108 * @throws AlgebraException raised if transform cannot be computed because of
109 * numerical instabilities.
110 */
111 public Conic transformAndReturnNew(final Conic inputConic) throws NonSymmetricMatrixException, AlgebraException {
112 final var outputConic = new Conic();
113 transform(inputConic, outputConic);
114 return outputConic;
115 }
116
117 /**
118 * Transforms and updates provided conic.
119 *
120 * @param conic conic to be transformed.
121 * @throws NonSymmetricMatrixException raised if due to numerical precision
122 * the resulting conic matrix is not considered to be symmetric.
123 * @throws AlgebraException raised if transform cannot be computed because of
124 * numerical instabilities.
125 */
126 public void transform(final Conic conic) throws NonSymmetricMatrixException, AlgebraException {
127 transform(conic, conic);
128 }
129
130 /**
131 * Transforms a conic using this transformation and stores the result into
132 * provided output conic.
133 *
134 * @param inputConic conic to be transformed.
135 * @param outputConic instance where data of transformed conic will be
136 * stored.
137 * @throws NonSymmetricMatrixException raised if due to numerical precision
138 * the resulting output conic matrix is not considered to be symmetric.
139 * @throws AlgebraException raised if transform cannot be computed because of
140 * numerical instabilities.
141 */
142 public abstract void transform(final Conic inputConic, final Conic outputConic) throws NonSymmetricMatrixException,
143 AlgebraException;
144
145 /**
146 * Transforms a dual conic using this transformation and returns a new one.
147 *
148 * @param inputDualConic dual conic to be transformed.
149 * @return transformed dual conic.
150 * @throws NonSymmetricMatrixException raised if due to numerical precision
151 * the resulting output conic matrix is not considered to be symmetric.
152 * @throws AlgebraException raised if transform cannot be computed because
153 * of numerical instabilities.
154 */
155 public DualConic transformAndReturnNew(final DualConic inputDualConic) throws NonSymmetricMatrixException,
156 AlgebraException {
157 final var outputDualConic = new DualConic();
158 transform(inputDualConic, outputDualConic);
159 return outputDualConic;
160 }
161
162 /**
163 * Transforms and updates a dual conic using this transformation.
164 *
165 * @param dualConic dual conic to be transformed.
166 * @throws NonSymmetricMatrixException raised if due to numerical precision
167 * the resulting conic matrix is not considered to be symmetric.
168 * @throws AlgebraException raised if transform cannot be computed because
169 * of numerical instabilities.
170 */
171 public void transform(final DualConic dualConic) throws NonSymmetricMatrixException, AlgebraException {
172 transform(dualConic, dualConic);
173 }
174
175 /**
176 * Transforms a dual conic using this transformation and stores the result
177 * into provided output dual conic.
178 *
179 * @param inputDualConic dual conic to be transformed.
180 * @param outputDualConic instance where data of transformed dual conic will
181 * be stored.
182 * @throws NonSymmetricMatrixException raised if due to numerical precision
183 * the resulting output dual conic matrix is not considered to be symmetric.
184 * @throws AlgebraException Raised if transform cannot be computed because
185 * of numerical instabilities.
186 */
187 public abstract void transform(final DualConic inputDualConic, final DualConic outputDualConic)
188 throws NonSymmetricMatrixException, AlgebraException;
189
190 /**
191 * Transforms provided line using this transformation and returns a new one.
192 *
193 * @param inputLine line to be transformed.
194 * @return transformed line.
195 * @throws AlgebraException raised if transform cannot be computed because
196 * of numerical instabilities.
197 */
198 public Line2D transformAndReturnNew(final Line2D inputLine) throws AlgebraException {
199 final var outputLine = new Line2D();
200 transform(inputLine, outputLine);
201 return outputLine;
202 }
203
204 /**
205 * Transforms and updates provided line using this transformation.
206 *
207 * @param line line to be transformed and updated.
208 * @throws AlgebraException if transform cannot be computed because of
209 * numerical instabilities.
210 */
211 public void transform(final Line2D line) throws AlgebraException {
212 transform(line, line);
213 }
214
215 /**
216 * Transforms provided input line using this transformation and stores the
217 * result into provided output line instance.
218 *
219 * @param inputLine line to be transformed.
220 * @param outputLine instance where data of transformed line will be stored.
221 * @throws AlgebraException Raised if transform cannot be computed because
222 * of numerical instabilities.
223 */
224 public abstract void transform(final Line2D inputLine, final Line2D outputLine) throws AlgebraException;
225
226 /**
227 * Transforms provided list of lines using this transformation and returns
228 * a new one.
229 *
230 * @param inputLines lines to be transformed.
231 * @return transformed lines.
232 * @throws AlgebraException raised if transform cannot be computed because
233 * of numerical instabilities.
234 */
235 public List<Line2D> transformLinesAndReturnNew(final List<Line2D> inputLines) throws AlgebraException {
236 final var outputLines = new ArrayList<Line2D>(inputLines.size());
237 transformLines(inputLines, outputLines);
238 return outputLines;
239 }
240
241 /**
242 * Transforms provided list of lines using this transformation and stores
243 * the result in provided output list of lines.
244 * Notice that any previous content in output list will be removed when
245 * calling this method.
246 *
247 * @param inputLines lines to be transformed.
248 * @param outputLines transformed lines.
249 * @throws AlgebraException raised if transform cannot be computed because
250 * of numerical instabilities.
251 */
252 public void transformLines(final List<Line2D> inputLines, final List<Line2D> outputLines) throws AlgebraException {
253 outputLines.clear();
254 for (final var line : inputLines) {
255 outputLines.add(Transformation2D.this.transformAndReturnNew(line));
256 }
257 }
258
259 /**
260 * Transforms provided list of lines using this transformation and
261 * overwriting their previous values.
262 *
263 * @param lines lines to be transformed and overwritten.
264 * @throws AlgebraException raised if transform cannot be computed because
265 * of numerical instabilities.
266 */
267 public void transformAndOverwriteLines(final List<Line2D> lines) throws AlgebraException {
268 for (final var line : lines) {
269 transform(line, line);
270 }
271 }
272
273 /**
274 * Transforms provided polygon using this transformation and returns a new
275 * one.
276 *
277 * @param inputPolygon polygon to be transformed.
278 * @return Transformed polygon.
279 */
280 public Polygon2D transformAndReturnNew(final Polygon2D inputPolygon) {
281 final var outVertices = transformPointsAndReturnNew(inputPolygon.getVertices());
282 try {
283 return new Polygon2D(outVertices);
284 } catch (final NotEnoughVerticesException ignore) {
285 // this will never happen because all existing polygons have enough
286 // vertices
287 return null;
288 }
289 }
290
291 /**
292 * Transforms and updates provided polygon using this transformation.
293 *
294 * @param polygon polygon to be transformed.
295 */
296 public void transform(final Polygon2D polygon) {
297 transformAndOverwritePoints(polygon.getVertices());
298 }
299
300 /**
301 * Transforms provided input polygon using this transformation and stores
302 * the result into provided output polygon instance.
303 *
304 * @param inputPolygon polygon to be transformed.
305 * @param outputPolygon instance where transformed polygon data will be
306 * stored.
307 */
308 public void transform(final Polygon2D inputPolygon, final Polygon2D outputPolygon) {
309 try {
310 outputPolygon.setVertices(transformPointsAndReturnNew(inputPolygon.getVertices()));
311 } catch (final NotEnoughVerticesException ignore) {
312 // this will never happen because all existing polygons have enough
313 // vertices
314 }
315 }
316
317 /**
318 * Transforms provided triangle using this transformation and returns a new
319 * one.
320 *
321 * @param inputTriangle triangle to be transformed.
322 * @return transformed triangle.
323 */
324 public Triangle2D transformAndReturnNew(final Triangle2D inputTriangle) {
325 final var vertex1 = Transformation2D.this.transformAndReturnNew(inputTriangle.getVertex1());
326 final var vertex2 = Transformation2D.this.transformAndReturnNew(inputTriangle.getVertex2());
327 final var vertex3 = Transformation2D.this.transformAndReturnNew(inputTriangle.getVertex3());
328 return new Triangle2D(vertex1, vertex2, vertex3);
329 }
330
331 /**
332 * Transforms and updates provided input triangle using this transformation.
333 *
334 * @param triangle triangle to be transformed.
335 */
336 public void transform(final Triangle2D triangle) {
337 transform(triangle, triangle);
338 }
339
340 /**
341 * Transforms provided input triangle using this transformation and stores
342 * the result into provided output triangle instance.
343 *
344 * @param inputTriangle triangle to be transformed.
345 * @param outputTriangle instance where transformed triangle data will be
346 * stored
347 */
348 public void transform(final Triangle2D inputTriangle, final Triangle2D outputTriangle) {
349 outputTriangle.setVertex1(transformAndReturnNew(inputTriangle.getVertex1()));
350 outputTriangle.setVertex2(transformAndReturnNew(inputTriangle.getVertex2()));
351 outputTriangle.setVertex3(transformAndReturnNew(inputTriangle.getVertex3()));
352 }
353
354 /**
355 * Represents this transformation as a 3x3 matrix.
356 * A point can be transformed as T * p, where T is the transformation matrix
357 * and p is a point expressed as an homogeneous vector.
358 *
359 * @return This transformation in matrix form.
360 */
361 public abstract Matrix asMatrix();
362
363 /**
364 * Represents this transformation as a 3x3 matrix and stores the result in
365 * provided instance.
366 *
367 * @param m Instance where transformation matrix will be stored.
368 * @throws IllegalArgumentException Raised if provided instance is not a 3x3
369 * matrix.
370 */
371 public abstract void asMatrix(final Matrix m);
372 }