30{
31 Math::Vector3D oc = ray.origin -
_apex;
33 k = k * k;
34
35 double dx = ray.direction.x;
36 double dy = ray.direction.y;
37 double dz = ray.direction.z;
41
42 double a = dx * dx + dz * dz - k * dy * dy;
43 double b = 2 * (ox * dx + oz * dz - k * oy * dy);
44 double c = ox * ox + oz * oz - k * oy * oy;
45
46 double discriminant = b * b - 4 * a * c;
47 if (discriminant < 0)
48 return false;
49
50 double sqrtDisc = std::sqrt(discriminant);
51 double t0 = (-b - sqrtDisc) / (2 * a);
52 double t1 = (-b + sqrtDisc) / (2 * a);
53
54 if (t0 > t1)
55 std::swap(t0, t1);
56
57 double y = oy + t0 * dy;
59 y = oy + t1 * dy;
61 return false;
62 t = t1;
63 } else {
64 t = t0;
65 }
66
67 hitPoint = ray.origin + ray.direction * t;
68
69 Math::Vector3D tmp = hitPoint -
_apex;
70 tmp.
y = -(k * std::sqrt(tmp.
x * tmp.
x + tmp.
z * tmp.
z));
71 double length = std::sqrt(tmp.
x * tmp.
x + tmp.
y * tmp.
y + tmp.
z * tmp.
z);
72 if (length != 0)
73 normal = tmp / length;
74 else
75 normal = tmp;
76
77 return true;
78}