topical media & game development
student-ar-org-papervision3d-core-math-Plane3D.ax
student-ar-org-papervision3d-core-math-Plane3D.ax
[swf]
[flash]
flex
package org.papervision3d.core.math
{
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.math.util.ClassificationUtil;
The @ax-student-ar-org-papervision3d-core-math-Plane3D class represents a plane in 3D space.
author: Tim Knip
public class @ax-student-ar-org-papervision3d-core-math-Plane3D
{
private static var _yUP : Number3D = new Number3D(0, 1, 0);
private static var _zUP : Number3D = new Number3D(0, 0, 1);
The plane normal (A, B, C).
public var normal: Number3D;
D.
public var d: Number;
Constructor.
@param normal The plane normal.
@param ptOnPlane A point on the plane.
public function @ax-student-ar-org-papervision3d-core-math-Plane3D( normal : Number3D = null, ptOnPlane : Number3D = null ) : void
{
if(normal && ptOnPlane)
{
this.normal = normal;
this.d = -Number3D.dot(normal, ptOnPlane);
}
else
{
this.normal = new Number3D();
this.d = 0;
}
}
internal var eps:Number = 0.01;
public function isCoplanar( plane: @ax-student-ar-org-papervision3d-core-math-Plane3D ): Boolean
{
return ( Math.abs( normal.x - plane.normal.x ) < eps && Math.abs( normal.y - plane.normal.y ) < eps && Math.abs( normal.z - plane.normal.z ) < eps && Math.abs( d - plane.d ) < eps );
}
protected static var flipPlane:@ax-student-ar-org-papervision3d-core-math-Plane3D = new @ax-student-ar-org-papervision3d-core-math-Plane3D();
public function isCoplanarOpposite( plane: @ax-student-ar-org-papervision3d-core-math-Plane3D ): Boolean
{
flipPlane.normal.z = -plane.normal.z;
flipPlane.normal.y = -plane.normal.y;
flipPlane.normal.x = -plane.normal.x;
flipPlane.d = plane.d;
return flipPlane.isCoplanar( plane );
}
public function getFlip(): @ax-student-ar-org-papervision3d-core-math-Plane3D
{
var plane: @ax-student-ar-org-papervision3d-core-math-Plane3D = @ax-student-ar-org-papervision3d-core-math-Plane3D.fromThreePoints(new Number3D(), new Number3D(), new Number3D());
plane.normal.z = -normal.z;
plane.normal.y = -normal.y;
plane.normal.x = -normal.x;
plane.d = d;
return plane;
}
public function getTempFlip():@ax-student-ar-org-papervision3d-core-math-Plane3D
{
flipPlane.normal.z = -normal.z;
flipPlane.normal.y = -normal.y;
flipPlane.normal.x = -normal.x;
flipPlane.d = d;
return flipPlane;
}
public function getIntersectionLineNumbers( v0: Number3D, v1: Number3D ): Number3D
{
var d0: Number = normal.x * v0.x + normal.y * v0.y + normal.z * v0.z - d;
var d1: Number = normal.x * v1.x + normal.y * v1.y + normal.z * v1.z - d;
var m: Number = d1 / ( d1 - d0 );
return new Number3D(
v1.x + ( v0.x - v1.x ) * m,
v1.y + ( v0.y - v1.y ) * m,
v1.z + ( v0.z - v1.z ) * m
);
}
public function getIntersectionLine( v0: Vertex3D, v1: Vertex3D ): Vertex3D
{
var d0: Number = normal.x * v0.x + normal.y * v0.y + normal.z * v0.z - d;
var d1: Number = normal.x * v1.x + normal.y * v1.y + normal.z * v1.z - d;
var m: Number = d1 / ( d1 - d0 );
return new Vertex3D(
v1.x + ( v0.x - v1.x ) * m,
v1.y + ( v0.y - v1.y ) * m,
v1.z + ( v0.z - v1.z ) * m
);
}
Creates a plane from coefficients.
@param a
@param b
@param c
@param d
@return The created plane.
public static function fromCoefficients( a:Number, b:Number, c:Number, d:Number ) : @ax-student-ar-org-papervision3d-core-math-Plane3D
{
var plane:@ax-student-ar-org-papervision3d-core-math-Plane3D = new @ax-student-ar-org-papervision3d-core-math-Plane3D();
plane.setCoefficients(a, b, c, d);
return plane;
}
Creates a plane from a normal and a point.
@param normal
@param point
@return The created plane.
public static function fromNormalAndPoint( normal : *, point : * ) : @ax-student-ar-org-papervision3d-core-math-Plane3D
{
var n : Number3D = normal is Number3D ? normal : new Number3D(normal.x, normal.y, normal.z);
var p : Number3D = point is Number3D ? point : new Number3D(point.x, point.y, point.z);
return new @ax-student-ar-org-papervision3d-core-math-Plane3D(n, p);
}
Creates a plane from three points.
@param p0 First point.
@param p1 Second point.
@param p2 Third point.
@return The created plane.
public static function fromThreePoints( p0:*, p1:*, p2:* ):@ax-student-ar-org-papervision3d-core-math-Plane3D
{
var plane:@ax-student-ar-org-papervision3d-core-math-Plane3D = new @ax-student-ar-org-papervision3d-core-math-Plane3D();
var n0 : Number3D = p0 is Number3D ? p0 : new Number3D(p0.x, p0.y, p0.z);
var n1 : Number3D = p1 is Number3D ? p1 : new Number3D(p1.x, p1.y, p1.z);
var n2 : Number3D = p2 is Number3D ? p2 : new Number3D(p2.x, p2.y, p2.z);
plane.setThreePoints(n0, n1, n2);
return plane;
}
Get the closest point on the plane.
@param point The point to 'project'.
parameter: ptOnPlane A known point on the plane.
public function closestPointOnPlane( point : Number3D, ptOnPlane : Number3D ) : Number3D
{
var dist : Number = Number3D.dot(this.normal, Number3D.sub(point, ptOnPlane));
var ret : Number3D = point.clone();
ret.x -= (dist * this.normal.x);
ret.y -= (dist * this.normal.y);
ret.z -= (dist * this.normal.z);
return ret;
}
distance of point to plane.
@param v
@return
public function distance( pt:* ):Number
{
var p:Number3D = pt is Vertex3D ? pt.toNumber3D() : pt;
return Number3D.dot(p, normal) + d;
}
distance of vertex to plane, optimized.
@param v
@return
public function vertDistance(pt:Vertex3D):Number
{
return ( pt.x * normal.x + normal.y * pt.y + pt.z * normal.z )+d;
}
normalize.
@return
public function normalize():void
{
var n:Number3D = this.normal;
//compute the length of the vector
var len:Number = Math.sqrt(n.x*n.x + n.y*n.y + n.z*n.z);
// normalize
n.x /= len;
n.y /= len;
n.z /= len;
this.d /= len;
}
Sets this plane from ABCD coefficients.
@param a
@param b
@param c
@param d
public function setCoefficients( a:Number, b:Number, c:Number, d:Number ):void
{
// set the normal vector
this.normal.x = a;
this.normal.y = b;
this.normal.z = c;
this.d = d;
normalize();
}
Sets this plane from a normal and a point.
@param normal
@param pt
public function setNormalAndPoint( normal:Number3D, pt:Number3D ):void
{
this.normal = normal;
this.d = -Number3D.dot(normal, pt);
}
Sets this plane from three points.
@param p0
@param p1
@param p2
public function setThreePoints( p0:Number3D, p1:Number3D, p2:Number3D ):void
{
var ab:Number3D = Number3D.sub(p1, p0);
var ac:Number3D = Number3D.sub(p2, p0);
this.normal = Number3D.cross(ab, ac);
this.normal.normalize();
this.d = -Number3D.dot(normal, p0);
}
Gets the side a vertex is on.
public function pointOnSide(num:Number3D):int
{
var distance:Number = distance(num);
if(distance < 0){
return ClassificationUtil.BACK;
}else if(distance > 0){
return ClassificationUtil.FRONT;
}
return ClassificationUtil.COINCIDING;
}
Projects points onto this plane.
<p>Passed points should be in the XY-plane. If the points have Z=0 then the points are
projected exactly on the plane. When however Z is greater then zero, the points are
moved 'out of the plane' by a distance Z. Negative values for Z move the points 'into the plane'.</p>
@param points Array of points (any object with x, y, z props).
@param origin Where to move the points.
public function projectPoints( points : Array, origin : Number3D = null ) : void {
// use other up-vector if angle between plane-normal and up-vector approaches zero.
var dot : Number = Number3D.dot(_yUP, this.normal);
// when the dot-product approaches 1 the angle approaches 0
var up : Number3D = Math.abs(dot) > 0.99 ? _zUP : _yUP;
// get side vector
var side:Number3D = Number3D.cross(up, normal);
side.normalize();
// adjust up vector
up = Number3D.cross(normal, side);
up.normalize();
// create the matrix!
var matrix : Matrix3D = new Matrix3D([
side.x, up.x, normal.x, 0,
side.y, up.y, normal.y, 0,
side.z, up.z, normal.z, 0,
0, 0, 0, 1]);
// translate if wanted
if(origin)
matrix = Matrix3D.multiply(Matrix3D.translationMatrix(origin.x, origin.y, origin.z), matrix);
// project!
var n : Number3D = new Number3D();
for each( var point:* in points ) {
n.x = point["x"];
n.y = point["y"];
n.z = point["z"];
Matrix3D.multiplyVector(matrix, n);
point["x"] = n.x;
point["y"] = n.y;
point["z"] = n.z;
}
}
public function toString():String
{
return "[a:" + normal.x +" b:" +normal.y + " c:" +normal.z + " d:" + d + "]";
}
}
}
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.