<p>I gave it a quick look and I found several places which need attention. First of all you forgot transforming the view space to NDC space.</p>

<p>We are working with 3 spaces. </p>

<p><strong>1)</strong> The world space, which is the global reference frame. You usually define spheres in this frame. Or if you are reading model data, you might want to multiply by a model matrix to bring them into world space.</p>

<p><strong>2)</strong> The camera space. This is the part of the world the camera views. The correct equation for generating rays in the camera space as i mentioned in the comments are given by.</p>

<p>$ x = l + (r-l)*(pixel_i * 0.5)/Width$</p>

<p>$ y = b + (t-b)*(pixel_y * 0.5)/Height$</p>

<p>$ z = -View Plane Distance$</p>

<p><strong>3)</strong> The third is the NDC space which is usually in the range $[-1,1]$ Some API's have this range in $[0,1]$ For ray tracing however, we are concerned with $[-1,1]$. The concept here is, imagine your whole image which is $Width \times Height$ to be mapped to a plane which is $2 \times 2$ units wide centered at the origin. This is somewhat a generalization. We don't need to mess with the width and height anymore. We introduced an intermediary space where everything is in the range [-1,1]. </p>

<p>However this is true only for square images. What happens when <code>width != height</code>?</p>

<p>Then we have to account for it by doing,</p>

<p>$ x = [-a, a]$</p>

<p>$ y = [-1, 1]$</p>

<p>Where $a$ is Aspect Ratio given by. </p>

<p>$ a = Width/Height $ </p>

<p>The NDC space is usually calcualted as,</p>

<p>$ x_{ndc} = [ (2 * ( i+ 0.5)/Width) - 1] * Aspect Ratio$</p>

<p>$ y_{ndc} = [ (2 * ( y+ 0.5)/Width) - 1]$</p>

<p>Note tho depending on the image coordinates, we might need to flip $y_{ndc}$. The calculation above assumes Image has the origin at the top left corner. If the origin is at the bottom left, we will need to flip.</p>

<p>However this assumes the camera is positioned at the origin. How do take into account for camera rotation and position. Normally this is done by the use of a camera matrix which transforms from world space to camera or vice versa. You calculate ray direction in the NDC space, multiply it by this matrix and then normalize it. I will not go into details about this one. </p>

<p>The way you are calculating the rays in camera space, haven't seen much like this but there is a simple fix to get a moving camera and transform it in NDC space. You divide by the width and height of the camera volume. So your equations become. </p>

<p>$ x = [l + (r-l)*(pixel_i * 0.5)/Width] / (r-l)$</p>

<p>$\therefore x = l/(r-l) + (pixel_i * 0.5)/Width $</p>

<p>$ y = [b + (t-b)*(pixel_y * 0.5)/Height] / (t-b)$</p>

<p>$\therefore y = b/(t-b) + (pixel_y * 0.5)/Height$</p>

<p>$ z = -View Plane Distance$</p>

<p>You don't need to account for aspect ratio in this scenario as it's already being done by $l/(r-l)$ and $b/(t-b)$ factors. </p>

<p>As for the proper way of intersecting spheres (if you are normalizing direction, which you should, would be)</p>

<pre><code> t = -1.0f;
 co = ray.origin - sphere.center // Note we subtract center FROM origin.
 b = dot(co, ray.dir);
 c = dot(co, co) - sphere.radius * sphere.radius;
 disc = b*b - c;
 if disc &gt;= 0
   t = -b + sqrt(disc); // wrong
   t = -b - sqrt(disc); // correct
 if ( t &gt;= 0)
 {
  ray.length = t;       /* you can add a length parameter in ray as 
                           direction is normalized
                           Set other parameters such as sphere id, or if 
                           there is only 1 sphere, set color here. */
  return true;
 }
 else
  return false;
</code></pre>

<p>Also forgot to mention your spheres $Z$ coordinates should be negative. Since rays are generating in the $-Z$ direction.</p>

