2009-04-19 18:07:22 +00:00
#region = = = = = = = = = = = = = = = = = = Copyright ( c ) 2007 Pascal vd Heiden
/ *
* Copyright ( c ) 2007 Pascal vd Heiden , www . codeimp . com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* /
#endregion
#region = = = = = = = = = = = = = = = = = = Namespaces
2014-10-17 11:55:08 +00:00
using System ;
2009-04-19 18:07:22 +00:00
#endregion
namespace CodeImp.DoomBuilder.Geometry
{
public struct Plane
{
#region = = = = = = = = = = = = = = = = = = Constants
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
//
// Plane definition:
// A * x + B * y + C * z + D = 0
//
// A, B, C is the normal
// D is the offset along the normal (negative)
//
private Vector3D normal ;
2020-05-18 16:14:54 +00:00
private double offset ;
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Properties
public Vector3D Normal { get { return normal ; } }
2020-05-18 16:14:54 +00:00
public double Offset { get { return offset ; } set { offset = value ; } }
public double a { get { return normal . x ; } }
public double b { get { return normal . y ; } }
public double c { get { return normal . z ; } }
public double d { get { return offset ; } set { offset = value ; } }
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Constructors
2009-05-21 08:18:34 +00:00
/// <summary></summary>
2020-05-18 16:14:54 +00:00
public Plane ( Vector3D normal , double offset )
2009-04-19 18:07:22 +00:00
{
#if DEBUG
if ( ! normal . IsNormalized ( ) )
2014-10-17 11:55:08 +00:00
throw new NotSupportedException ( "Attempt to create a plane with a vector that is not normalized!" ) ; // General.Fail("Attempt to create a plane with a vector that is not normalized!");
2009-04-19 18:07:22 +00:00
#endif
this . normal = normal ;
this . offset = offset ;
}
2009-05-21 08:18:34 +00:00
/// <summary></summary>
2009-04-19 18:07:22 +00:00
public Plane ( Vector3D normal , Vector3D position )
{
#if DEBUG
if ( ! normal . IsNormalized ( ) )
2014-10-17 11:55:08 +00:00
throw new NotSupportedException ( "Attempt to create a plane with a vector that is not normalized!" ) ; //General.Fail("Attempt to create a plane with a vector that is not normalized!");
2009-04-19 18:07:22 +00:00
#endif
this . normal = normal ;
this . offset = - Vector3D . DotProduct ( normal , position ) ;
}
2009-05-21 08:18:34 +00:00
/// <summary></summary>
2010-09-04 11:19:37 +00:00
public Plane ( Vector3D p1 , Vector3D p2 , Vector3D p3 , bool up )
2009-04-19 18:07:22 +00:00
{
2010-09-08 20:39:59 +00:00
this . normal = Vector3D . CrossProduct ( p2 - p1 , p3 - p1 ) . GetNormal ( ) ;
2010-09-08 15:05:32 +00:00
2010-09-04 11:19:37 +00:00
if ( ( up & & ( this . normal . z < 0.0f ) ) | | ( ! up & & ( this . normal . z > 0.0f ) ) )
2010-09-08 20:39:59 +00:00
this . normal = - this . normal ;
this . offset = - Vector3D . DotProduct ( normal , p3 ) ;
2009-04-19 18:07:22 +00:00
}
2014-10-17 11:55:08 +00:00
/// <summary></summary>
2020-05-18 16:14:54 +00:00
public Plane ( Vector3D center , double anglexy , double anglez , bool up ) //mxd
2014-10-17 11:55:08 +00:00
{
2020-05-18 16:14:54 +00:00
Vector2D point = new Vector2D ( center . x + Math . Cos ( anglexy ) * Math . Sin ( anglez ) , center . y + Math . Sin ( anglexy ) * Math . Sin ( anglez ) ) ;
2014-10-17 11:55:08 +00:00
Vector2D perpendicular = new Line2D ( center , point ) . GetPerpendicular ( ) ;
2020-05-18 16:14:54 +00:00
Vector3D p2 = new Vector3D ( point . x + perpendicular . x , point . y + perpendicular . y , center . z + Math . Cos ( anglez ) ) ;
Vector3D p3 = new Vector3D ( point . x - perpendicular . x , point . y - perpendicular . y , center . z + Math . Cos ( anglez ) ) ;
2014-10-17 11:55:08 +00:00
this . normal = Vector3D . CrossProduct ( p2 - center , p3 - center ) . GetNormal ( ) ;
if ( ( up & & ( this . normal . z < 0.0f ) ) | | ( ! up & & ( this . normal . z > 0.0f ) ) )
this . normal = - this . normal ;
this . offset = - Vector3D . DotProduct ( normal , p3 ) ;
}
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Methods
2009-05-21 08:18:34 +00:00
/// <summary>
2010-09-08 20:39:59 +00:00
/// This tests for intersection with a line.
/// See http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/
2009-05-21 08:18:34 +00:00
/// </summary>
2020-05-18 16:14:54 +00:00
public bool GetIntersection ( Vector3D from , Vector3D to , ref double u_ray )
2009-04-19 18:07:22 +00:00
{
2020-05-18 16:14:54 +00:00
double w = Vector3D . DotProduct ( normal , from - to ) ;
2010-09-04 11:19:37 +00:00
if ( w ! = 0.0f )
2009-04-19 18:07:22 +00:00
{
2020-05-18 16:14:54 +00:00
double v = Vector3D . DotProduct ( normal , from ) ;
2010-09-08 20:39:59 +00:00
u_ray = ( offset + v ) / w ;
2009-04-19 18:07:22 +00:00
return true ;
}
else
{
return false ;
}
}
2009-05-21 08:18:34 +00:00
/// <summary>
/// This returns the smallest distance to the plane and the side on which the point lies.
2013-03-18 13:52:27 +00:00
/// Greater than 0 means the point lies on the front of the plane
/// Less than 0 means the point lies behind the plane
2010-09-08 20:39:59 +00:00
/// See http://mathworld.wolfram.com/Point-PlaneDistance.html
2009-05-21 08:18:34 +00:00
/// </summary>
2020-05-18 16:14:54 +00:00
public double Distance ( Vector3D p )
2009-04-19 18:07:22 +00:00
{
2010-09-08 20:39:59 +00:00
return Vector3D . DotProduct ( normal , p ) + offset ;
2009-04-19 18:07:22 +00:00
}
2009-05-21 08:18:34 +00:00
/// <summary>
/// This returns a point on the plane closest to the given point
/// </summary>
2009-04-19 18:07:22 +00:00
public Vector3D ClosestOnPlane ( Vector3D p )
{
2016-04-25 14:48:39 +00:00
return p - normal * this . Distance ( p ) ;
2009-04-19 18:07:22 +00:00
}
2010-09-04 11:19:37 +00:00
/// <summary>
/// This returns Z on the plane at X, Y
/// </summary>
2020-05-18 16:14:54 +00:00
public double GetZ ( Vector2D pos )
2010-09-04 11:19:37 +00:00
{
2010-09-08 20:39:59 +00:00
return ( - offset - Vector2D . DotProduct ( normal , pos ) ) / normal . z ;
2010-09-04 11:19:37 +00:00
}
/// <summary>
/// This returns Z on the plane at X, Y
/// </summary>
2020-05-18 16:14:54 +00:00
public double GetZ ( double x , double y )
2010-09-04 11:19:37 +00:00
{
2010-09-08 20:39:59 +00:00
return ( - offset - ( normal . x * x + normal . y * y ) ) / normal . z ;
2010-09-04 11:19:37 +00:00
}
2009-05-21 08:18:34 +00:00
/// <summary>
/// This inverts the plane
/// </summary>
2009-04-19 18:07:22 +00:00
public Plane GetInverted ( )
{
return new Plane ( - normal , - offset ) ;
}
2016-04-25 14:48:39 +00:00
//mxd. Addeed to make compiler a bit more happy...
public override int GetHashCode ( )
{
return base . GetHashCode ( ) ;
}
//mxd. Addeed to make compiler a bit more happy...
public override bool Equals ( object obj )
{
if ( ! ( obj is Plane ) ) return false ;
Plane other = ( Plane ) obj ;
return ( normal ! = other . normal ) | | ( offset ! = other . offset ) ;
}
2009-04-19 18:07:22 +00:00
#endregion
2016-04-22 13:28:23 +00:00
#region = = = = = = = = = = = = = = = = = = Statics ( mxd )
// This compares a vector
public static bool operator = = ( Plane a , Plane b )
{
return ( a . normal = = b . normal ) & & ( a . offset = = b . offset ) ;
}
// This compares a vector
public static bool operator ! = ( Plane a , Plane b )
{
return ( a . normal ! = b . normal ) | | ( a . offset ! = b . offset ) ;
}
#endregion
2009-04-19 18:07:22 +00:00
}
}