www.pudn.com > mfcopentree.rar > 3DMath.cpp


#include "stdafx.h" 
#include 	// We include math.h so we can use the sqrt() function 
#include "3DMath.h" 
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// * 
 
#include 	// This is so we can use _isnan() for acos() 
#include "resource.h" 
// 
// 
// This file was build from the Ray Plane Collision tutorial. 
// We added 5 new functions to this math file:   
// 
// This returns the dot product between 2 vectors 
// float Dot(CVector3 vVector1, CVector3 vVector2); 
// 
// This returns the angle between 2 vectors 
// double AngleBetweenVectors(CVector3 Vector1, CVector3 Vector2); 
// 
// This returns an intersection point of a polygon and a line (assuming intersects the plane) 
// CVector3 IntersectionPoint(CVector3 vNormal, CVector3 vLine[], double distance); 
// 
// This returns true if the intersection point is inside of the polygon 
// bool InsidePolygon(CVector3 vIntersection, CVector3 Poly[], long verticeCount); 
// 
// Use this function to test collision between a line and polygon 
// bool IntersectedPolygon(CVector3 vPoly[], CVector3 vLine[], int verticeCount); 
// 
// These will enable to check if we internet not just the plane of a polygon, 
// but the actual polygon itself.  Once the line is outside the permiter, it will fail 
// on a collision test. 
// 
// 
//武汉华中科技大学,2002,(C)版权所有 
//作者:金德才 联系方式:iskyflying@163.com 
//请不要将本软件的任何一部分用于商业用途 
//如果您觉得任何地方有用或者错误,请告诉作者,谢谢! 
//如果你想引用部分源程序,请注明作者信息 
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// * 
 
int whichnode = 1;//处理到第几个子节点 
long zongshu = 0;//均匀切分的子节点总数 
double zongshu_d = 0;//跟踪zongshu的double值 
 
 
/////////////////////////////////////// CROSS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This returns a perpendicular vector from 2 given vectors by taking the cross product. 
///// 
/////////////////////////////////////// CROSS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
												 
CVector3 Cross(CVector3 vVector1, CVector3 vVector2) 
{ 
	CVector3 vNormal;									// The vector to hold the cross product 
 
	// Once again, if we are given 2 vectors (directions of 2 sides of a polygon) 
	// then we have a plane define.  The cross product finds a vector that is perpendicular 
	// to that plane, which means it's point straight out of the plane at a 90 degree angle. 
	 
	// The X value for the vector is:  (V1.y * V2.z) - (V1.z * V2.y)													// Get the X value 
	vNormal.x = ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y)) ; 
	if(vNormal.x < 0.000001 && vNormal.x > -0.000001) 
		vNormal.x = 0; 
														 
	// The Y value for the vector is:  (V1.z * V2.x) - (V1.x * V2.z) 
	vNormal.y = ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z)); 
	if(vNormal.y < 0.000001 && vNormal.y > -0.000001) 
		vNormal.y = 0;		 
	 
	// The Z value for the vector is:  (V1.x * V2.y) - (V1.y * V2.x) 
	vNormal.z = ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x)); 
	if(vNormal.z < 0.000001 && vNormal.z > -0.000001) 
		vNormal.z = 0; 
 
	return vNormal;										// Return the cross product (Direction the polygon is facing - Normal) 
} 
 
 
/////////////////////////////////////// VECTOR \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This returns a vector between 2 points 
///// 
/////////////////////////////////////// VECTOR \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
 
CVector3 Vector(CVector3 vPoint1, CVector3 vPoint2) 
{ 
	CVector3 vVector = {0};								// Initialize our variable to zero 
 
	// In order to get a vector from 2 points (a direction) we need to 
	// subtract the second point from the first point. 
 
	vVector.x = vPoint1.x - vPoint2.x;					// Get the X value of our new vector 
	vVector.y = vPoint1.y - vPoint2.y;					// Get the Y value of our new vector 
	vVector.z = vPoint1.z - vPoint2.z;					// Get the Z value of our new vector 
 
	return vVector;										// Return our new vector 
} 
 
 
/////////////////////////////////////// MAGNITUDE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This returns the magnitude of a normal (or any other vector) 
///// 
/////////////////////////////////////// MAGNITUDE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
 
float Magnitude(CVector3 vNormal) 
{ 
	// This will give us the magnitude or "Norm" as some say, of our normal. 
	// Here is the equation:  magnitude = sqrt(V.x^2 + V.y^2 + V.z^2)  Where V is the vector 
 
	return (float)sqrt( (vNormal.x * vNormal.x) + (vNormal.y * vNormal.y) + (vNormal.z * vNormal.z) ); 
} 
 
 
/////////////////////////////////////// NORMALIZE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This returns a normalize vector (A vector exactly of length 1) 
///// 
/////////////////////////////////////// NORMALIZE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
 
CVector3 Normalize(CVector3 vNormal) 
{ 
	float magnitude = Magnitude(vNormal);				// Get the magnitude of our normal 
 
	// Now that we have the magnitude, we can divide our normal by that magnitude. 
	// That will make our normal a total length of 1.  This makes it easier to work with too. 
 
	vNormal.x /= magnitude;								// Divide the X value of our normal by it's magnitude 
	vNormal.y /= magnitude;								// Divide the Y value of our normal by it's magnitude 
	vNormal.z /= magnitude;								// Divide the Z value of our normal by it's magnitude 
 
	// Finally, return our normalized normal. 
 
	return vNormal;										// Return the new normal of length 1. 
} 
 
 
/////////////////////////////////////// NORMAL \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This returns the normal of a polygon (The direction the polygon is facing) 
///// 
/////////////////////////////////////// NORMAL \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
 
CVector3 NormalVector(CVector3 vTriangle[])					 
{														// Get 2 vectors from the polygon (2 sides), Remember the order! 
	CVector3 vVector1 = Vector(vTriangle[2], vTriangle[0]); 
	CVector3 vVector2 = Vector(vTriangle[1], vTriangle[0]); 
 
	CVector3 vNormal = Cross(vVector1, vVector2);		// Take the cross product of our 2 vectors to get a perpendicular vector 
 
	// Now we have a normal, but it's at a strange length, so let's make it length 1. 
 
	vNormal = Normalize(vNormal);						// Use our function we created to normalize the normal (Makes it a length of one) 
 
	return vNormal;										// Return our normal at our desired length 
} 
 
 
/////////////////////////////////// PLANE DISTANCE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This returns the distance between a plane and the origin 
///// 
/////////////////////////////////// PLANE DISTANCE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
									 
float PlaneDistance(CVector3 Normal, CVector3 Point) 
{	 
	float distance = 0;									// This variable holds the distance from the plane tot he origin 
 
	// Use the plane equation to find the distance (Ax + By + Cz + D = 0)  We want to find D. 
	// So, we come up with D = -(Ax + By + Cz) 
														// Basically, the negated dot product of the normal of the plane and the point. (More about the dot product in another tutorial) 
	distance = - ((Normal.x * Point.x) + (Normal.y * Point.y) + (Normal.z * Point.z)); 
 
	return distance;									// Return the distance 
} 
 
 
 
 
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// * 
 
// Since the last tutorial, we added 2 more parameters for the normal and the distance 
// from the origin.  This is so we don't have to recalculate it 3 times in our IntersectionPoint()  
// IntersectedPolygon() functions.  We would probably make 2 different functions for 
// this so we have the choice of getting the normal and distance back, or not. 
// I also changed the vTriangle to "vPoly" because it isn't always a triangle. 
// The code doesn't change, it's just more correct (though we only need 3 points anyway). 
// For C programmers, the '&' is called a reference and is the same concept as the '*' for addressing. 
 
 
/////////////////////////////////// INTERSECTED PLANE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This checks to see if a line intersects a plane 
///// 
/////////////////////////////////// INTERSECTED PLANE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
	 
bool IntersectedPlane_2(CVector3 vLine[], CVector3 vNormal, float originDistance) 
{ 
	float distance1=0, distance2=0;	 
	distance1 = ((vNormal.x * vLine[0].x)  +					// Ax + 
		         (vNormal.y * vLine[0].y)  +					// By + 
				 (vNormal.z * vLine[0].z)) + originDistance;	// Cz + D 
	 
	// Get the distance from point2 from the plane using Ax + By + Cz + D = (The distance from the plane) 
	 
	distance2 = ((vNormal.x * vLine[1].x)  +					// Ax + 
		         (vNormal.y * vLine[1].y)  +					// By + 
				 (vNormal.z * vLine[1].z)) + originDistance;	// Cz + D 
 
	if(distance1 * distance2 > 0)			// Check to see if both point's distances are both negative or both positive 
	   return false;						// Return false if each point has the same sign.  -1 and 1 would mean each point is on either side of the plane.  -1 -2 or 3 4 wouldn't... 
	else 
		return true; 
/*	 
	if(distance1 == 0 && distance2 ==0) 
		return true; 
	return true; 
*/ 
} 
										 
