bool KRTriangle3::containsPoint(const KRVector3 &p) const { /* // From: http://stackoverflow.com/questions/995445/determine-if-a-3d-point-is-within-a-triangle const float SMALL_NUM = 0.00000001f; // anything that avoids division overflow // KRVector3 A = m_c[0], B = m_c[1], C = m_c[2]; if (_sameSide(p, m_c[0], m_c[1], m_c[2]) && _sameSide(p, m_c[1], m_c[0], m_c[2]) && _sameSide(p, m_c[2], m_c[0], m_c[1])) { KRVector3 vc1 = KRVector3::Cross(m_c[0] - m_c[1], m_c[0] - m_c[2]); if(fabs(KRVector3::Dot(m_c[0] - p, vc1)) <= SMALL_NUM) { return true; } } return false; */ // From: http://blogs.msdn.com/b/rezanour/archive/2011/08/07/barycentric-coordinates-and-point-in-triangle-tests.aspx KRVector3 A = m_c[0]; KRVector3 B = m_c[1]; KRVector3 C = m_c[2]; KRVector3 P = p; // Prepare our barycentric variables KRVector3 u = B - A; KRVector3 v = C - A; KRVector3 w = P - A; KRVector3 vCrossW = KRVector3::Cross(v, w); KRVector3 vCrossU = KRVector3::Cross(v, u); // Test sign of r if (KRVector3::Dot(vCrossW, vCrossU) < 0) return false; KRVector3 uCrossW = KRVector3::Cross(u, w); KRVector3 uCrossV = KRVector3::Cross(u, v); // Test sign of t if (KRVector3::Dot(uCrossW, uCrossV) < 0) return false; // At this point, we know that r and t and both > 0. // Therefore, as long as their sum is <= 1, each must be less <= 1 float denom = uCrossV.magnitude(); float r = vCrossW.magnitude() / denom; float t = uCrossW.magnitude() / denom; return (r + t <= 1); }
bool _intersectSphere(const KRVector3 &start, const KRVector3 &dir, const KRVector3 &sphere_center, float sphere_radius, float &distance) { // dir must be normalized // From: http://archive.gamedev.net/archive/reference/articles/article1026.html // TODO - Move to another class? KRVector3 Q = sphere_center - start; float c = Q.magnitude(); float v = KRVector3::Dot(Q, dir); float d = sphere_radius * sphere_radius - (c * c - v * v); if(d < 0.0) { // No intersection return false; } // Return the distance to the [first] intersecting point distance = v - sqrt(d); if(distance < 0.0f) { return false; } return true; }