<p>EDIT:- I corrected my sphere intersection. There was a mistake. To answer the questions in your comments.</p>

<p>1) About the spaces, scratchapixel seems to follow RenderMan's coordinate system. Since I'm more from an OpenGL background, I'll talk with that in mind.
When I talk about NDC space that equals scratchapixels's definition of screen space. </p>

<p>Screen space usually means screen/window coordinates which range from 0 to image width/height and that's why scratchapixel can be confusing sometimes.</p>

<p>2 and 3) About the sphere intersection and why rays need a length parameter. First of all rays are defined by this formula.</p>

<p>$ R = e + t*\hat{d}$</p>

<p>Where $e$ is the origin, $\hat{d}$ is the direction vector of that ray and $t$ is the length of that ray. In raytracing we initialize all our rays to have the length infinity. Then whenever we intersect anything, we set this $t$ parameter if it's less than the previous value. For the first time, the $t$ value is set to the distance to the first object hit. After that whenever we find that the same ray hits another object we compare the $t$ values to see which one is closer.</p>

<p>We can't directly set color by checking discriminant only because when a Ray interseccts a sphere it can be the case that it intersects at two points (when ray isn't tangent to the sphere). Both of these are given by,</p>

<p>$ t = -b + sqrt(disc)$</p>

<p>$ t = -b - sqrt(disc)$</p>

<p>However in the case for spheres, the closest point is always given by the second one. I mistakenly provided you the first one. </p>

<p>However this doesn't mean we dont have a view frustum. If we want we can define near and far planes to get a closed view frustum and initialize all rays with the <code>length = distance to far plane</code>. Then any objects farther than this far plane will not get intersected. In other words, <code>discriminant</code> will be greater than zero but the <code>t</code> check would fail.</p>

<p>Also I don't see where you have declared <code>window_width</code> in your code but make sure when dividing by <code>width</code> or <code>height</code> the division should have a float value in it (cast width/height into float if declared as int) other wise aspect ratio would be rounded off to an integer.</p>

<p>And try placing your sphere further in the -Z direction. Let's say <code>(0,0, -6)</code>.</p>

CC BY-SA 4.0
2018-08-29T16:07:54.963Z
Part 1/3: Thanks for your input, gallickgunner! As I tried to follow your answer and correct my mistakes in code, I also consulted the article on ray tracing from scratchapixel.com[1] since the different depictions/approaches of the involved coordinate systems confused me (they are different from Wolfgang Huerst's, Shirley's).
As you pointed out, I have forgotten to map to the NDC space and from there to the screen space (as [1] puts it).


