<p>I have written a really basic ray tracer. It generates primary rays and sets the colour of the pixel to the colour of the object that I have set myself. The code for which can be seen below.</p>

<pre><code>from PIL import Image, ImageDraw
from Sphere import Sphere
import numpy as np

imgx = 300
imgy = 300

img = Image.new('RGB', (imgx, imgy), color = 'black')
pixelMap = img.load()

#Place a Sphere in centre, distance 10 away.
#Sphere has a constructor (centre, colour, radius)
sphere1 = Sphere(np.array([0,0,-1]), (255, 255, 255), 100)
#sphere2 = Sphere(np.array([300,0,-1]), (255, 0, 0), 100)

objects = [sphere1]

for i in range(img.size[0]):
    for j in range(img.size[1]):

        u = -imgx/2 + (imgx)*(i+0.5)/imgx
        v = -imgy/2 + (imgy)*(j+0.5)/imgy

        rayDirection = -1*np.array([0,0,1]) + u*np.array([1,0,0]) + v*np.array([0,1,0])
        rayOrigin = np.array([0,0,0])
        #p(t) = rayorigin + t*raydirect

        #Sphere intersection
        for obj in objects:     
            a = np.dot(rayDirection, rayDirection)
            b = np.dot(2*rayDirection, (rayOrigin - obj.centre))
            c = np.dot((rayOrigin - obj.centre), (rayOrigin - obj.centre)) - obj.radius**2

            eminc = rayOrigin - obj.centre

            discrim = (np.dot(rayDirection, eminc))**2 - ((np.dot(rayDirection, rayDirection))*(np.dot(eminc, eminc))-obj.radius**2)
            if(discrim &gt;= 0):
                print("intersect")
                pixelMap[i,j] = obj.colour
            else:
                pixelMap[i,j] = (0, 0,0)

img.save('output.png')
</code></pre>

<p><a href="https://i.sstatic.net/cDdocs.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/cDdocs.png" alt="enter image description here"></a></p>

<p>It works in the sense that when I run the code, I get an image of a white circle. My issue arises when I change the centre of the sphere. Instead of shifting to the left, right, up or down. I get a skewed image. Seen below when I set the Sphere to have centre <code>np.array([3,0,-1])</code>.</p>

<p><a href="https://i.sstatic.net/KqsPls.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/KqsPls.png" alt="enter image description here"></a></p>

<p>I believe the problem may be to do with the translation between world co-ordinates and camera co-ordinates? However, I am not sure what transformation matrix to use or how to use it. For what it's worth, my code takes ideas from Fundamentals of Computer Graphics by Pete Shirley and Steve Marschner.</p>

CC BY-SA 4.0
2019-07-15T13:34:24.510Z
`discrim = (np.dot(rayDirection, eminc))**2 - ((np.dot(rayDirection, rayDirection))*(np.dot(eminc, eminc))-obj.radius**2)`, use `discrim = b * b-4*a*c`
lightxbulb
CC BY-SA 4.0
2019-07-15T16:26:11.760Z
@lightxbulb discrim is equivalent to b^2-4ac with the values for a,b and c substituted in.
Tim
CC BY-SA 4.0
2019-07-15T18:37:41.120Z
It is not. It would be if you actually wrote `(np.dot(rayDirection, eminc))**2 - 4*((np.dot(rayDirection, rayDirection))*(np.dot(eminc, eminc)-obj.radius**2))`. So just put in `b * b - 4 * a * c`, and check whether it works.
lightxbulb
<raytracing><transformations>
Moving a sphere in a basic ray tracer
Tim
# Moving a sphere in a basic ray tracer

(Asked by: username_0 on 2019-07-14)

I have written a really basic ray tracer. It generates primary rays and sets the colour of the pixel to the colour of the object that I have set myself. The code for which can be seen below.

```
from PIL import Image, ImageDraw
from Sphere import Sphere
import numpy as np

imgx = 300
imgy = 300

img = Image.new('RGB', (imgx, imgy), color = 'black')
pixelMap = img.load()

#Place a Sphere in centre, distance 10 away.
#Sphere has a constructor (centre, colour, radius)
sphere1 = Sphere(np.array([0,0,-1]), (255, 255, 255), 100)
#sphere2 = Sphere(np.array([300,0,-1]), (255, 0, 0), 100)

objects = [sphere1]

for i in range(img.size[0]):
    for j in range(img.size[1]):

        u = -imgx/2 + (imgx)*(i+0.5)/imgx
        v = -imgy/2 + (imgy)*(j+0.5)/imgy

        rayDirection = -1*np.array([0,0,1]) + u*np.array([1,0,0]) + v*np.array([0,1,0])
        rayOrigin = np.array([0,0,0])
        #p(t) = rayorigin + t*raydirect

        #Sphere intersection
        for obj in objects:     
            a = np.dot(rayDirection, rayDirection)
            b = np.dot(2*rayDirection, (rayOrigin - obj.centre))
            c = np.dot((rayOrigin - obj.centre), (rayOrigin - obj.centre)) - obj.radius**2

            eminc = rayOrigin - obj.centre

            discrim = (np.dot(rayDirection, eminc))**2 - ((np.dot(rayDirection, rayDirection))*(np.dot(eminc, eminc))-obj.radius**2)
            if(discrim >= 0):
                print("intersect")
                pixelMap[i,j] = obj.colour
            else:
                pixelMap[i,j] = (0, 0,0)

img.save('output.png')

```

[![enter image description here](https://i.sstatic.net/cDdocs.png)](https://i.sstatic.net/cDdocs.png)

It works in the sense that when I run the code, I get an image of a white circle. My issue arises when I change the centre of the sphere. Instead of shifting to the left, right, up or down. I get a skewed image. Seen below when I set the Sphere to have centre `np.array([3,0,-1])`.

[![enter image description here](https://i.sstatic.net/KqsPls.png)](https://i.sstatic.net/KqsPls.png)

I believe the problem may be to do with the translation between world co-ordinates and camera co-ordinates? However, I am not sure what transformation matrix to use or how to use it. For what it's worth, my code takes ideas from Fundamentals of Computer Graphics by Pete Shirley and Steve Marschner.

**Tags:** raytracing, transformations

> **Comments:**
> **username_1**: `discrim = (np.dot(rayDirection, eminc))**2 - ((np.dot(rayDirection, rayDirection))*(np.dot(eminc, eminc))-obj.radius**2)`, use `discrim = b * b-4*a*c`  
> **username_0**: @username_1 discrim is equivalent to b^2-4ac with the values for a,b and c substituted in.  
> **username_1**: It is not. It would be if you actually wrote `(np.dot(rayDirection, eminc))**2 - 4*((np.dot(rayDirection, rayDirection))*(np.dot(eminc, eminc)-obj.radius**2))`. So just put in `b * b - 4 * a * c`, and check whether it works.  

---

## 0 answers

