Class Plane3D

 1 /*
 2  * Copyright (c) 2016 Martin Davis.
 3  *
 4  * All rights reserved. This program and the accompanying materials
 5  * are made available under the terms of the Eclipse Public License 2.0
 6  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
 7  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
 8  * and the Eclipse Distribution License is available at
 9  *
10  * http://www.eclipse.org/org/documents/edl-v10.php.
11  */
12  
13 package org.locationtech.jts.math;
14  
15 import org.locationtech.jts.geom.Coordinate;
16  
17 /**
18  * Models a plane in 3-dimensional Cartesian space.
19  * 
20  * @author mdavis
21  *
22  */
23 public class Plane3D {
24     
25     /**
26      * Enums for the 3 coordinate planes
27      */
28     public static final int XY_PLANE = 1;
29     public static final int YZ_PLANE = 2;
30     public static final int XZ_PLANE = 3;
31     
32     private Vector3D normal;
33     private Coordinate basePt;
34  
35     public Plane3D(Vector3D normal, Coordinate basePt)
36     {
37         this.normal = normal;
38         this.basePt = basePt;
39     }
40     
41     /**
42      * Computes the oriented distance from a point to the plane.
43      * The distance is:
44      * <ul>
45      * <li><b>positive</b> if the point lies above the plane (relative to the plane normal)
46      * <li><b>zero</b> if the point is on the plane
47      * <li><b>negative</b> if the point lies below the plane (relative to the plane normal)
48      * </ul> 
49      * 
50      * @param p the point to compute the distance for
51      * @return the oriented distance to the plane
52      */
53     public double orientedDistance(Coordinate p) {
54         Vector3D pb = new Vector3D(p, basePt);
55         double pbdDotNormal = pb.dot(normal);
56         if (Double.isNaN(pbdDotNormal)) 
57             throw new IllegalArgumentException("3D Coordinate has NaN ordinate");
58         double d = pbdDotNormal / normal.length();
59         return d;
60     }
61  
62     /**
63      * Computes the axis plane that this plane lies closest to.
64      * <p>
65      * Geometries lying in this plane undergo least distortion
66      * (and have maximum area)
67      * when projected to the closest axis plane.
68      * This provides optimal conditioning for
69      * computing a Point-in-Polygon test.
70      *  
71      * @return the index of the closest axis plane.
72      */
73     public int closestAxisPlane() {
74         double xmag = Math.abs(normal.getX());
75         double ymag = Math.abs(normal.getY());
76         double zmag = Math.abs(normal.getZ());
77         if (xmag > ymag) {
78             if (xmag > zmag)
79                 return YZ_PLANE;
80             else
81                 return XY_PLANE;
82         }
83         // y >= x
84         else if (zmag > ymag) {
85             return XY_PLANE;
86         }
87         // y >= z
88         return XZ_PLANE;
89     }
90  
91 }
92