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    *      https://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  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.geometry.euclidean.threed;
23  
24  import org.hipparchus.geometry.Point;
25  import org.hipparchus.geometry.euclidean.oned.Euclidean1D;
26  import org.hipparchus.geometry.euclidean.oned.Vector1D;
27  import org.hipparchus.geometry.euclidean.twod.Euclidean2D;
28  import org.hipparchus.geometry.euclidean.twod.PolygonsSet;
29  import org.hipparchus.geometry.euclidean.twod.Vector2D;
30  import org.hipparchus.geometry.partitioning.AbstractSubHyperplane;
31  import org.hipparchus.geometry.partitioning.BSPTree;
32  import org.hipparchus.geometry.partitioning.Hyperplane;
33  import org.hipparchus.geometry.partitioning.Region;
34  import org.hipparchus.geometry.partitioning.SubHyperplane;
35  
36  /** This class represents a sub-hyperplane for {@link Plane}.
37   */
38  public class SubPlane extends AbstractSubHyperplane<Euclidean3D, Euclidean2D> {
39  
40      /** Simple constructor.
41       * @param hyperplane underlying hyperplane
42       * @param remainingRegion remaining region of the hyperplane
43       */
44      public SubPlane(final Hyperplane<Euclidean3D> hyperplane,
45                      final Region<Euclidean2D> remainingRegion) {
46          super(hyperplane, remainingRegion);
47      }
48  
49      /** {@inheritDoc} */
50      @Override
51      protected AbstractSubHyperplane<Euclidean3D, Euclidean2D> buildNew(final Hyperplane<Euclidean3D> hyperplane,
52                                                                         final Region<Euclidean2D> remainingRegion) {
53          return new SubPlane(hyperplane, remainingRegion);
54      }
55  
56      /** Split the instance in two parts by an hyperplane.
57       * @param hyperplane splitting hyperplane
58       * @return an object containing both the part of the instance
59       * on the plus side of the instance and the part of the
60       * instance on the minus side of the instance
61       */
62      @Override
63      public SplitSubHyperplane<Euclidean3D> split(Hyperplane<Euclidean3D> hyperplane) {
64  
65          final Plane otherPlane = (Plane) hyperplane;
66          final Plane thisPlane  = (Plane) getHyperplane();
67          final Line  inter      = otherPlane.intersection(thisPlane);
68          final double tolerance = thisPlane.getTolerance();
69  
70          if (inter == null) {
71              // the hyperplanes are parallel
72              final double global = otherPlane.getOffset(thisPlane);
73              if (global < -tolerance) {
74                  return new SplitSubHyperplane<Euclidean3D>(null, this);
75              } else if (global > tolerance) {
76                  return new SplitSubHyperplane<Euclidean3D>(this, null);
77              } else {
78                  return new SplitSubHyperplane<Euclidean3D>(null, null);
79              }
80          }
81  
82          // the hyperplanes do intersect
83          Vector2D p = thisPlane.toSubSpace((Point<Euclidean3D>) inter.toSpace((Point<Euclidean1D>) Vector1D.ZERO));
84          Vector2D q = thisPlane.toSubSpace((Point<Euclidean3D>) inter.toSpace((Point<Euclidean1D>) Vector1D.ONE));
85          Vector3D crossP = Vector3D.crossProduct(inter.getDirection(), thisPlane.getNormal());
86          if (crossP.dotProduct(otherPlane.getNormal()) < 0) {
87              final Vector2D tmp = p;
88              p           = q;
89              q           = tmp;
90          }
91          final SubHyperplane<Euclidean2D> l2DMinus =
92              new org.hipparchus.geometry.euclidean.twod.Line(p, q, tolerance).wholeHyperplane();
93          final SubHyperplane<Euclidean2D> l2DPlus =
94              new org.hipparchus.geometry.euclidean.twod.Line(q, p, tolerance).wholeHyperplane();
95  
96          final BSPTree<Euclidean2D> splitTree = getRemainingRegion().getTree(false).split(l2DMinus);
97          final BSPTree<Euclidean2D> plusTree  = getRemainingRegion().isEmpty(splitTree.getPlus()) ?
98                                                 new BSPTree<>(Boolean.FALSE) :
99                                                 new BSPTree<>(l2DPlus, new BSPTree<>(Boolean.FALSE),
100                                                              splitTree.getPlus(), null);
101 
102         final BSPTree<Euclidean2D> minusTree = getRemainingRegion().isEmpty(splitTree.getMinus()) ?
103                                                new BSPTree<>(Boolean.FALSE) :
104                                                new BSPTree<>(l2DMinus, new BSPTree<>(Boolean.FALSE),
105                                                                             splitTree.getMinus(), null);
106 
107         return new SplitSubHyperplane<>(new SubPlane(thisPlane.copySelf(), new PolygonsSet(plusTree, tolerance)),
108                                         new SubPlane(thisPlane.copySelf(), new PolygonsSet(minusTree, tolerance)));
109 
110     }
111 
112 }