1
2
3
4
5 package math.geom3d.plane;
6
7 import math.geom2d.Point2D;
8 import math.geom3d.Box3D;
9 import math.geom3d.Point3D;
10 import math.geom3d.Shape3D;
11 import math.geom3d.Vector3D;
12 import math.geom3d.line.StraightLine3D;
13 import math.geom3d.transform.AffineTransform3D;
14
15
16
17
18 public class Plane3D implements Shape3D {
19
20
21
22
23 protected double x0 = 0;
24 protected double y0 = 0;
25 protected double z0 = 0;
26 protected double dx1 = 1;
27 protected double dy1 = 0;
28 protected double dz1 = 0;
29 protected double dx2 = 0;
30 protected double dy2 = 1;
31 protected double dz2 = 0;
32
33
34
35
36 public final static Plane3D createXYPlane() {
37 return new Plane3D(new Point3D(0, 0, 0), new Vector3D(1, 0, 0),
38 new Vector3D(0, 1, 0));
39 }
40
41 public final static Plane3D createXZPlane() {
42 return new Plane3D(new Point3D(0, 0, 0), new Vector3D(1, 0, 0),
43 new Vector3D(0, 0, 1));
44 }
45
46 public final static Plane3D createYZPlane() {
47 return new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 1, 0),
48 new Vector3D(0, 0, 1));
49 }
50
51
52
53
54 public Plane3D() {
55 }
56
57 public Plane3D(Point3D point, Vector3D vector1, Vector3D vector2) {
58 this.x0 = point.getX();
59 this.y0 = point.getY();
60 this.z0 = point.getZ();
61 this.dx1 = vector1.getX();
62 this.dy1 = vector1.getY();
63 this.dz1 = vector1.getZ();
64 this.dx2 = vector2.getX();
65 this.dy2 = vector2.getY();
66 this.dz2 = vector2.getZ();
67 }
68
69
70
71
72 public Point3D getOrigin() {
73 return new Point3D(x0, y0, z0);
74 }
75
76 public Vector3D getVector1() {
77 return new Vector3D(dx1, dy1, dz1);
78 }
79
80 public Vector3D getVector2() {
81 return new Vector3D(dx2, dy2, dz2);
82 }
83
84
85
86
87
88
89 public Vector3D getNormalVector() {
90 return Vector3D.crossProduct(this.getVector1(), this.getVector2())
91 .getOpposite();
92 }
93
94
95
96
97
98
99
100
101
102 public Point3D getLineIntersection(StraightLine3D line) {
103
104 Vector3D n = this.getNormalVector();
105
106
107 Vector3D dp = new Vector3D(line.getOrigin(), this.getOrigin());
108
109
110
111 double t = Vector3D.dotProduct(n, dp)
112 /Vector3D.dotProduct(n, line.getDirection());
113
114 return line.getPoint(t);
115 }
116
117 public Point3D projectPoint(Point3D point) {
118 StraightLine3D line = new StraightLine3D(point, this.getNormalVector());
119 return this.getLineIntersection(line);
120 }
121
122 public Vector3D projectVector(Vector3D vect) {
123 Point3D point = new Point3D(x0+vect.getX(), y0+vect.getY(), z0
124 +vect.getZ());
125 point = this.projectPoint(point);
126 return new Vector3D(point.getX()-x0, point.getY()-y0, point.getZ()-z0);
127 }
128
129 public Point3D getPoint(double u, double v) {
130 return new Point3D(x0+u*dx1+v*dx2, y0+u*dy1+v*dy2, z0+u*dz1+v*dz2);
131 }
132
133 public Point2D getPointPosition(Point3D point) {
134 point = this.projectPoint(point);
135 throw new UnsupportedOperationException();
136 }
137
138
139
140
141
142
143
144
145
146 public Shape3D clip(Box3D box) {
147
148 throw new UnsupportedOperationException();
149 }
150
151
152
153
154
155
156 public boolean contains(Point3D point) {
157 Point3D proj = this.projectPoint(point);
158 return (point.getDistance(proj)<Shape3D.ACCURACY);
159 }
160
161
162
163
164
165
166 public Box3D getBoundingBox() {
167
168 if (Math.abs(dz1)<Shape3D.ACCURACY&&Math.abs(dz2)<Shape3D.ACCURACY)
169 return new Box3D(Double.NEGATIVE_INFINITY,
170 Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY,
171 Double.POSITIVE_INFINITY, z0, z0);
172
173
174 if (Math.abs(dx1)<Shape3D.ACCURACY&&Math.abs(dx2)<Shape3D.ACCURACY)
175 return new Box3D(x0, x0, Double.NEGATIVE_INFINITY,
176 Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY,
177 Double.POSITIVE_INFINITY);
178
179
180 if (Math.abs(dy1)<Shape3D.ACCURACY&&Math.abs(dy2)<Shape3D.ACCURACY)
181 return new Box3D(Double.NEGATIVE_INFINITY,
182 Double.POSITIVE_INFINITY, y0, y0, Double.NEGATIVE_INFINITY,
183 Double.POSITIVE_INFINITY);
184
185 return new Box3D(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
186 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
187 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
188 }
189
190
191
192
193
194
195 public double getDistance(Point3D point) {
196 return point.getDistance(this.projectPoint(point));
197 }
198
199
200
201
202
203
204 public boolean isBounded() {
205 return false;
206 }
207
208
209
210
211
212
213 public boolean isEmpty() {
214 return false;
215 }
216
217
218
219
220
221
222 public Shape3D transform(AffineTransform3D trans) {
223 return new Plane3D(this.getOrigin().transform(trans), this.getVector1()
224 .transform(trans), this.getVector2().transform(trans));
225 }
226
227
228
229
230 @Override
231 public boolean equals(Object obj) {
232 if (!(obj instanceof Plane3D))
233 return false;
234 Plane3D plane = (Plane3D) obj;
235
236 if (Math.abs(this.x0-plane.x0)>Shape3D.ACCURACY)
237 return false;
238 if (Math.abs(this.y0-plane.y0)>Shape3D.ACCURACY)
239 return false;
240 if (Math.abs(this.z0-plane.z0)>Shape3D.ACCURACY)
241 return false;
242 if (Math.abs(this.dx1-plane.dx1)>Shape3D.ACCURACY)
243 return false;
244 if (Math.abs(this.dy1-plane.dy1)>Shape3D.ACCURACY)
245 return false;
246 if (Math.abs(this.dz1-plane.dz1)>Shape3D.ACCURACY)
247 return false;
248 if (Math.abs(this.dx2-plane.dx2)>Shape3D.ACCURACY)
249 return false;
250 if (Math.abs(this.dy2-plane.dy2)>Shape3D.ACCURACY)
251 return false;
252 if (Math.abs(this.dz2-plane.dz2)>Shape3D.ACCURACY)
253 return false;
254 return true;
255 }
256
257 }