1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
37
38 public class SubPlane extends AbstractSubHyperplane<Euclidean3D, Euclidean2D> {
39
40
41
42
43
44 public SubPlane(final Hyperplane<Euclidean3D> hyperplane,
45 final Region<Euclidean2D> remainingRegion) {
46 super(hyperplane, remainingRegion);
47 }
48
49
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
57
58
59
60
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
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
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 }