bool IntersectedPlane(CVector3 vPoly[], CVector3 vLine[], CVector3 &vNormal, float &originDistance) 
{ 
	float distance1=0, distance2=0;						// The distances from the 2 points of the line from the plane 
			 
	vNormal = NormalVector(vPoly);							// We need to get the normal of our plane to go any further 
 
	// Let's find the distance our plane is from the origin.  We can find this value 
	// from the normal to the plane (polygon) and any point that lies on that plane (Any vertice) 
	originDistance = PlaneDistance(vNormal, vPoly[0]); 
 
	// Get the distance from point1 from the plane using: Ax + By + Cz + D = (The distance from the plane) 
 
	distance1 = ((vNormal.x * vLine[0].x)  +					// Ax + 
		         (vNormal.y * vLine[0].y)  +					// Bx + 
				 (vNormal.z * vLine[0].z)) + originDistance;	// Cz + D 
	 
	// Get the distance from point2 from the plane using Ax + By + Cz + D = (The distance from the plane) 
	 
	distance2 = ((vNormal.x * vLine[1].x)  +					// Ax + 
		         (vNormal.y * vLine[1].y)  +					// Bx + 
				 (vNormal.z * vLine[1].z)) + originDistance;	// Cz + D 
 
	// Now that we have 2 distances from the plane, if we times them together we either 
	// get a positive or negative number.  If it's a negative number, that means we collided! 
	// This is because the 2 points must be on either side of the plane (IE. -1 * 1 = -1). 
 
	if(distance1 * distance2 >= 0)			// Check to see if both point's distances are both negative or both positive 
	   return false;						// Return false if each point has the same sign.  -1 and 1 would mean each point is on either side of the plane.  -1 -2 or 3 4 wouldn't... 
					 
	return true;							// The line intersected the plane, Return TRUE 
} 
 
 
/////////////////////////////////// DOT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This computers the dot product of 2 vectors 
///// 
/////////////////////////////////// DOT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
 
float Dot(CVector3 vVector1, CVector3 vVector2)  
{ 
	// The dot product is this equation: V1.V2 = (V1.x * V2.x  +  V1.y * V2.y  +  V1.z * V2.z) 
	// In math terms, it looks like this:  V1.V2 = ||V1|| ||V2|| cos(theta) 
	// The '.' means DOT.   The || || is magnitude.  So the magnitude of V1 times the magnitude 
	// of V2 times the cosine of the angle.  It seems confusing now, but it will become more clear. 
	// This function is used for a ton of things, which we will cover in other tutorials. 
	// For this tutorial, we use it to compute the angle between 2 vectors.  If the vectors 
	// are normalize, the dot product returns the cosine of the angle between the 2 vectors. 
	// What does that mean? Well, it doesn't return the actual angle, it returns the value of: 
	// cos(angle).	Well, what if we want to get the actual angle?  Then we use the arc cosine. 
	// There is more on this in the below function AngleBetweenVectors().  Let's give some 
	// applications of using the dot product.  How would you tell if the angle between the 
	// 2 vectors is perpendicular (90 degrees)?  Well, if we normalize the vectors we can 
	// get rid of the ||V1|| * ||V2|| in front, which just leaves us with:  cos(theta). 
	// If a vector is normalize, it's magnitude is 1, so it would be: 1 * 1 * cos(theta) ,  
	// which is pointless, so we discard that part of the equation.  So, What is the cosine of 90? 
	// If you punch it in your calculator you will find that it's 0.  So that means 
	// if the dot product of 2 angles is 0, then they are perpendicular.  What we did in 
	// our mind is take the arc cosine of 0, which is 90 (or PI/2 in radians).  More on this below. 
 
			 //    (V1.x * V2.x        +        V1.y * V2.y        +        V1.z * V2.z) 
	return ( (vVector1.x * vVector2.x) + (vVector1.y * vVector2.y) + (vVector1.z * vVector2.z) ); 
} 
 
 
/////////////////////////////////// ANGLE BETWEEN VECTORS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This checks to see if a point is inside the ranges of a polygon 
///// 
/////////////////////////////////// ANGLE BETWEEN VECTORS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
 
