You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
1.4 KiB

4 years ago
4 years ago
4 years ago
4 years ago
  1. #include "Sphere.h"
  2. #include"Ray.h"
  3. #include<math.h>
  4. Sphere::Sphere(const Vector3 & origin, float radius) {
  5. mOrigin = origin;
  6. mRadius = radius;
  7. }
  8. void Sphere::set(const Vector3 & origin, float radius)
  9. {
  10. mOrigin = origin;
  11. mRadius = radius;
  12. }
  13. bool Sphere::HitTest(const Ray& input_ray, float min_distance, float max_distance, HitPoint& hit_point) {
  14. Vector3 sphere_center_to_ray = input_ray.mOrigin - mOrigin;
  15. float a = Dot(input_ray.mDirection, input_ray.mDirection);
  16. float b = 2.0f * Dot(sphere_center_to_ray, input_ray.mDirection);
  17. float c = Dot(sphere_center_to_ray, sphere_center_to_ray) - mRadius * mRadius;
  18. float determinant = b * b - 4.0f * a * c;
  19. bool isHited = false;
  20. float distance = -1.0f;
  21. if (determinant > 0.0f) {
  22. distance = (-b - sqrtf(determinant))/ 2.0f *a;
  23. if (distance > min_distance && distance < max_distance) {
  24. isHited = true;
  25. }
  26. else {
  27. distance = (-b + sqrtf(determinant)) / 2.0f*a;
  28. if (distance > min_distance && distance < max_distance) {
  29. isHited = true;
  30. }
  31. }
  32. }
  33. else if (determinant == 0.0f) {
  34. distance = -b / (2.0f * a);
  35. if (distance > min_distance && distance < max_distance) {
  36. isHited = true;
  37. }
  38. }
  39. if (isHited) {
  40. hit_point.mPosition = input_ray.PointAt(distance);
  41. Vector3 normal = hit_point.mPosition - mOrigin;
  42. normal.Normalize();
  43. hit_point.mDistance = distance;
  44. hit_point.mNormal = normal;
  45. }
  46. return isHited;
  47. }