Skip to content

Instantly share code, notes, and snippets.

/Plane.cs Secret

Created June 21, 2011 15:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/786881ad028999a8c623 to your computer and use it in GitHub Desktop.
Save anonymous/786881ad028999a8c623 to your computer and use it in GitHub Desktop.
PlaneIntersectiion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlaneIntersection
{
public struct Plane
{
#region Fields
/// <summary>
/// Direction the plane is facing.
/// </summary>
public Vector3 Normal;
/// <summary>
/// Distance from the origin.
/// </summary>
public float D;
private static readonly Plane nullPlane = new Plane(Vector3.Zero, 0);
public static Plane Null { get { return nullPlane; } }
#endregion Fields
#region Constructors
public Plane(Plane plane)
{
this.Normal = plane.Normal;
this.D = plane.D;
}
/// <summary>
/// Construct a plane through a normal, and a distance to move the plane along the normal.
/// </summary>
/// <param name="normal"></param>
/// <param name="constant"></param>
public Plane(Vector3 normal, float constant)
{
this.Normal = normal;
this.D = -constant;
}
public Plane(Vector3 normal, Vector3 point)
{
this.Normal = normal;
this.D = -normal.Dot(point);
}
/// <summary>
/// Construct a plane from 3 coplanar points.
/// </summary>
/// <param name="point0">First point.</param>
/// <param name="point1">Second point.</param>
/// <param name="point2">Third point.</param>
public Plane(Vector3 point0, Vector3 point1, Vector3 point2)
{
Vector3 edge1 = point1 - point0;
Vector3 edge2 = point2 - point0;
Normal = edge1.Cross(edge2);
Normal.Normalize();
D = -Normal.Dot(point0);
}
#endregion
#region Methods
/// <summary>
/// This is a pseudodistance. The sign of the return value is
/// positive if the point is on the positive side of the plane,
/// negative if the point is on the negative side, and zero if the
/// point is on the plane.
/// The absolute value of the return value is the true distance only
/// when the plane normal is a unit length vector.
/// </summary>
/// <param name="point"></param>
/// <returns></returns>
public float GetDistance(Vector3 point)
{
return Normal.Dot(point) + D;
}
/// <summary>
/// Construct a plane from 3 coplanar points.
/// </summary>
/// <param name="point0">First point.</param>
/// <param name="point1">Second point.</param>
/// <param name="point2">Third point.</param>
public void Redefine(Vector3 point0, Vector3 point1, Vector3 point2)
{
Vector3 edge1 = point1 - point0;
Vector3 edge2 = point2 - point0;
Normal = edge1.Cross(edge2);
Normal.Normalize();
D = -Normal.Dot(point0);
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlaneIntersection
{
class Program
{
static void Main(string[] args)
{
// Define the first plane parameters and create it
Vector3 A = new Vector3();
Vector3 B = new Vector3();
Vector3 C = new Vector3();
Plane p1 = new Plane(A, B, C);
// Define the first plane parameters and create it
Vector3 D = new Vector3();
Vector3 E = new Vector3();
Vector3 F = new Vector3();
Plane p2 = new Plane(D, E, F);
///////////////////////////// Get the parallel to the line of interrsection
Vector3 IntersectionDirection = p1.Normal.Cross(p2.Normal);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlaneIntersection
{
public struct Vector3
{
#region Fields
/// <summary>X component.</summary>
public float x;
/// <summary>Y component.</summary>
public float y;
/// <summary>Z component.</summary>
public float z;
private static readonly Vector3 unitX = new Vector3(1.0f, 0.0f, 0.0f);
private static readonly Vector3 unitY = new Vector3(0.0f, 1.0f, 0.0f);
private static readonly Vector3 unitZ = new Vector3(0.0f, 0.0f, 1.0f);
private static readonly Vector3 zeroVector = new Vector3(0.0f, 0.0f, 0.0f);
private static readonly Vector3 unitVector = new Vector3(1.0f, 1.0f, 1.0f);
#endregion
#region Public properties
public bool IsZero { get { return this.x == 0f && this.y == 0f && this.z == 0f; } }
/// <summary>
/// Gets the length (magnitude) of this Vector3. The Sqrt operation is expensive, so
/// only use this if you need the exact length of the Vector. If vector lengths are only going
/// to be compared, use LengthSquared instead.
/// </summary>
public float Length
{
get
{
return (float)Math.Sqrt( (double)(this.x * this.x + this.y * this.y + this.z * this.z));
}
}
/// <summary>
/// Returns the length (magnitude) of the vector squared.
/// </summary>
public float LengthSquared
{
get
{
return (this.x * this.x + this.y * this.y + this.z * this.z);
}
}
#endregion
#region Static properties
/// <summary>
/// Gets a Vector3 with the X set to 1, and the others set to 0.
/// </summary>
public static Vector3 UnitX
{
get
{
return unitX;
}
}
/// <summary>
/// Gets a Vector3 with the Y set to 1, and the others set to 0.
/// </summary>
public static Vector3 UnitY
{
get
{
return unitY;
}
}
/// <summary>
/// Gets a Vector3 with the Z set to 1, and the others set to 0.
/// </summary>
public static Vector3 UnitZ
{
get
{
return unitZ;
}
}
/// <summary>
/// Gets a Vector3 with all components set to 0.
/// </summary>
public static Vector3 Zero
{
get
{
return zeroVector;
}
}
/// <summary>
/// Gets a Vector3 with all components set to 1.
/// </summary>
public static Vector3 UnitScale
{
get
{
return unitVector;
}
}
#endregion
#region Constructors
/// <summary>
/// Creates a new 3 dimensional Vector.
/// </summary>
public Vector3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
/// <summary>
/// Creates a new 3 dimensional Vector.
/// </summary>
public Vector3(float[] coordinates)
{
if (coordinates.Length != 3)
throw new ArgumentException("The coordinates array must be of length 3 to specify the x, y, and z coordinates.");
this.x = coordinates[0];
this.y = coordinates[1];
this.z = coordinates[2];
}
#endregion
#region Public methods
/// <summary>
/// Performs a Dot Product operation on 2 vectors, which produces the angle between them.
/// </summary>
/// <param name="vector">The vector to perform the Dot Product against.</param>
/// <returns>The angle between the 2 vectors.</returns>
public float Dot(Vector3 vector)
{
return (float)x * vector.x + y * vector.y + z * vector.z;
}
/// <summary>
/// Performs a Cross Product operation on 2 vectors, which returns a vector that is perpendicular
/// to the intersection of the 2 vectors. Useful for finding face normals.
/// </summary>
/// <param name="vector">A vector to perform the Cross Product against.</param>
/// <returns>A new Vector3 perpedicular to the 2 original vectors.</returns>
public Vector3 Cross(Vector3 vector)
{
return new Vector3(
(this.y * vector.z) - (this.z * vector.y),
(this.z * vector.x) - (this.x * vector.z),
(this.x * vector.y) - (this.y * vector.x)
);
}
/// <summary>
/// Finds a vector perpendicular to this one.
/// </summary>
/// <returns></returns>
public Vector3 Perpendicular()
{
Vector3 result = this.Cross(Vector3.UnitX);
// check length
if (result.LengthSquared < float.Epsilon)
{
// This vector is the Y axis multiplied by a scalar, so we have to use another axis
result = this.Cross(Vector3.UnitY);
}
return result;
}
/// <summary>
/// Normalizes the vector.
/// </summary>
/// <remarks>
/// This method normalises the vector such that it's
/// length / magnitude is 1. The result is called a unit vector.
/// <p/>
/// This function will not crash for zero-sized vectors, but there
/// will be no changes made to their components.
/// </remarks>
/// <returns>The previous length of the vector.</returns>
public float Normalize()
{
float length =(float) Math.Sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
// Will also work for zero-sized vectors, but will change nothing
if (length > float.Epsilon)
{
float inverseLength = 1.0f / length;
this.x *= inverseLength;
this.y *= inverseLength;
this.z *= inverseLength;
}
return length;
}
#endregion
#region Overloaded operators + CLS compliant method equivalents
/// <summary>
/// Used when a Vector3 is added to another Vector3.
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Vector3 Add(Vector3 left, Vector3 right)
{
return left + right;
}
/// <summary>
/// Used when a Vector3 is added to another Vector3.
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Vector3 operator +(Vector3 left, Vector3 right)
{
return new Vector3(left.x + right.x, left.y + right.y, left.z + right.z);
}
/// <summary>
/// Used to subtract a Vector3 from another Vector3.
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Vector3 Subtract(Vector3 left, Vector3 right)
{
return left - right;
}
/// <summary>
/// Used to subtract a Vector3 from another Vector3.
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Vector3 operator -(Vector3 left, Vector3 right)
{
return new Vector3(left.x - right.x, left.y - right.y, left.z - right.z);
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment