This is my first self-guided programming project, and all the math used in the program is self-taught. I wanted to get a better understanding of how computer graphics worked, but I just feel more confused. Please tell me what I could do better in my next attempt programming something like this and how to learn more. Note: if you are running this code, it's not broken but takes about 40 seconds for the image to be drawn.
import math
import turtle
window = turtle.Screen()
window.title("My Window")
window.bgcolor(0.65, 0.65, 0.65)
window.tracer(0)
window.setup(width=1200, height=500)
turtle = turtle.Turtle()
turtle.hideturtle()
turtle.speed(0)
turtle.pencolor(1, 0, 0)
turtle.pensize(0.001)
light = [60, 60, -50]
sphere = [0, 0, 101]
floorLevel = 100
radius = 100
camera = [0, 0, -100]
pixel = [20, 20, 0]
def checkIntersections_sphere(camera, pixel, sphere, radius):
global point_of_contact
point_of_contact = []
a = (
(pixel[0] - camera[0]) ** 2
+ (pixel[1] - camera[1]) ** 2
+ (pixel[2] - camera[2]) ** 2
)
b = (-1 * 2) * (
(pixel[0] - camera[0]) * (sphere[0] - camera[0])
+ (pixel[1] - camera[1]) * (sphere[1] - camera[1])
+ (sphere[2] - camera[2]) * (pixel[2] - camera[2])
)
c = (
(sphere[0] - camera[0]) ** 2
+ (sphere[1] - camera[1]) ** 2
+ (sphere[2] - camera[2]) ** 2
- radius**2
)
d = b**2 - 4 * a * c
if d < 0:
point_of_contact = []
return False
else:
if d == 0:
solution_1 = (-b - math.sqrt(d)) / (2 * a)
point_of_contact = [
camera[0] + solution_1 * (pixel[0] - camera[0]),
camera[1] + solution_1 * (pixel[1] - camera[1]),
camera[2] + solution_1 * (pixel[2] - camera[2]),
]
return True
else:
solution_1 = (-b - math.sqrt(d)) / (2 * a)
solution_2 = (-b + math.sqrt(d)) / (2 * a)
point_of_contact1 = [
camera[0] + solution_1 * (pixel[0] - camera[0]),
camera[1] + solution_1 * (pixel[1] - camera[1]),
camera[2] + solution_1 * (pixel[2] - camera[2]),
]
point_of_contact2 = [
camera[0] + solution_2 * (pixel[0] - camera[0]),
camera[1] + solution_2 * (pixel[1] - camera[1]),
camera[2] + solution_2 * (pixel[2] - camera[2]),
]
distance1 = math.sqrt(
(point_of_contact1[0] - camera[0]) ** 2
+ (point_of_contact1[1] - camera[1]) ** 2
+ (point_of_contact1[2] - camera[2]) ** 2
)
distance2 = math.sqrt(
(point_of_contact2[0] - camera[0]) ** 2
+ (point_of_contact2[1] - camera[1]) ** 2
+ (point_of_contact2[2] - camera[2]) ** 2
)
if distance1 < distance2:
point_of_contact = point_of_contact1
else:
point_of_contact = point_of_contact2
return True
def color(pixel, diffrence_in_angle, spector):
turtle.penup()
turtle.pencolor(1 - diffrence_in_angle, 0 + spector, 0 + spector)
turtle.goto(pixel[0], pixel[1])
turtle.dot()
turtle.pendown()
turtle.penup()
def getColor(sphere, point_of_contact):
global diffrence_in_angle
global spector
global spector_1
spector = 0
spector_1 = 0
normal_vector = [
point_of_contact[0] - sphere[0],
point_of_contact[1] - sphere[1],
point_of_contact[2] - sphere[2],
]
light_vector = [
light[0] - point_of_contact[0],
light[1] - point_of_contact[1],
light[2] - point_of_contact[2],
]
step_1 = (
(normal_vector[0] * light_vector[0])
+ (normal_vector[1] * light_vector[1])
+ (normal_vector[2] * light_vector[2])
)
step_2 = math.sqrt(
normal_vector[0] ** 2 + normal_vector[1] ** 2 + normal_vector[2] ** 2
)
step_3 = math.sqrt(
light_vector[0] ** 2 + light_vector[1] ** 2 + light_vector[2] ** 2
)
step_4 = (step_1) / (step_2 * step_3)
diffrence_in_angle = (math.acos(step_4)) / 3.14
spector = 1 - diffrence_in_angle**0.09333
def checkFloor(camera, pixel, floorLevel):
global floor_contact
if pixel[1] == 0:
return False
else:
t = -1 * (camera[1] + floorLevel) / (pixel[1] - camera[1])
floor_contact = [
camera[0] + (t * (pixel[0] - camera[0])),
camera[1] + (t * (pixel[1] - camera[1])),
camera[2] + (t * (pixel[2] - camera[2])),
]
return True
def colorFloor(
pixel,
):
turtle.penup()
turtle.pencolor(0.4, 0.4, 0.4)
turtle.goto(pixel[0], pixel[1])
turtle.dot()
turtle.pendown()
turtle.penup()
for x in range(-200, 200, 1):
for y in range(-200, 200, 1):
pixel[0] = x
pixel[1] = y
if checkIntersections_sphere(camera, pixel, sphere, radius):
getColor(sphere, point_of_contact)
color(pixel, diffrence_in_angle, spector)
else:
if checkFloor(camera, pixel, floorLevel):
if checkIntersections_sphere(floor_contact, light, sphere, radius):
colorFloor(pixel)
sphere = [200, 0, 101]
camera = [200, 0, -100]
for x in range(50, 475, 1):
for y in range(-200, 200, 1):
pixel[0] = x
pixel[1] = y
if checkIntersections_sphere(camera, pixel, sphere, radius):
getColor(sphere, point_of_contact)
color(pixel, diffrence_in_angle, spector)
else:
if checkFloor(camera, pixel, floorLevel):
if checkIntersections_sphere(floor_contact, light, sphere, radius):
colorFloor(pixel)
sphere = [-200, 0, 101]
camera = [-200, 0, -100]
for x in range(-800, 75, 1):
for y in range(-200, 200, 1):
pixel[0] = x
pixel[1] = y
if checkIntersections_sphere(camera, pixel, sphere, radius):
getColor(sphere, point_of_contact)
color(pixel, diffrence_in_angle, spector)
else:
if checkFloor(camera, pixel, floorLevel):
if checkIntersections_sphere(floor_contact, light, sphere, radius):
colorFloor(pixel)
window.mainloop()
global
. \$\endgroup\$