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.

64 lines
2.4 KiB

  1. import Vector from './vector';
  2. import Intersection from './intersection';
  3. import Ray from './ray';
  4. /**
  5. * A class representing a sphere
  6. */
  7. export default class Sphere {
  8. public center: Vector;
  9. public radius: number;
  10. public color: Vector;
  11. /**
  12. * Creates a new Sphere with center and radius
  13. * @param center The center of the Sphere
  14. * @param radius The radius of the Sphere
  15. * @param color The color of the Sphere
  16. */
  17. constructor(
  18. center: Vector,
  19. radius: number,
  20. color: Vector
  21. ) {
  22. this.center = center;
  23. this.radius = radius;
  24. this.color = color;
  25. }
  26. /**
  27. * Calculates the intersection of the sphere with the given ray
  28. * @param ray The ray to intersect with
  29. * @return The intersection if there is one, null if there is none
  30. */
  31. intersect(ray: Ray): Intersection | null {
  32. // TODO: Calculate the quadratic equation for ray-sphere
  33. // TODO: intersection. You will need the origin of your ray as x0,
  34. // TODO: the ray direction, and the radius of the sphere.
  35. // TODO: Don't forget to translate your ray's starting position with
  36. // TODO: respect to the center of the sphere.
  37. // TODO: Calculate the discriminant c, and distinguish between the 3
  38. // TODO: possible outcomes: no hit, one hit, or two hits.
  39. // TODO: Return an Intersection or null if there was no hit. In case
  40. // TODO: of two hits, return the one closer to the start point of
  41. // TODO: the ray.
  42. let newCenter = ray.origin.sub(this.center);
  43. // hier oben noch nicht t berechenenm da c negativ sein kann und dann wurzel nicht funktioniert
  44. let c = Math.pow(newCenter.dot(ray.direction),2) - newCenter.dot(newCenter) + Math.pow(this.radius,2);
  45. if(c < 0) {
  46. return null;
  47. } else if(c == 0) {
  48. //PQ Formel
  49. let t1 = - newCenter.dot(ray.direction);
  50. return new Intersection(t1, newCenter.add(ray.direction.mul(t1)), (newCenter.add(ray.direction.mul(t1)).sub(this.center)).normalize() ); //schnittpunkt ist origin + direction * t
  51. } else {
  52. let t2 = - newCenter.dot(ray.direction) - Math.sqrt(c);
  53. return new Intersection(t2, newCenter.add(ray.direction.mul(t2)), (newCenter.add(ray.direction.mul(t2)).sub(this.center)).normalize() ); //schnittpunkt ist origin + direction * t
  54. }
  55. }
  56. }