double AngleBetweenVectors(CVector3 Vector1, CVector3 Vector2) 
{							 
	// Remember, above we said that the Dot Product of returns the cosine of the angle 
	// between 2 vectors?  Well, that is assuming they are unit vectors (normalize vectors). 
	// So, if we don't have a unit vector, then instead of just saying  arcCos(DotProduct(A, B)) 
	// We need to divide the dot product by the magnitude of the 2 vectors multiplied by each other. 
	// Here is the equation:   arc cosine of (V . W / || V || * || W || ) 
	// the || V || means the magnitude of V.  This then cancels out the magnitudes dot product magnitudes. 
	// But basically, if you have normalize vectors already, you can forget about the magnitude part. 
 
	// Get the dot product of the vectors 
	float dotProduct = Dot(Vector1, Vector2);				 
 
	// Get the product of both of the vectors magnitudes 
	float vectorsMagnitude = Magnitude(Vector1) * Magnitude(Vector2) ; 
 
	// Get the arc cosine of the (dotProduct / vectorsMagnitude) which is the angle in RADIANS. 
	// (IE.   PI/2 radians = 90 degrees      PI radians = 180 degrees    2*PI radians = 360 degrees) 
	// To convert radians to degress use this equation:   radians * (PI / 180) 
	// TO convert degrees to radians use this equation:   degrees * (180 / PI) 
	double angle = acos( dotProduct / vectorsMagnitude ); 
 
	// Here we make sure that the angle is not a -1.#IND0000000 number, which means indefinate. 
	// acos() thinks it's funny when it returns -1.#IND0000000.  If we don't do this check, 
	// our collision results will sometimes say we are colliding when we aren't.  I found this 
	// out the hard way after MANY hours and already wrong written tutorials :)  Usually 
	// this value is found when the dot product and the maginitude are the same value. 
	// We want to return 0 when this happens. 
	if(_isnan(angle)) 
		return 0; 
	 
	// Return the angle in radians 
	return( angle ); 
} 
 
 
/////////////////////////////////// INTERSECTION POINT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This returns the intersection point of the line that intersects the plane 
///// 
/////////////////////////////////// INTERSECTION POINT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
											 
CVector3 IntersectionPoint(CVector3 vNormal, CVector3 vLine[], double distance) 
{ 
	CVector3 vPoint = {0}, vLineDir = {0};		// Variables to hold the point and the line's direction 
	double Numerator = 0.0, Denominator = 0.0, dist = 0.0; 
 
	// Here comes the confusing part.  We need to find the 3D point that is actually 
	// on the plane.  Here are some steps to do that: 
	 
	// 1)  First we need to get the vector of our line, Then normalize it so it's a length of 1 
	vLineDir = Vector(vLine[1], vLine[0]);		// Get the Vector of the line 
	vLineDir = Normalize(vLineDir);				// Normalize the lines vector 
 
 
	// 2) Use the plane equation (distance = Ax + By + Cz + D) to find the distance from one of our points to the plane. 
	//    Here I just chose a arbitrary point as the point to find that distance.  You notice we negate that 
	//    distance.  We negate the distance because we want to eventually go BACKWARDS from our point to the plane. 
	//    By doing this is will basically bring us back to the plane to find our intersection point. 
	Numerator = - (vNormal.x * vLine[0].x +		// Use the plane equation with the normal and the line 
				   vNormal.y * vLine[0].y + 
				   vNormal.z * vLine[0].z + distance); 
 
	// 3) If we take the dot product between our line vector and the normal of the polygon, 
	//    this will give us the cosine of the angle between the 2 (since they are both normalized - length 1). 
	//    We will then divide our Numerator by this value to find the offset towards the plane from our arbitrary point. 
	Denominator = Dot(vNormal, vLineDir);		// Get the dot product of the line's vector and the normal of the plane 
				   
	// Since we are using division, we need to make sure we don't get a divide by zero error 
	// If we do get a 0, that means that there are INFINATE points because the the line is 
	// on the plane (the normal is perpendicular to the line - (Normal.Vector = 0)).   
	// In this case, we should just return any point on the line. 
 
	if( Denominator == 0.0)						// Check so we don't divide by zero 
		return vLine[0];						// Return an arbitrary point on the line 
 
	// We divide the (distance from the point to the plane) by (the dot product) 
	// to get the distance (dist) that we need to move from our arbitrary point.  We need 
	// to then times this distance (dist) by our line's vector (direction).  When you times 
	// a scalar (single number) by a vector you move along that vector.  That is what we are 
	// doing.  We are moving from our arbitrary point we chose from the line BACK to the plane 
	// along the lines vector.  It seems logical to just get the numerator, which is the distance 
	// from the point to the line, and then just move back that much along the line's vector. 
	// Well, the distance from the plane means the SHORTEST distance.  What about in the case that 
	// the line is almost parallel with the polygon, but doesn't actually intersect it until half 
	// way down the line's length.  The distance from the plane is short, but the distance from 
	// the actual intersection point is pretty long.  If we divide the distance by the dot product 
	// of our line vector and the normal of the plane, we get the correct length.  Cool huh? 
 
	dist = Numerator / Denominator;				// Divide to get the multiplying (percentage) factor 
	 
	// Now, like we said above, we times the dist by the vector, then add our arbitrary point. 
	// This essentially moves the point along the vector to a certain distance.  This now gives 
	// us the intersection point.  Yay! 
 
	vPoint.x = (float)(vLine[0].x + (vLineDir.x * dist)); 
	vPoint.y = (float)(vLine[0].y + (vLineDir.y * dist)); 
	vPoint.z = (float)(vLine[0].z + (vLineDir.z * dist)); 
 
	return vPoint;								// Return the intersection point 
} 
 
 
/////////////////////////////////// INSIDE POLYGON \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This checks to see if a point is inside the ranges of a polygon 
///// 
/////////////////////////////////// INSIDE POLYGON \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
 
