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.euclidean.oned.Vector1D;
25 import org.hipparchus.geometry.euclidean.twod.Euclidean2D;
26 import org.hipparchus.geometry.euclidean.twod.PolygonsSet;
27 import org.hipparchus.geometry.euclidean.twod.SubLine;
28 import org.hipparchus.geometry.euclidean.twod.Vector2D;
29 import org.hipparchus.geometry.partitioning.AbstractSubHyperplane;
30 import org.hipparchus.geometry.partitioning.BSPTree;
31 import org.hipparchus.geometry.partitioning.Region;
32
33
34
35 public class SubPlane extends AbstractSubHyperplane<Euclidean3D, Vector3D, Plane, SubPlane,
36 Euclidean2D, Vector2D, org.hipparchus.geometry.euclidean.twod.Line, SubLine> {
37
38
39
40
41
42 public SubPlane(final Plane hyperplane,
43 final Region<Euclidean2D, Vector2D, org.hipparchus.geometry.euclidean.twod.Line, SubLine> remainingRegion) {
44 super(hyperplane, remainingRegion);
45 }
46
47
48 @Override
49 protected SubPlane buildNew(final Plane hyperplane,
50 final Region<Euclidean2D, Vector2D, org.hipparchus.geometry.euclidean.twod.Line, SubLine> remainingRegion) {
51 return new SubPlane(hyperplane, remainingRegion);
52 }
53
54
55 @Override
56 public Vector3D getInteriorPoint() {
57 return isEmpty() ? null : getHyperplane().toSpace(getRemainingRegion().getInteriorPoint());
58 }
59
60
61
62
63
64
65
66 @Override
67 public SplitSubHyperplane<Euclidean3D, Vector3D, Plane, SubPlane> split(Plane hyperplane) {
68
69 final Line inter = hyperplane.intersection(getHyperplane());
70 final double tolerance = getHyperplane().getTolerance();
71
72 if (inter == null) {
73
74 final double global = hyperplane.getOffset(getHyperplane());
75 if (global < -tolerance) {
76 return new SplitSubHyperplane<>(null, this);
77 } else if (global > tolerance) {
78 return new SplitSubHyperplane<>(this, null);
79 } else {
80 return new SplitSubHyperplane<>(null, null);
81 }
82 }
83
84
85 Vector2D p = getHyperplane().toSubSpace(inter.toSpace(Vector1D.ZERO));
86 Vector2D q = getHyperplane().toSubSpace(inter.toSpace(Vector1D.ONE));
87 Vector3D crossP = Vector3D.crossProduct(inter.getDirection(), getHyperplane().getNormal());
88 if (crossP.dotProduct(hyperplane.getNormal()) < 0) {
89 final Vector2D tmp = p;
90 p = q;
91 q = tmp;
92 }
93 final SubLine l2DMinus = new org.hipparchus.geometry.euclidean.twod.Line(p, q, tolerance).wholeHyperplane();
94 final SubLine l2DPlus = new org.hipparchus.geometry.euclidean.twod.Line(q, p, tolerance).wholeHyperplane();
95
96 final BSPTree<Euclidean2D, Vector2D, org.hipparchus.geometry.euclidean.twod.Line, SubLine> splitTree =
97 getRemainingRegion().getTree(false).split(l2DMinus);
98 final BSPTree<Euclidean2D, Vector2D, org.hipparchus.geometry.euclidean.twod.Line, SubLine> plusTree =
99 getRemainingRegion().isEmpty(splitTree.getPlus()) ?
100 new BSPTree<>(Boolean.FALSE) :
101 new BSPTree<>(l2DPlus, new BSPTree<>(Boolean.FALSE), splitTree.getPlus(), null);
102
103 final BSPTree<Euclidean2D, Vector2D, org.hipparchus.geometry.euclidean.twod.Line, SubLine> minusTree =
104 getRemainingRegion().isEmpty(splitTree.getMinus()) ?
105 new BSPTree<>(Boolean.FALSE) :
106 new BSPTree<>(l2DMinus, new BSPTree<>(Boolean.FALSE), splitTree.getMinus(), null);
107
108 return new SplitSubHyperplane<>(new SubPlane(getHyperplane().copySelf(), new PolygonsSet(plusTree, tolerance)),
109 new SubPlane(getHyperplane().copySelf(), new PolygonsSet(minusTree, tolerance)));
110
111 }
112
113 }