[1]: https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-generating-camera-rays/generating-camera-rays
user9266
CC BY-SA 4.0
2018-08-29T16:08:10.757Z
Part 2/3: So I did this in the for loop where the pixels are handled (https://privatebin.net/?7546e951d5dbabd5#DeLXVUTGsVl7crnHU8D27rD54jsIuZrh/79nwplQjDo=).
The result I got is a black screen. Unexpectedly, The green sphere isn't appearing at all.
Furthermore I am not sure why the length parameter is needed. Also, what does t = -b + sqrt(disc) do? Why does the discrimant alone not suffice (the "intersection detector")?
user9266
CC BY-SA 4.0
2018-08-29T16:08:23.557Z
Part 3/3: 
So I need 3 spaces: world, camera, screen space.
The camera "sits" at the origin and shoots rays into the view plane.
Since I converted from NDC space to screen space already all I need to do is to construct a primary ray w/
the distance from the view plane and the x and y coordinates of the screen space.
Thus apparently there is no view frustum and the rays go to infinity.
Are the screen space and the camera space the same? What's the difference?
user9266
CC BY-SA 4.0
2018-08-29T16:13:24.357Z
Sorry, I forgott to disable the expiration: https://privatebin.net/?1db98377b85f2b0f#AOhpWXLhw5O9/zsYnMOsO7xT2mhdkRegbJGFGq2zTb0=
user9266
CC BY-SA 4.0
2018-08-29T17:52:03.040Z
@user9266 - edited my answer to add some details. brief ans is use `t = -b - sqrt(disc)` (Notice the negative) and when dividing by `window_width/height` cast it into float if saved as integer.
gallickgunner
CC BY-SA 4.0
2018-08-29T20:15:15.227Z
Thanks gallickgunner!
I still get a black screen though but it is porbably due to my code containing possible bugs as the c variable is always large such that the discriminant always is negative:
Engine.cpp: https://privatebin.net/?33ff3fde29662a09#OPcMukb068p0gmiXCdMwZU4vcufJjb4bEILhXratSp4=
Engine.hpp: https://privatebin.net/?aee6ed326fb190f0#JL6WE8Ofn8jzneHavld9S1qnIfmkv1Kr0gz03rXDZTo=
Ray3.hpp: https://privatebin.net/?9d8f33d689d65576#zDC7apSmzM2XmU+eeqEISGokgHtS/oRX16d9jbty4i4=
Vector3.hpp: https://privatebin.net/?4e44e7ff0cd268a5#c003Y7zoY7WOOyCYo4iZ/lqhBbNiIJrpxq27INeJmp4=
user9266
CC BY-SA 4.0
2018-08-29T20:16:03.073Z
Anyhow, thanks again for the explanation. It made the things more clear to me.
user9266
CC BY-SA 4.0
2018-08-29T21:21:47.833Z
@user9266 - you have a typo in your vector class, overloaded `-` operator. You are adding instead of subtracting.
gallickgunner
CC BY-SA 4.0
2018-08-29T21:43:36.157Z
gallickgunner: Wow!!! Thank you!!! Thank you very much!!! I get the sphere!!!! Thanks!!!

Result: https://i.imgur.com/XTODdLI.png
user9266
CC BY-SA 4.0
2018-08-29T21:46:09.873Z
Good to see the result xD
gallickgunner
CC BY-SA 4.0
2018-08-28T15:13:48.017Z
2018-08-29T19:22:14.090Z
2018-08-29T19:22:14.090Z
gallickgunner
<p>This picture depicts my current immagination of the coordinate systems involved in ray tracing:</p>

<p><img src="https://i.sstatic.net/eyUEh.png" alt="my current imagination of the coordinate systems involved"></p>

<p><strong>Explanation:</strong>
So the green rectangle is the [-0.5, nx-0.5] x [-0.5, ny-0.5] coordinate system and you can translate that coordinate system to the {u, v, w} coordinate system's coordinates (the world coordinate system) w/ the equations near the green rectangle.
<br>
From the origin of the world coordinate system, you can cast rays into the [l, r] x [b, t] coordinate system w/ the equation near the red rectangle ($s = e + u_{s} * u + v_{s} * v + w_{s} * w$).</p>

<p>The [-0.5, nx-0.5] x [-0.5, ny-0.5] matches a classic windowing systems coordinate sytem while the [l, r] x [b, t] seems to be the "ray tracer's screen"/"ray tracer's view area".
<br>
Both apparently define the view frustum depicted above. This however is counterintuitive for me since I expect the screen directly in front of the world coordinate system. So the screen I am seeing is the green rectangle, the [-0.5, nx-0.5] x [-0.5, ny-0.5]. That means everything goes backwards.</p>

<p><br><br></p>

<p><strong>The ray tracer algorithm in my own words (and with my current understanding):</strong></p>

<p>"Cause" the world space to shoot a ray so that it goes through each pixel of the window screen [-0.5, nx-0.5] x [-0.5, ny-0.5] and check for an intersection within the frustum along the way. If there is an intersection color it, if not leave it at the background color.
<br>
IOW: I am a "commander" and as I go through each pixel of [-0.5, nx-0.5] x [-0.5, ny-0.5] I cause the world space to shoot/cast a ray so that it goes through the pixel that I am currently at as well while checking for intersections within the frustum.</p>

<p><br><br></p>

<p>With my current understanding I tried to implement a ray tracer on the basis of a set_pixel() function.</p>

<p><br><br></p>

<p><strong>My implementation attempt (w/ a skewed green sphere as a result):</strong></p>

<pre><code>void game::Engine::run()
</code></pre>

<p>{   </p>

<pre><code>int nx = window_width; // 1366
int ny = window_heigth; // 768
// Construct the "ray tracer window"/"ray tracer screen"
int left = -200;
int right = 200;
int top = 100;
int bottom = -100;
int distance = 10;
// Create the {u, v, w} coordinate system
Vec3f e{ 0, 0, float(distance) };
Vec3f u{ 1, 0, 0 };
Vec3f v{ 0, 1, 0 };
Vec3f w{ 0, 0, float(distance) };
// Create the sphere
Vec3f center{ -50, -20, 11 };
float radius = 3.0f;

// Game loop
bool running{ true };
SDL_Event event{};
while (running)
{
    // Clear buffer
    SDL_SetRenderDrawColor(renderer, 153, 153, 153, 255);
    SDL_RenderClear(renderer);

    // Draw
    for (int i = 0; i &lt;= window_width; ++i) {
        for (int j = 0; j &lt; window_heigth; ++j) {
            // Calculate the scalar factors from the pixel position for each axis of the {u, v, w} coordinate system
            float u_s = (left + (right - left) * (i + 0.5)) / nx;
            float v_s = (bottom + (top - bottom) * (j + 0.5)) / ny;
            float w_s = -distance;
            // Cast a ray (in a perspective manner)
            Ray3f s{ e, u * u_s + v * v_s + w * w_s};
            Vec3f co = center - s.origin_vector;
            // Calculate the intersection between the sphere and the ray
            float a = Vec3f::dot_product(s.direction_vector, s.direction_vector);
            float b = 2 * Vec3f::dot_product(co, s.direction_vector);
            float c = Vec3f::dot_product(co, co) - radius * radius;
            float discriminant = b * b - 4 * a * c;
            Vec3f color_vec{ 0, 0, 0 }; // default background color
            if (discriminant &gt; 0)
            {
                // Make the hit sphere green
                color_vec.x = 0;
                color_vec.y = 1;
                color_vec.z = 0;
            }
            set_pixel(renderer, i, j, 255 * color_vec.x, 255 * color_vec.y, 255 * color_vec.z, 255);
        }
    }

    // Swap buffers
    SDL_RenderPresent(renderer);
    // Process event queue
    while (SDL_PollEvent(&amp;event))
    {
        switch (event.type)
        {
        case SDL_QUIT:
            running = false;
            break;
        }
    }
}
</code></pre>

<p>}</p>

<p><br><br>
<strong>The result:</strong>
<img src="https://i.sstatic.net/791eG.png" alt="result">
<br><br></p>

<p><strong>My conclusion:</strong>
I got the coordinate system totally wrong thus the skewed result.
So the window 1366 x 768 and the ray tracer's screen 400 x 200 as well as the world coordinate system that is spanned with the standard basis in the code doesn't lead to the expected result the sphere beeing on the center of the screen and not looking skewed. Plus, the coordinate system acts weird and seems to be arbitrary.
<br>
Thus something is fundamentally wrong with my current understanding.</p>

<p><strong>References:</strong>
<br>
<a href="https://www.youtube.com/watch?v=zQIvR_6IayM&amp;feature=youtu.be&amp;t=27m16s" rel="nofollow noreferrer">Lecture on ray tracing</a>
<br>
<a href="https://www.cs.utah.edu/~shirley/books/fcg2/rt.pdf" rel="nofollow noreferrer">Peter Shirley's treatise on ray tracing</a></p>

CC BY-SA 4.0
2018-08-28T13:21:33.230Z
Your sphere intersection is somewhat wrong as it doesn't test, the case of spheres on the back side of camera. Second the formula is `left + (right - left)*(i+0.5)/nx` Notice that `left` doesn't get divided by `nx`
gallickgunner
CC BY-SA 4.0
2018-08-28T13:30:31.923Z
Also always aim to normalize all your direction vectors unless you have a use for their magnitude. That simiplifies a lot of things such as intersection. You won't have to divde or multiply by `a`'s
gallickgunner
CC BY-SA 4.0
2018-08-28T14:38:03.910Z
Thanks for the input, gallickgunner!
I normalized all the involved vectors and I corrected the formulas as you suggested.
I don't know what exactly of my sphere intersection test is wrong.
The result is now that the entire window gets painted green.
Here is the code: https://privatebin.net/?080012578f6fb173#mvw2yi/yV3OwIAnEHj0EX7aXxjoAj9B75DPLkgsLbuk=
Here is the screenshot: https://s15.postimg.cc/x16akk6sb/Screenshot_RT_app_03.png
user9266
<raytracing>
Problem of understanding the coordinate systems involved in ray tracing
user9266
# Problem of understanding the coordinate systems involved in ray tracing

(Asked by: username_0 on 2018-08-28)

This picture depicts my current immagination of the coordinate systems involved in ray tracing:

![my current imagination of the coordinate systems involved](https://i.sstatic.net/eyUEh.png)

**Explanation:**
So the green rectangle is the [-0.5, nx-0.5] x [-0.5, ny-0.5] coordinate system and you can translate that coordinate system to the {u, v, w} coordinate system's coordinates (the world coordinate system) w/ the equations near the green rectangle.
  
From the origin of the world coordinate system, you can cast rays into the [l, r] x [b, t] coordinate system w/ the equation near the red rectangle ($s = e + u\_{s} \* u + v\_{s} \* v + w\_{s} \* w$).

The [-0.5, nx-0.5] x [-0.5, ny-0.5] matches a classic windowing systems coordinate sytem while the [l, r] x [b, t] seems to be the "ray tracer's screen"/"ray tracer's view area".
  
Both apparently define the view frustum depicted above. This however is counterintuitive for me since I expect the screen directly in front of the world coordinate system. So the screen I am seeing is the green rectangle, the [-0.5, nx-0.5] x [-0.5, ny-0.5]. That means everything goes backwards.

**The ray tracer algorithm in my own words (and with my current understanding):**

"Cause" the world space to shoot a ray so that it goes through each pixel of the window screen [-0.5, nx-0.5] x [-0.5, ny-0.5] and check for an intersection within the frustum along the way. If there is an intersection color it, if not leave it at the background color.
  
IOW: I am a "commander" and as I go through each pixel of [-0.5, nx-0.5] x [-0.5, ny-0.5] I cause the world space to shoot/cast a ray so that it goes through the pixel that I am currently at as well while checking for intersections within the frustum.

With my current understanding I tried to implement a ray tracer on the basis of a set\_pixel() function.

**My implementation attempt (w/ a skewed green sphere as a result):**

```
void game::Engine::run()

```

{

```
int nx = window_width; // 1366
int ny = window_heigth; // 768
// Construct the "ray tracer window"/"ray tracer screen"
int left = -200;
int right = 200;
int top = 100;
int bottom = -100;
int distance = 10;
// Create the {u, v, w} coordinate system
Vec3f e{ 0, 0, float(distance) };
Vec3f u{ 1, 0, 0 };
Vec3f v{ 0, 1, 0 };
Vec3f w{ 0, 0, float(distance) };
// Create the sphere
Vec3f center{ -50, -20, 11 };
float radius = 3.0f;

// Game loop
bool running{ true };
SDL_Event event{};
while (running)
{
    // Clear buffer
    SDL_SetRenderDrawColor(renderer, 153, 153, 153, 255);
    SDL_RenderClear(renderer);

    // Draw
    for (int i = 0; i <= window_width; ++i) {
        for (int j = 0; j < window_heigth; ++j) {
            // Calculate the scalar factors from the pixel position for each axis of the {u, v, w} coordinate system
            float u_s = (left + (right - left) * (i + 0.5)) / nx;
            float v_s = (bottom + (top - bottom) * (j + 0.5)) / ny;
            float w_s = -distance;
            // Cast a ray (in a perspective manner)
            Ray3f s{ e, u * u_s + v * v_s + w * w_s};
            Vec3f co = center - s.origin_vector;
            // Calculate the intersection between the sphere and the ray
            float a = Vec3f::dot_product(s.direction_vector, s.direction_vector);
            float b = 2 * Vec3f::dot_product(co, s.direction_vector);
            float c = Vec3f::dot_product(co, co) - radius * radius;
            float discriminant = b * b - 4 * a * c;
            Vec3f color_vec{ 0, 0, 0 }; // default background color
            if (discriminant > 0)
            {
                // Make the hit sphere green
                color_vec.x = 0;
                color_vec.y = 1;
                color_vec.z = 0;
            }
            set_pixel(renderer, i, j, 255 * color_vec.x, 255 * color_vec.y, 255 * color_vec.z, 255);
        }
    }

    // Swap buffers
    SDL_RenderPresent(renderer);
    // Process event queue
    while (SDL_PollEvent(&event))
    {
        switch (event.type)
        {
        case SDL_QUIT:
            running = false;
            break;
        }
    }
}

```

}

**The result:**
![result](https://i.sstatic.net/791eG.png)

**My conclusion:**
I got the coordinate system totally wrong thus the skewed result.
So the window 1366 x 768 and the ray tracer's screen 400 x 200 as well as the world coordinate system that is spanned with the standard basis in the code doesn't lead to the expected result the sphere beeing on the center of the screen and not looking skewed. Plus, the coordinate system acts weird and seems to be arbitrary.
  
Thus something is fundamentally wrong with my current understanding.

**References:**
  
[Lecture on ray tracing](https://www.youtube.com/watch?v=zQIvR_6IayM&feature=youtu.be&t=27m16s)
  
[Peter Shirley's treatise on ray tracing](https://www.cs.utah.edu/~shirley/books/fcg2/rt.pdf)

**Tags:** raytracing

> **Comments:**
> **username_1**: Your sphere intersection is somewhat wrong as it doesn't test, the case of spheres on the back side of camera. Second the formula is `left + (right - left)*(i+0.5)/nx` Notice that `left` doesn't get divided by `nx`  
> **username_1**: Also always aim to normalize all your direction vectors unless you have a use for their magnitude. That simiplifies a lot of things such as intersection. You won't have to divde or multiply by `a`'s  
> **username_0**: Thanks for the input, username_1! I normalized all the involved vectors and I corrected the formulas as you suggested. I don't know what exactly of my sphere intersection test is wrong. The result is now that the entire window gets painted green. Here is the code: https://privatebin.net/?080012578f6fb173#mvw2yi/yV3OwIAnEHj0EX7aXxjoAj9B75DPLkgsLbuk= Here is the screenshot: https://s15.postimg.cc/x16akk6sb/Screenshot_RT_app_03.png  

---

## 1 answers

### Answer by username_1 on 2018-08-28. Score: 2 | Accepted answer

I gave it a quick look and I found several places which need attention. First of all you forgot transforming the view space to NDC space.

We are working with 3 spaces.

**1)** The world space, which is the global reference frame. You usually define spheres in this frame. Or if you are reading model data, you might want to multiply by a model matrix to bring them into world space.

**2)** The camera space. This is the part of the world the camera views. The correct equation for generating rays in the camera space as i mentioned in the comments are given by.

$ x = l + (r-l)\*(pixel\_i \* 0.5)/Width$

$ y = b + (t-b)\*(pixel\_y \* 0.5)/Height$

$ z = -View Plane Distance$

**3)** The third is the NDC space which is usually in the range $[-1,1]$ Some API's have this range in $[0,1]$ For ray tracing however, we are concerned with $[-1,1]$. The concept here is, imagine your whole image which is $Width \times Height$ to be mapped to a plane which is $2 \times 2$ units wide centered at the origin. This is somewhat a generalization. We don't need to mess with the width and height anymore. We introduced an intermediary space where everything is in the range [-1,1].

However this is true only for square images. What happens when `width != height`?

Then we have to account for it by doing,

$ x = [-a, a]$

$ y = [-1, 1]$

Where $a$ is Aspect Ratio given by.

$ a = Width/Height $

The NDC space is usually calcualted as,

$ x\_{ndc} = [ (2 \* ( i+ 0.5)/Width) - 1] \* Aspect Ratio$

$ y\_{ndc} = [ (2 \* ( y+ 0.5)/Width) - 1]$

Note tho depending on the image coordinates, we might need to flip $y\_{ndc}$. The calculation above assumes Image has the origin at the top left corner. If the origin is at the bottom left, we will need to flip.

However this assumes the camera is positioned at the origin. How do take into account for camera rotation and position. Normally this is done by the use of a camera matrix which transforms from world space to camera or vice versa. You calculate ray direction in the NDC space, multiply it by this matrix and then normalize it. I will not go into details about this one.

The way you are calculating the rays in camera space, haven't seen much like this but there is a simple fix to get a moving camera and transform it in NDC space. You divide by the width and height of the camera volume. So your equations become.

$ x = [l + (r-l)\*(pixel\_i \* 0.5)/Width] / (r-l)$

$\therefore x = l/(r-l) + (pixel\_i \* 0.5)/Width $

$ y = [b + (t-b)\*(pixel\_y \* 0.5)/Height] / (t-b)$

$\therefore y = b/(t-b) + (pixel\_y \* 0.5)/Height$

$ z = -View Plane Distance$

You don't need to account for aspect ratio in this scenario as it's already being done by $l/(r-l)$ and $b/(t-b)$ factors.

As for the proper way of intersecting spheres (if you are normalizing direction, which you should, would be)

```
 t = -1.0f;
 co = ray.origin - sphere.center // Note we subtract center FROM origin.
 b = dot(co, ray.dir);
 c = dot(co, co) - sphere.radius * sphere.radius;
 disc = b*b - c;
 if disc >= 0
   t = -b + sqrt(disc); // wrong
   t = -b - sqrt(disc); // correct
 if ( t >= 0)
 {
  ray.length = t;       /* you can add a length parameter in ray as 
                           direction is normalized
                           Set other parameters such as sphere id, or if 
                           there is only 1 sphere, set color here. */
  return true;
 }
 else
  return false;

```

Also forgot to mention your spheres $Z$ coordinates should be negative. Since rays are generating in the $-Z$ direction.

EDIT:- I corrected my sphere intersection. There was a mistake. To answer the questions in your comments.

1) About the spaces, scratchapixel seems to follow RenderMan's coordinate system. Since I'm more from an OpenGL background, I'll talk with that in mind.
When I talk about NDC space that equals scratchapixels's definition of screen space.

Screen space usually means screen/window coordinates which range from 0 to image width/height and that's why scratchapixel can be confusing sometimes.

2 and 3) About the sphere intersection and why rays need a length parameter. First of all rays are defined by this formula.