bool InsidePolygon(CVector3 vIntersection, CVector3 Poly[], long verticeCount) 
{ 
	const double MATCH_FACTOR = 0.9999;		// Used to cover up the error in floating point 
	double Angle = 0.0;						// Initialize the angle 
	CVector3 vA, vB;						// Create temp vectors 
	 
	// Just because we intersected the plane, doesn't mean we were anywhere near the polygon. 
	// This functions checks our intersection point to make sure it is inside of the polygon. 
	// This is another tough function to grasp at first, but let me try and explain. 
	// It's a brilliant method really, what it does is create triangles within the polygon 
	// from the intersection point.  It then adds up the inner angle of each of those triangles. 
	// If the angles together add up to 360 degrees (or 2 * PI in radians) then we are inside! 
	// If the angle is under that value, we must be outside of polygon.  To further 
	// understand why this works, take a pencil and draw a perfect triangle.  Draw a dot in 
	// the middle of the triangle.  Now, from that dot, draw a line to each of the vertices. 
	// Now, we have 3 triangles within that triangle right?  Now, we know that if we add up 
	// all of the angles in a triangle we get 360 right?  Well, that is kinda what we are doing, 
	// but the inverse of that.  Say your triangle is an isosceles triangle, so add up the angles 
	// and you will get 360 degree angles.  90 + 90 + 90 is 360. 
 
	for (int i = 0; i < verticeCount; i++)		// Go in a circle to each vertex and get the angle between 
	{	 
		vA = Vector(Poly[i], vIntersection);	// Subtract the intersection point from the current vertex 
												// Subtract the point from the next vertex 
		vB = Vector(Poly[(i + 1) % verticeCount], vIntersection); 
												 
		Angle += AngleBetweenVectors(vA, vB);	// Find the angle between the 2 vectors and add them all up as we go along 
	} 
 
	// Now that we have the total angles added up, we need to check if they add up to 360 degrees. 
	// Since we are using the dot product, we are working in radians, so we check if the angles 
	// equals 2*PI.  We defined PI in 3DMath.h.  You will notice that we use a MATCH_FACTOR 
	// in conjunction with our desired degree.  This is because of the inaccuracy when working 
	// with floating point numbers.  It usually won't always be perfectly 2 * PI, so we need 
	// to use a little twiddling.  I use .9999, but you can change this to fit your own desired accuracy. 
												 
	if(Angle >= (MATCH_FACTOR * (2.0 * PI)) )	// If the angle is greater than 2 PI, (360 degrees) 
		return TRUE;							// The point is inside of the polygon 
		 
	return FALSE;								// If you get here, it obviously wasn't inside the polygon, so Return FALSE 
} 
 
 
/////////////////////////////////// INTERSECTED POLYGON \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
///// 
/////	This checks if a line is intersecting a polygon 
///// 
/////////////////////////////////// INTERSECTED POLYGON \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* 
 
bool IntersectedPolygon(CVector3 vPoly[], CVector3 vLine[], int verticeCount) 
{ 
	CVector3 vNormal = {0}; 
	float originDistance = 0; 
 
	// First we check to see if our line intersected the plane.  If this isn't true 
	// there is no need to go on, so return false immediately. 
	// We pass in address of vNormal and originDistance so we only calculate it once 
 
									 // Reference   // Reference 
	if(!IntersectedPlane(vPoly, vLine,   vNormal,   originDistance)) 
		return false; 
 
	// Now that we have our normal and distance passed back from IntersectedPlane(),  
	// we can use it to calculate the intersection point.  The intersection point 
	// is the point that actually is ON the plane.  It is between the line.  We need 
	// this point test next, if we are inside the polygon.  To get the I-Point, we 
	// give our function the normal of the plan, the points of the line, and the originDistance. 
 
	CVector3 vIntersection = IntersectionPoint(vNormal, vLine, originDistance); 
 
 
	//排除端点的情形 
	for(int i=0; i<2; i++) 
	{ 
		if(vIntersection.x == vLine[i].x && vIntersection.y == vLine[i].y && vIntersection.z == vLine[i].z) 
			return FALSE; 
	} 
 
	// Now that we have the intersection point, we need to test if it's inside the polygon. 
	// To do this, we pass in : 
	// (our intersection point, the polygon, and the number of vertices our polygon has) 
 
	if(InsidePolygon(vIntersection, vPoly, verticeCount)) 
		return true;							// We collided!	  Return success 
 
 
	// If we get here, we must have NOT collided 
 
	return false;								// There was no collision, so return false 
} 
 
