#include "munga.h" #pragma hdrstop #include "plane.h" #include "sphere.h" #include "linmtrx.h" #include "extntbox.h" // //############################################################################# //############################################################################# // Plane::Plane( const Point3D& p0, const Point3D& p1, const Point3D& p2 ) { Vector3D v1,v2; v1.Subtract(p1, p0); v2.Subtract(p2, p1); Vector3D axis; axis.Cross(v1, v2); Verify(!Small_Enough(axis.Length())); normal = axis; offset = -(normal * p0); Verify(Small_Enough(DistanceTo(p1))); Verify(Small_Enough(DistanceTo(p2))); Check_Fpu(); } // //############################################################################# //############################################################################# // Plane& Plane::Multiply( const Plane &p, const LinearMatrix &m ) { Check_Pointer(this); Check(&p); Check(&m); normal.x = p.normal.x*m(0,0) + p.normal.y*m(1,0) + p.normal.z*m(2,0); normal.y = p.normal.x*m(0,1) + p.normal.y*m(1,1) + p.normal.z*m(2,1); normal.z = p.normal.x*m(0,2) + p.normal.y*m(1,2) + p.normal.z*m(2,2); offset = p.normal.x*m(3,0) + p.normal.y*m(3,1) + p.normal.z*m(3,2) + p.offset; return *this; } // //############################################################################# //############################################################################# // Logical Plane::Contains(const Point3D &point) const { return normal * point <= offset; } // //############################################################################# //############################################################################# // Logical Plane::ContainsSomeOf(const Sphere &sphere) const { return normal*sphere.center - offset <= sphere.radius; } // //############################################################################# //############################################################################# // Logical Plane::ContainsAllOf(const Sphere &sphere) const { return offset - normal*sphere.center >= sphere.radius; } // //############################################################################# //############################################################################# // Logical Plane::ContainsSomeOf(const ExtentBox &box) const { Check(this); Check(&box); Point3D test; test.x = (normal.x > 0.0f) ? box.minX : box.maxX; test.y = (normal.y > 0.0f) ? box.minY : box.maxY; test.z = (normal.z > 0.0f) ? box.minZ : box.maxZ; return Contains(test); } // //############################################################################# //############################################################################# // Logical Plane::ContainsAllOf(const ExtentBox &box) const { Check(this); Check(&box); Point3D test; test.x = (normal.x < 0.0f) ? box.minX : box.maxX; test.y = (normal.y < 0.0f) ? box.minY : box.maxY; test.z = (normal.z < 0.0f) ? box.minZ : box.maxZ; return Contains(test); } // //############################################################################# //############################################################################# // Logical Plane::Intersect(const Sphere &sphere) const { Scalar dist = normal*sphere.center - offset; return Abs(dist) <= sphere.radius; } // //############################################################################# //############################################################################# // Logical Plane::Intersect(const ExtentBox &box) const { if (!ContainsSomeOf(box)) { return False; } Plane inverse(-normal.x, -normal.y, -normal.z, -offset); return inverse.ContainsSomeOf(box); } // //############################################################################# //############################################################################# // std::ostream& operator<<(std::ostream& Stream, const Plane &A_Plane) { Stream << "\n\tPlane Normal: " << A_Plane.normal; return Stream << "\n\tOffset: " << -A_Plane.offset; } // //########################################################################### //########################################################################### // Logical Plane::TestInstance() const { return True; } Scalar Plane::CalculateX(Scalar y, Scalar z) { Check(this); Verify(!Small_Enough(normal.x)); Scalar result = (offset - y*normal.y - z*normal.z)/normal.x; Check_Fpu(); return result; } Scalar Plane::CalculateY(Scalar x, Scalar z) { Check(this); Verify(!Small_Enough(normal.y)); Scalar result = (offset - x*normal.x - z*normal.z)/normal.y; Check_Fpu(); return result; } Scalar Plane::CalculateZ(Scalar x, Scalar y) { Check(this); Verify(!Small_Enough(normal.z)); Scalar result = (offset - x*normal.x - y*normal.y)/normal.z; Check_Fpu(); return result; }