//----------------------------------------------------------------//
ZLVec2D USSurface2D::GetNorm ( const ZLVec2D& e0, const ZLVec2D& e1 ) {

	ZLVec2D norm;

	norm = e0;
	norm.Sub ( e1 );
	norm.Rotate90Anticlockwise ();
	norm.Norm ();
	
	return norm;
}
//----------------------------------------------------------------//
bool USSurface2D::GetHit ( ZLVec2D& sphereLoc, ZLVec2D& move, SurfaceHit2D& hit ) {

	// The usual stuff...
	ZLVec2D unitMove = move;
	unitMove.Norm ();
	
	if ( unitMove.Dot ( this->mNorm ) >= -0.001f ) return false;
	if ( ZLDist::PointToPlane2D ( sphereLoc, *this ) <= 0.0f ) return false;
	
	// Get the point of first contact on the polygon...
	ZLVec2D pofcop = this->mNorm;
	pofcop.Reverse ();
	pofcop.Add ( sphereLoc );
	this->ClampPoint ( pofcop );

	// Send a ray from the point on the surface to intersect the circle.
	// The ray is the inverse of the move vec.
	ZLVec2D inverseMove = move;
	inverseMove.Reverse ();

	float t0, t1;
	u32 sectType;
	sectType = ZLSect::VecToCircle ( t0, t1, pofcop, inverseMove, sphereLoc, 1.0f );

	// Bail if the point will not intersect the sphere.
	if ( sectType == ZLSect::SECT_PARALLEL ) return false;

	if ( t0 >= hit.mTime ) return false;

	// Bail if the point will graze the sphere.
	if ( sectType == ZLSect::SECT_TANGENT ) return false;

	// Bail if the point will stay outside of the sphere.
	if (( t0 > 1.0f ) || ( t1 < 0.0f )) return false;

	// OMG!  We hit something!

	float time = t0;
	
	hit.mTime = time;

	inverseMove.Scale ( t0 );
	hit.mPoint = pofcop;
	hit.mPoint.Add ( inverseMove );
	
	hit.mNorm = sphereLoc;
	hit.mNorm.Sub ( hit.mPoint );
	hit.mNorm.Norm ();
	
	if ( unitMove.Dot ( hit.mNorm ) >= -0.001f ) return false;
	
	return true;
}
//----------------------------------------------------------------//
void MOAIVectorUtil::ComputeLineJoins ( MOAIVectorLineJoin* joins, const ZLVec2D* verts, int nVerts, bool open, bool forward, bool interior ) {
	
	int top = nVerts - 1;
	float scale = interior ? -1.0f : 1.0f;
	
	if ( forward ) {
		for ( int i = 0; i < nVerts; ++i ) {
			joins [ i ].mVertex = verts [ i ];
		}
	}
	else {
		for ( int i = 0; i < nVerts; ++i ) {
			joins [ i ].mVertex = verts [ top - i ];
		}
	}
	
	for ( int i = 0; i < nVerts; ++i ) {
		
		ZLVec2D v0 = joins [ i ].mVertex;
		ZLVec2D v1 = joins [( i + 1 ) % nVerts ].mVertex;
		
		ZLVec2D n = v1;
		
		n.Sub ( v0 );
		n.Norm ();
		
		joins [ i ].mEdgeVec = n;
		
		n.Rotate90Anticlockwise ();
		n.Scale ( scale );
		
		joins [ i ].mEdgeNorm = n;
		joins [ i ].mIsCap = false;
	}
	
	int start = 0;
	int max = nVerts;
	
	if ( open ) {
		
		joins [ 0 ].mIsCap = true;
		joins [ 0 ].mJointNorm = joins [ 0 ].mEdgeNorm;
		
		joins [ top ].mIsCap = true;
		joins [ top ].mEdgeVec = joins [ top - 1 ].mEdgeVec;
		joins [ top ].mEdgeNorm = joins [ top - 1 ].mEdgeNorm;
		joins [ top ].mJointNorm = joins [ top ].mEdgeNorm;
		
		start = 1;
		max = top;
	}
	
	for ( int i = start; i < max; ++i ) {
		
		ZLVec2D n = joins [( i + top ) % nVerts ].mEdgeNorm;
		n.Add ( joins [ i ].mEdgeNorm );
		n.Norm ();
		
		joins [ i ].mJointNorm = n;
	}
}