A) Луч проходит мимо сферы; и
Рисунок 15.4. a) Луч проходит мимо сферы; и t0 и t1 мнимые числа б) Луч находится за сферой; и t0 и t1 отрицательные числа. в) Луч начинается внутри сферы; одно из решений положительное, а другое — отрицательное. Положительное решение соответствует единственной точке пересечения. г) Луч пересекает сферу; и t0 и t1 положительные числа. д) Луч касается сферы в единственной точке; в этом случае оба решения положительны и t0 = t1.
Приведенный ниже метод возвращает true, если переданный в первом параметре луч пересекает переданную во втором параметре сферу. Если луч проходит мимо сферы, метод возвращает false:
bool PickApp::raySphereIntersectionTest(Ray* ray, BoundingSphere* sphere) { D3DXVECTOR3 v = ray->_origin - sphere->_center;
float b = 2.0f * D3DXVec3Dot(&ray->_direction, &v); float c = D3DXVec3Dot(&v, &v) – (sphere->_radius * sphere->_radius);
// Находим дискриминант float discriminant = (b * b) - (4.0f * c);
// Проверяем на мнимые числа if(discriminant < 0.0f) return false;
discriminant = sqrtf(discriminant);
float s0 = (-b + discriminant) / 2.0f; float s1 = (-b - discriminant) / 2.0f;
// Если есть решение >= 0, луч пересекает сферу if(s0 >= 0.0f || s1 >= 0.0f) return true;
return false; }
Конечно, мы уже показывали объявление структуры BoundingSphere, но для удобства приведем его здесь еще раз:
struct BoundingSphere { BoundingSphere();
D3DXVECTOR3 _center; float _radius; };