/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
******************************************************************************/
package com.badlogic.gdx.math;
import java.io.Serializable;
/**
* A plane defined via a unit length normal and the distance from the origin, as you learned in your math class.
*
* @author badlogicgames@gmail.com
*/
public class Plane implements Serializable {
private static final long serialVersionUID = -1240652082930747866L;
/**
* Enum specifying on which side a point lies respective to the plane and it's normal. {@link PlaneSide#Front} is
* the side to which the normal points.
*
* @author mzechner
*/
public enum PlaneSide {
OnPlane, Back, Front
}
public final Vector3 normal = new Vector3();
public float d = 0;
/**
* Constructs a new plane based on the normal and distance to the origin.
*
* @param normal
* The plane normal
* @param d
* The distance to the origin
*/
public Plane(Vector3 normal, float d) {
this.normal.set(normal).nor();
this.d = d;
}
/**
* Constructs a new plane based on the normal and a point on the plane.
*
* @param normal
* The normal
* @param point
* The point on the plane
*/
public Plane(Vector3 normal, Vector3 point) {
this.normal.set(normal).nor();
this.d = -this.normal.dot(point);
}
/**
* Constructs a new plane out of the three given points that are considered to be on the plane. The normal is
* calculated via a cross product between (point1-point2)x(point2-point3)
*
* @param point1
* The first point
* @param point2
* The second point
* @param point3
* The third point
*/
public Plane(Vector3 point1, Vector3 point2, Vector3 point3) {
set(point1, point2, point3);
}
/**
* Sets the plane normal and distance to the origin based on the three given points which are considered to be on
* the plane. The normal is calculated via a cross product between (point1-point2)x(point2-point3)
*
* @param point1
* @param point2
* @param point3
*/
public void set(Vector3 point1, Vector3 point2, Vector3 point3) {
Vector3 l = point1.tmp().sub(point2);
Vector3 r = point2.tmp2().sub(point3);
Vector3 nor = l.crs(r).nor();
normal.set(nor);
d = -point1.dot(nor);
}
/**
* Sets the plane normal and distance
*
* @param nx
* normal x-component
* @param ny
* normal y-component
* @param nz
* normal z-component
* @param d
* distance to origin
*/
public void set(float nx, float ny, float nz, float d) {
normal.set(nx, ny, nz);
this.d = d;
}
/**
* Calculates the shortest signed distance between the plane and the given point.
*
* @param point
* The point
* @return the shortest signed distance between the plane and the point
*/
public float distance(Vector3 point) {
return normal.dot(point) + d;
}
/**
* Returns on which side the given point lies relative to the plane and its normal. PlaneSide.Front refers to the
* side the plane normal points to.
*
* @param point
* The point
* @return The side the point lies relative to the plane
*/
public PlaneSide testPoint(Vector3 point) {
float dist = normal.dot(point) + d;
if (dist == 0)
return PlaneSide.OnPlane;
else if (dist < 0)
return PlaneSide.Back;
else
return PlaneSide.Front;
}
/**
* Returns on which side the given point lies relative to the plane and its normal. PlaneSide.Front refers to the
* side the plane normal points to.
*
* @param x
* @param y
* @param z
* @return The side the point lies relative to the plane
*/
public PlaneSide testPoint(float x, float y, float z) {
float dist = normal.dot(x, y, z) + d;
if (dist == 0)
return PlaneSide.OnPlane;
else if (dist < 0)
return PlaneSide.Back;
else
return PlaneSide.Front;
}
/**
* Returns whether the plane is facing the direction vector. Think of the direction vector as the direction a camera
* looks in. This method will return true if the front side of the plane determined by its normal faces the camera.
*
* @param direction
* the direction
* @return whether the plane is front facing
*/
public boolean isFrontFacing(Vector3 direction) {
float dot = normal.dot(direction);
return dot <= 0;
}
/** @return The normal */
public Vector3 getNormal() {
return normal;
}
/** @return The distance to the origin */
public float getD() {
return d;
}
/**
* Sets the plane to the given point and normal.
*
* @param point
* the point on the plane
* @param normal
* the normal of the plane
*/
public void set(Vector3 point, Vector3 normal) {
this.normal.set(normal);
d = -point.dot(normal);
}
public void set(float pointX, float pointY, float pointZ, float norX, float norY, float norZ) {
this.normal.set(norX, norY, norZ);
d = -(pointX * norX + pointY * norY + pointZ * norZ);
}
/**
* Sets this plane from the given plane
*
* @param plane
* the plane
*/
public void set(Plane plane) {
this.normal.set(plane.normal);
this.d = plane.d;
}
public String toString() {
return normal.toString() + ", " + d;
}
}