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 Plane3D(Vector3D normal, Coordinate basePt)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 */ orientedDistance(Coordinate p)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 */ closestAxisPlane()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