Ray - Sphere Intersection

Aug 7, 2021 at 5:46pm
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
Aug 7, 2021 at 8:47pm
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 Aug 7, 2021 at 9:00pm
Aug 7, 2021 at 9:13pm
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.
Aug 7, 2021 at 9:52pm
Do you know how to use Quaternions ?
Aug 7, 2021 at 10:50pm
Aug 7, 2021 at 10:59pm
this exact question was posted and abandoned not long ago.
Aug 8, 2021 at 12:31am
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.
Aug 8, 2021 at 5:25am
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.
Aug 8, 2021 at 12:39pm
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.
Aug 8, 2021 at 12:43pm
dot() is a function taking 2 args. See L13
Aug 8, 2021 at 12:44pm
@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 Aug 8, 2021 at 1:03pm
Aug 8, 2021 at 2:14pm
I showed it to the teacher and she I had to do it different using quadratics or quaternions
Aug 8, 2021 at 2:34pm
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.
Aug 8, 2021 at 4:06pm
Regarding the dot product, there is std::inner_product :

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