$ R = e + t\*\hat{d}$

Where $e$ is the origin, $\hat{d}$ is the direction vector of that ray and $t$ is the length of that ray. In raytracing we initialize all our rays to have the length infinity. Then whenever we intersect anything, we set this $t$ parameter if it's less than the previous value. For the first time, the $t$ value is set to the distance to the first object hit. After that whenever we find that the same ray hits another object we compare the $t$ values to see which one is closer.

We can't directly set color by checking discriminant only because when a Ray interseccts a sphere it can be the case that it intersects at two points (when ray isn't tangent to the sphere). Both of these are given by,

$ t = -b + sqrt(disc)$

$ t = -b - sqrt(disc)$

However in the case for spheres, the closest point is always given by the second one. I mistakenly provided you the first one.

However this doesn't mean we dont have a view frustum. If we want we can define near and far planes to get a closed view frustum and initialize all rays with the `length = distance to far plane`. Then any objects farther than this far plane will not get intersected. In other words, `discriminant` will be greater than zero but the `t` check would fail.

Also I don't see where you have declared `window_width` in your code but make sure when dividing by `width` or `height` the division should have a float value in it (cast width/height into float if declared as int) other wise aspect ratio would be rounded off to an integer.

And try placing your sphere further in the -Z direction. Let's say `(0,0, -6)`.