bool IntersectedPolygon2(CVector3 tri[3], CVector3 nor, CVector3 vLine[], float dis)//三角形平面方程已知 
{ 
	CVector3 vNormal = {0}; 
								 
	if(!IntersectedPlane_2(vLine, nor, dis)) 
		return false; 
 
	CVector3 vIntersection = IntersectionPoint(nor, vLine, dis); 
/* 
	//排除端点的情形 
	for(int i=0; i<2; i++) 
	{ 
		if(vIntersection.x == vLine[i].x && vIntersection.y == vLine[i].y && vIntersection.z == vLine[i].z) 
			return FALSE; 
	} 
*/ 
	// Now that we have the intersection point, we need to test if it's inside the polygon. 
	// To do this, we pass in : 
	// (our intersection point, the polygon, and the number of vertices our polygon has) 
 
	if(InsidePolygon(vIntersection, tri, 3)) 
		return true;							// We collided!	  Return success 
 
 
	// If we get here, we must have NOT collided 
 
	return false;								// There was no collision, so return false 
} 
 
bool IntersectedPolygon3(CVector3 vPoly[], CVector3 nor, CVector3 vLine[], int verticeCount, float dis) 
{ 
	CVector3 vNormal = {0}; 
								 
	if(!IntersectedPlane_2(vLine, nor, dis)) 
		return false; 
 
	CVector3 vIntersection = IntersectionPoint(nor, vLine, dis); 
 
	// Now that we have the intersection point, we need to test if it's inside the polygon. 
	// To do this, we pass in : 
	// (our intersection point, the polygon, and the number of vertices our polygon has) 
 
	if(InsidePolygon(vIntersection, vPoly, verticeCount)) 
		return true;							// We collided!	  Return success 
 
 
	// If we get here, we must have NOT collided 
 
	return false;						 
} 
 
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// * 
 
