Ray - Sphere Intersection

Can someone help me get the Ray - Sphere Intersections formula using quadratics?
It's for my homework and I'm having problems finding the answers.

This is the rubric:
https://drive.google.com/file/d/14lfNeFsC8FPHl1Y02VlygL8uEURjG-G7/view?usp=sharing
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <cmath>
using namespace std;

//======================================================================

struct Pt { double x, y, z; };

Pt operator + ( Pt p, Pt q )     { return { p.x + q.x, p.y + q.y, p.z + q.z }; }
Pt operator - ( Pt p, Pt q )     { return { p.x - q.x, p.y - q.y, p.z - q.z }; }
Pt operator * ( double r, Pt p ) { return {   r * p.x,   r * p.y,   r * p.z }; }
Pt operator / ( Pt p, double r ) { return {   p.x / r,   p.y / r,   p.z / r }; }
double dot( Pt p, Pt q ) { return p.x * q.x + p.y * q.y + p.z * q.z; }
ostream &operator << ( ostream &out, const Pt &p ) { return out << p.x << " " << p.y << " " << p.z; }
istream &operator >> ( istream &in ,       Pt &p ) { return in  >> p.x        >> p.y        >> p.z; }

//======================================================================

int main()
{
   Pt centre, origin, direction;
   double radius;

   cout << "Enter sphere centre (vector): ";   cin >> centre;
   cout << "Enter sphere radius: "         ;   cin >> radius;
   cout << "Enter ray origin (vector): "   ;   cin >> origin;
   cout << "Enter ray direction (vector): ";   cin >> direction;

   // t satisfies a quadratic
   double a = dot( direction, direction );
   double b = 2 * dot( direction, origin - centre );
   double c = dot( origin - centre, origin - centre ) - radius * radius;
   double discriminant = b * b - 4 * a * c;

   if ( discriminant < 0 )
   {
      cout << "No intersection.\n";
   }
   else if ( discriminant > 0 )
   {
      double t = ( -b + sqrt( discriminant ) ) / ( 2 * a );
      double t2 = -b / a - t;
      if ( abs( t2 ) < abs( t ) ) t = t2;
      cout << "Closest intersection at " << origin + t * direction << '\n';
   }
   else
   {
      cout << "Touches sphere at " << origin + (-0.5 * b / a) * direction << '\n';
   }
}


Enter sphere centre (vector): 0 0 0 
Enter sphere radius: 5
Enter ray origin (vector): 2 -1 -1
Enter ray direction (vector): 0 2 3
Closest intersection at 2 -2.76807 -3.6521
Last edited on
This exercise points up the "ooops!" factor that C++ has a contiguous, at runtime variable-sized container named the same (ignoring std::) as a mathematical quantity that not only describes the magnitude but also describes the movement of an object or the position of an object with respect to another point or object.

</rant>

Back to your regularly scheduled C++ programming channel.
Do you know how to use Quaternions ?
this exact question was posted and abandoned not long ago.
This exercise points up the "ooops!" factor that C++ has a contiguous, at runtime variable-sized container named the same (ignoring std::) as a mathematical quantity that not only describes the magnitude but also describes the movement of an object or the position of an object with respect to another point or object.
"Vector" is a perfectly appropriate name, since like mathematical vectors, std::vectors are ordered (two vectors with the same elements in different orders are not equal) and homogeneous (all elements are of the same type). The fact you wouldn't use an std::vector to store a vector (unless it had many or unknown dimensions), or that the class doesn't implement any vector operations, isn't terribly relevant as far as the appropriateness of the name goes.
I have the feeling that the OP doesn’t know the difference between quadratics and quaternions.

I have no idea why he would want the latter here.
lastchance wrote:
1
2
3
 double a = dot( direction, direction );
   double b = 2 * dot( direction, origin - centre );
   double c = dot( origin - centre, origin - centre ) - radius * radius;

I'm not familiar with this way of calling methods. It looks like it's the same as:
1
2
3
double a = direction.dot(direction);
double b = 2*direction.dot(origin - center);
double c = (origin-centre).dot(origin-centre) - radius * radius;

is that right? Can you point me at a reference for this type of call?

Thanks.
dot() is a function taking 2 args. See L13
@dhayden,
I defined the dot() function at the top of the code. It just does a dot product (scalar product) on structs representing 3-d points.

Since it's symmetric I chose not to make it a type-bound procedure ("method"), that's all. This just seemed more natural (to me). I've no idea which, if either, is more computationally efficient.

In other languages you can define and name your own operators, so looking more like the mathematics:
a .dot. b
However, you can't do that in c++ and you are stuck with the predefined names or symbols for operators. OK for the cross product, but not really for the dot product.
Last edited on
I showed it to the teacher and she I had to do it different using quadratics or quaternions
I showed it to the teacher and she I had to do it different using quadratics or quaternions

Then we can presume that she has taught you quadratics and quaternions so that you are the expert on the topic.
Regarding the dot product, there is std::inner_product :

https://en.cppreference.com/w/cpp/algorithm/inner_product
My bad. I thought dot() and the others were part of struct Pt. Doh!
Topic archived. No new replies allowed.