> **Comments:**
> **username_0**: Part 1/3: Thanks for your input, username_1! As I tried to follow your answer and correct my mistakes in code, I also consulted the article on ray tracing from scratchapixel.com[1] since the different depictions/approaches of the involved coordinate systems confused me (they are different from Wolfgang Huerst's, Shirley's). As you pointed out, I have forgotten to map to the NDC space and from there to the screen space (as [1] puts it).   [1]: https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-generating-camera-rays/generating-camera-rays  
> **username_0**: Part 2/3: So I did this in the for loop where the pixels are handled (https://privatebin.net/?7546e951d5dbabd5#DeLXVUTGsVl7crnHU8D27rD54jsIuZrh/79nwplQjDo=). The result I got is a black screen. Unexpectedly, The green sphere isn't appearing at all. Furthermore I am not sure why the length parameter is needed. Also, what does t = -b + sqrt(disc) do? Why does the discrimant alone not suffice (the "intersection detector")?  
> **username_0**: Part 3/3:  So I need 3 spaces: world, camera, screen space. The camera "sits" at the origin and shoots rays into the view plane. Since I converted from NDC space to screen space already all I need to do is to construct a primary ray w/ the distance from the view plane and the x and y coordinates of the screen space. Thus apparently there is no view frustum and the rays go to infinity. Are the screen space and the camera space the same? What's the difference?  
> **username_0**: Sorry, I forgott to disable the expiration: https://privatebin.net/?1db98377b85f2b0f#AOhpWXLhw5O9/zsYnMOsO7xT2mhdkRegbJGFGq2zTb0=  
> **username_1**: @username_0 - edited my answer to add some details. brief ans is use `t = -b - sqrt(disc)` (Notice the negative) and when dividing by `window_width/height` cast it into float if saved as integer.  
> **username_0**: Thanks username_1! I still get a black screen though but it is porbably due to my code containing possible bugs as the c variable is always large such that the discriminant always is negative: Engine.cpp: https://privatebin.net/?33ff3fde29662a09#OPcMukb068p0gmiXCdMwZU4vcufJjb4bEILhXratSp4= Engine.hpp: https://privatebin.net/?aee6ed326fb190f0#JL6WE8Ofn8jzneHavld9S1qnIfmkv1Kr0gz03rXDZTo= Ray3.hpp: https://privatebin.net/?9d8f33d689d65576#zDC7apSmzM2XmU+eeqEISGokgHtS/oRX16d9jbty4i4= Vector3.hpp: https://privatebin.net/?4e44e7ff0cd268a5#c003Y7zoY7WOOyCYo4iZ/lqhBbNiIJrpxq27INeJmp4=  
> **username_0**: Anyhow, thanks again for the explanation. It made the things more clear to me.  
> **username_1**: @username_0 - you have a typo in your vector class, overloaded `-` operator. You are adding instead of subtracting.  
> **username_0**: username_1: Wow!!! Thank you!!! Thank you very much!!! I get the sphere!!!! Thanks!!!  Result: https://i.imgur.com/XTODdLI.png  
> **username_1**: Good to see the result xD  

---