////////////////////////////////////// 
//八叉树划分空间算法 
////////////////////////////////////// 
 
 
void CreateNode(STLOctTree *node, STLArray *data, float precision, int i) 
{ 
	if(node->IsHave == 0 || node->m_Width <= precision) 
	{ 
		zongshu_d = zongshu_d-pow(node->m_Width/precision, 3); 
		return; 
	} 
 
	if(whichnode==1)//计算另一棵树 
	{ 
		zongshu_d = pow(node->m_Width/precision, 3); 
	} 
 
	whichnode++; 
	if(zongshu_d>1000) 
	{ 
		if(whichnode%8==0) 
		{ 
			zongshu = long(zongshu_d); 
			::SendMessage(AfxGetApp()->GetMainWnd()->m_hWnd, WM_DISPPROG, whichnode+(i<<16), zongshu); 
		} 
	} 
	else if(zongshu_d<=1000 && zongshu_d>=600) 
	{ 
		if(whichnode%4==0) 
		{ 
			zongshu = long(zongshu_d); 
			::SendMessage(AfxGetApp()->GetMainWnd()->m_hWnd, WM_DISPPROG, whichnode+(i<<16), zongshu); 
		} 
	} 
	else 
	{ 
		if(whichnode%2==0) 
		{ 
			zongshu = long(zongshu_d); 
			::SendMessage(AfxGetApp()->GetMainWnd()->m_hWnd, WM_DISPPROG, whichnode+(i<<16), zongshu); 
		}	 
	} 
	STLOctTree *childnode1 = new STLOctTree;	 
	STLOctTree *childnode2 = new STLOctTree; 
	STLOctTree *childnode3 = new STLOctTree; 
	STLOctTree *childnode4 = new STLOctTree; 
	STLOctTree *childnode5 = new STLOctTree; 
	STLOctTree *childnode6 = new STLOctTree; 
	STLOctTree *childnode7 = new STLOctTree; 
	STLOctTree *childnode8 = new STLOctTree; 
 
	for(int vv=0; vv<8; vv++) 
	{ 
		childnode1->pchild[vv] = NULL; 
		childnode2->pchild[vv] = NULL; 
		childnode3->pchild[vv] = NULL; 
		childnode4->pchild[vv] = NULL; 
		childnode5->pchild[vv] = NULL; 
		childnode6->pchild[vv] = NULL; 
		childnode7->pchild[vv] = NULL; 
		childnode8->pchild[vv] = NULL; 
	} 
 
	node->pchild[0] = childnode1; 
	node->pchild[1] = childnode2; 
	node->pchild[2] = childnode3; 
	node->pchild[3] = childnode4; 
	node->pchild[4] = childnode5; 
	node->pchild[5] = childnode6; 
	node->pchild[6] = childnode7; 
	node->pchild[7] = childnode8; 
 
	childnode1->m_vCenter.x = node->m_vCenter.x - node->m_Width/4.0f; 
	childnode1->m_vCenter.y = node->m_vCenter.y + node->m_Width/4.0f; 
	childnode1->m_vCenter.z = node->m_vCenter.z + node->m_Width/4.0f; 
	childnode1->m_Width     = node->m_Width/2.0f; 
	childnode1->IsHave      = ChildIsHave(childnode1, data); 
	CreateNode(childnode1, data, precision, i); 
 
	childnode2->m_vCenter.x = node->m_vCenter.x - node->m_Width/4.0f; 
	childnode2->m_vCenter.y = node->m_vCenter.y + node->m_Width/4.0f; 
	childnode2->m_vCenter.z = node->m_vCenter.z - node->m_Width/4.0f; 
	childnode2->m_Width     = node->m_Width/2.0f; 
	childnode2->IsHave      = ChildIsHave(childnode2, data); 
	CreateNode(childnode2, data, precision, i); 
 
	childnode3->m_vCenter.x = node->m_vCenter.x + node->m_Width/4.0f; 
	childnode3->m_vCenter.y = node->m_vCenter.y + node->m_Width/4.0f; 
	childnode3->m_vCenter.z = node->m_vCenter.z - node->m_Width/4.0f; 
	childnode3->m_Width     = node->m_Width/2.0f; 
	childnode3->IsHave      = ChildIsHave(childnode3, data); 
	CreateNode(childnode3, data, precision, i); 
 
	childnode4->m_vCenter.x = node->m_vCenter.x + node->m_Width/4.0f; 
	childnode4->m_vCenter.y = node->m_vCenter.y + node->m_Width/4.0f; 
	childnode4->m_vCenter.z = node->m_vCenter.z + node->m_Width/4.0f; 
	childnode4->m_Width     = node->m_Width/2.0f; 
	childnode4->IsHave      = ChildIsHave(childnode4, data); 
	CreateNode(childnode4, data, precision, i); 
	 
	childnode5->m_vCenter.x = node->m_vCenter.x - node->m_Width/4.0f; 
	childnode5->m_vCenter.y = node->m_vCenter.y - node->m_Width/4.0f; 
	childnode5->m_vCenter.z = node->m_vCenter.z + node->m_Width/4.0f; 
	childnode5->m_Width     = node->m_Width/2.0f; 
	childnode5->IsHave      = ChildIsHave(childnode5, data); 
	CreateNode(childnode5, data, precision, i); 
 
	childnode6->m_vCenter.x = node->m_vCenter.x - node->m_Width/4.0f; 
	childnode6->m_vCenter.y = node->m_vCenter.y - node->m_Width/4.0f; 
	childnode6->m_vCenter.z = node->m_vCenter.z - node->m_Width/4.0f; 
	childnode6->m_Width     = node->m_Width/2.0f; 
	childnode6->IsHave      = ChildIsHave(childnode6, data); 
	CreateNode(childnode6, data, precision, i); 
 
	childnode7->m_vCenter.x = node->m_vCenter.x + node->m_Width/4.0f; 
	childnode7->m_vCenter.y = node->m_vCenter.y - node->m_Width/4.0f; 
	childnode7->m_vCenter.z = node->m_vCenter.z - node->m_Width/4.0f; 
	childnode7->m_Width     = node->m_Width/2.0f; 
	childnode7->IsHave      = ChildIsHave(childnode7, data); 
	CreateNode(childnode7, data, precision, i); 
 
	childnode8->m_vCenter.x = node->m_vCenter.x + node->m_Width/4.0f; 
	childnode8->m_vCenter.y = node->m_vCenter.y - node->m_Width/4.0f; 
	childnode8->m_vCenter.z = node->m_vCenter.z + node->m_Width/4.0f; 
	childnode8->m_Width     = node->m_Width/2.0f; 
	childnode8->IsHave      = ChildIsHave(childnode8, data); 
	CreateNode(childnode8, data, precision, i); 
} 
 
