View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.geometry.euclidean.threed;
18  
19  import java.util.List;
20  
21  import org.apache.commons.geometry.core.Transform;
22  import org.apache.commons.geometry.core.partitioning.Hyperplane;
23  import org.apache.commons.geometry.core.partitioning.Split;
24  import org.apache.commons.geometry.euclidean.twod.AffineTransformMatrix2D;
25  import org.apache.commons.geometry.euclidean.twod.ConvexArea;
26  import org.apache.commons.geometry.euclidean.twod.Vector2D;
27  
28  /** Internal implementation of {@link PlaneConvexSubset} that uses an embedded
29   * {@link ConvexArea} to represent the subspace region. This class is capable of
30   * representing regions of infinite size.
31   */
32  final class EmbeddedAreaPlaneConvexSubset extends AbstractEmbeddedRegionPlaneSubset
33      implements PlaneConvexSubset, PlaneConvexSubset.Embedded {
34  
35      /** The embedded 2D area. */
36      private final ConvexArea area;
37  
38      /** Create a new instance from its component parts.
39       * @param plane plane the the convex area is embedded in
40       * @param area the embedded convex area
41       */
42      EmbeddedAreaPlaneConvexSubset(final EmbeddingPlane plane, final ConvexArea area) {
43          super(plane);
44  
45          this.area = area;
46      }
47  
48      /** {@inheritDoc} */
49      @Override
50      public PlaneConvexSubset.Embedded getEmbedded() {
51          return this;
52      }
53  
54      /** {@inheritDoc} */
55      @Override
56      public ConvexArea getSubspaceRegion() {
57          return area;
58      }
59  
60      /** {@inheritDoc} */
61      @Override
62      public List<Vector3D> getVertices() {
63          return getPlane().toSpace(area.getVertices());
64      }
65  
66      /** {@inheritDoc} */
67      @Override
68      public Bounds3D getBounds() {
69          return getBoundsFromSubspace(area);
70      }
71  
72      /** {@inheritDoc} */
73      @Override
74      public List<Triangle3D> toTriangles() {
75          if (isInfinite()) {
76              throw new IllegalStateException("Cannot convert infinite plane subset to triangles: " + this);
77          }
78  
79          final EmbeddingPlane plane = getPlane();
80          final List<Vector3D> vertices = plane.toSpace(area.getVertices());
81  
82          return Planes.convexPolygonToTriangleFan(plane, vertices);
83      }
84  
85      /** {@inheritDoc} */
86      @Override
87      public EmbeddedAreaPlaneConvexSubset transform(final Transform<Vector3D> transform) {
88          final EmbeddingPlane.SubspaceTransform st = getPlane().subspaceTransform(transform);
89          final ConvexArea tArea = area.transform(st.getTransform());
90  
91          return new EmbeddedAreaPlaneConvexSubset(st.getPlane().getEmbedding(), tArea);
92      }
93  
94      /** {@inheritDoc} */
95      @Override
96      public EmbeddedAreaPlaneConvexSubset reverse() {
97          final EmbeddingPlane plane = getPlane();
98          final EmbeddingPlane rPlane = plane.reverse();
99  
100         final Vector2D rU = rPlane.toSubspace(plane.toSpace(Vector2D.Unit.PLUS_X));
101         final Vector2D rV = rPlane.toSubspace(plane.toSpace(Vector2D.Unit.PLUS_Y));
102 
103         final AffineTransformMatrix2D transform =
104                 AffineTransformMatrix2D.fromColumnVectors(rU, rV);
105 
106         return new EmbeddedAreaPlaneConvexSubset(rPlane, area.transform(transform));
107     }
108 
109     /** {@inheritDoc} */
110     @Override
111     public Split<PlaneConvexSubset> split(final Hyperplane<Vector3D> splitter) {
112         // delegate back to the Planes factory method so that it has a chance to decide
113         // on the best possible implementation for the given area
114         return Planes.subspaceSplit((Plane) splitter, this,
115             (p, r) -> Planes.subsetFromConvexArea(p, (ConvexArea) r));
116     }
117 }