package MapEditor;

import javax.vecmath.*;

public class Plane
{
	// Plane Equation: m_normal . (x,y,z) - d = 0
	// Datatype Invariant: |m_normal| = 1
	private Vector3d m_normal;
	private double m_d;

	public Plane(Vector3d normal, double d)
	{
		m_normal = normal;
		m_d = d;

		// Establish the datatype invariant.
		double length = normal.length();
		m_normal.scale(1/length);
		m_d /= length;
	}

	/**
	Returns the (perpendicular) displacement from the plane to the specified point.
	The result is signed, being positive when the point is in front of the plane
	and negative when it is behind the plane. (Obviously when it's on the plane,
	it's zero).

	@param p	The point whose displacement from the plane we want to determine
	@return		The (perpendicular) displacement from the plane to the point
	*/
	public double displacement_to_point(final Point3d p)
	{
		// Note: We have a unit normal, so we don't need to normalise this.
		return m_normal.dot(new Vector3d(p)) - m_d;
	}

	/**
	Reflects the specified point across the plane.

	@param p	The point to reflect
	*/
	public void reflect_point(Point3d p)
	{
		double disp = displacement_to_point(p);

		Vector3d scaledNormal = (Vector3d)m_normal.clone();
		scaledNormal.scale(-2*disp);

		// Now |scaledNormal| = 2*disp, since |m_normal| = 1. It points towards the plane, so
		// adding it to our original point will reflect the latter across the plane.
		p.add(scaledNormal);
	}
}
