#ifndef N_SPHERE_H #define N_SPHERE_H //------------------------------------------------------------------------------ /** a sphere in 3d space @author - RadonLabs GmbH @since - 2005.7.06 @remarks - Áö¿Ï Ãß°¡ */ #include "vector.h" #include "bbox.h" //------------------------------------------------------------------- class sphere { public: vector3 p; // position float r; // radius //--- constructors ---------------------------------------------- sphere() : r(1.0f) {}; sphere(const vector3& _p, float _r) : p(_p), r(_r) {}; sphere(const sphere& s) : p(s.p), r(s.r) {}; sphere(float _x, float _y, float _z, float _r) : r(_r) { p.set(_x,_y,_z); }; //--- set position and radius --- void set(const vector3& _p, float _r) { p = _p; r = _r; }; void set(float _x, float _y, float _z, float _r) { p.set(_x, _y, _z); r = _r; }; //--- check if 2 spheres overlap, without contact point --------- bool intersects(const sphere& s) const { vector3 d(s.p-p); float rsum = s.r+r; if (d.lensquared() <= (rsum*rsum)) return true; else return false; }; /** @brief Check if sphere intersects with box. Taken from "Simple Intersection Tests For Games", Gamasutra, Oct 18 1999 */ bool intersects(const bbox3& box) const { float s, d = 0; // find the square of the distance // from the sphere to the box, if (p.x < box.vmin.x) { s = p.x - box.vmin.x; d += s*s; } else if (p.x > box.vmax.x) { s = p.x - box.vmax.x; d += s*s; } if (p.y < box.vmin.y) { s = p.y - box.vmin.y; d += s*s; } else if (p.y > box.vmax.y) { s = p.y - box.vmax.y; d += s*s; } if (p.z < box.vmin.z) { s = p.z - box.vmin.z; d += s*s; } else if (p.z > box.vmax.z) { s = p.z - box.vmax.z; d += s*s; } return d <= r*r; } //--- check if 2 moving spheres have contact -------------------- //--- taken from "Simple Intersection Tests For Games" ---------- //--- article in Gamasutra, Oct 18 1999 ------------------------- bool intersect_sweep(const vector3& va, // in: distance travelled by 'this' const sphere& sb, // in: the other sphere const vector3& vb, // in: distance travelled by 'sb' float& u0, // out: normalized intro contact u0 float& u1) // out: normalized outro contact u1 { vector3 vab(vb - va); vector3 ab(sb.p - p); float rab = r + sb.r; // check if spheres are currently overlapping... if ((ab % ab) <= (rab*rab)) { u0 = 0.0f; u1 = 0.0f; return true; } else { // check if they hit each other float a = vab % vab; if ((a<-TINY) || (a>+TINY)) { // if a is '0' then the objects don't move relative to each other float b = (vab % ab) * 2.0f; float c = (ab % ab) - (rab * rab); float q = b*b - 4*a*c; if (q >= 0.0f) { // 1 or 2 contacts float sq = (float) sqrt(q); float d = 1.0f / (2.0f*a); float r1 = (-b + sq) * d; float r2 = (-b - sq) * d; if (r1 < r2) { u0 = r1; u1 = r2; } else { u0 = r2; u1 = r1; } return true; } else return false; } else return false; } }; }; //------------------------------------------------------------------- #endif