int ChildIsHave(STLOctTree *node, STLArray *data) 
{ 
		STLData *tri = data->stl->next; 
		while( tri != NULL ) 
		{ 
			//三角形有一点在立方体内 
			if((tri->fPoint1[0] <= node->m_vCenter.x+node->m_Width/2.0f+0.00001f && 
				tri->fPoint1[0] >= node->m_vCenter.x-node->m_Width/2.0f-0.00001f && 
				tri->fPoint1[1] <= node->m_vCenter.y+node->m_Width/2.0f+0.00001f && 
				tri->fPoint1[1] >= node->m_vCenter.y-node->m_Width/2.0f-0.00001f && 
				tri->fPoint1[2] <= node->m_vCenter.z+node->m_Width/2.0f+0.00001f && 
				tri->fPoint1[2] >= node->m_vCenter.z-node->m_Width/2.0f-0.00001f) || 
				(tri->fPoint2[0] <= node->m_vCenter.x+node->m_Width/2.0f+0.00001f && 
				tri->fPoint2[0] >= node->m_vCenter.x-node->m_Width/2.0f-0.00001f && 
				tri->fPoint2[1] <= node->m_vCenter.y+node->m_Width/2.0f+0.00001f && 
				tri->fPoint2[1] >= node->m_vCenter.y-node->m_Width/2.0f-0.00001f && 
				tri->fPoint2[2] <= node->m_vCenter.z+node->m_Width/2.0f+0.00001f && 
				tri->fPoint2[2] >= node->m_vCenter.z-node->m_Width/2.0f-0.00001f) || 
				(tri->fPoint3[0] <= node->m_vCenter.x+node->m_Width/2.0f+0.00001f && 
				tri->fPoint3[0] >= node->m_vCenter.x-node->m_Width/2.0f-0.00001f && 
				tri->fPoint3[1] <= node->m_vCenter.y+node->m_Width/2.0f+0.00001f && 
				tri->fPoint3[1] >= node->m_vCenter.y-node->m_Width/2.0f-0.00001f && 
				tri->fPoint3[2] <= node->m_vCenter.z+node->m_Width/2.0f+0.00001f && 
				tri->fPoint3[2] >= node->m_vCenter.z-node->m_Width/2.0f-0.00001f)) 
				return 1; 
 
			//三角形平面方程 
			float tri_a, tri_b, tri_c, tri_d; 
			CVector3 triangle[3] = { {tri->fPoint1[0], tri->fPoint1[1], tri->fPoint1[2]},  
									 {tri->fPoint2[0], tri->fPoint2[1], tri->fPoint2[2]}, 
									 {tri->fPoint3[0], tri->fPoint3[1], tri->fPoint3[2]} }; 
			CVector3 nor = {tri->fNormal[0], tri->fNormal[1], tri->fNormal[2]}; 
			tri_a = nor.x; tri_b = nor.y; tri_c = nor.z; 
			tri_d = PlaneDistance(nor, triangle[0]); 
 
 
			float cube_center_tri = tri_a * node->m_vCenter.x + tri_b * node->m_vCenter.y + tri_c * node->m_vCenter.z + tri_d; 
			if(fabs(cube_center_tri) > node->m_Width) 
			{ 
				tri = tri->next; 
				continue; 
			}			 
			else 
			{ 
				//三角形有可能和立方体相交,结果取决于立方体的12条边和三角形的相交情况 
				CVector3 cubeside[12][2] = {{ {node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f}, 
											{node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f} 
											},	//前面的四条边 
											{ {node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f}, 
											{node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f}  
											},	// 
											{ {node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f}, 
											{node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f} 
											},	// 
											{ {node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f}, 
											{node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f} 
											},	// 
 
											{ {node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f}, 
											{node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f} 
											},	//后面的四条边 
											{ {node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f}, 
											{node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f}  
											},	// 
											{ {node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f}, 
											{node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f} 
											},	// 
											{ {node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f}, 
											{node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f} 
											},	// 
 
											{ {node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f}, 
											{node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f} 
											},	//左侧面的两条边 
											{ {node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f}, 
											{node->m_vCenter.x-node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f}  
											},	// 
											{ {node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f}, 
											{node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y+node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f} 
											},	//右侧面的两条边 
											{ {node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z-node->m_Width/2.0f}, 
											{node->m_vCenter.x+node->m_Width/2.0f, node->m_vCenter.y-node->m_Width/2.0f, node->m_vCenter.z+node->m_Width/2.0f} 
											} 
										}; 
				for(int kk=0; kk<12; kk++) 
				{ 
					bool m_binter = IntersectedPolygon2(triangle, nor, cubeside[kk], tri_d);//(triangle, cubeside[kk], 3); 
					if(m_binter) 
						return 1; 
				} 
			} 
			tri = tri->next; 
		} 
	return 0; 
}