1
$\begingroup$

I am trying to learn about 3d graphics from first principles, so i have decided to implement a simple thing, create a circle in 3d space & rotate it along some axis. I understand the basics theory.

  1. position circle somewhere in 3d space.
  2. calculate its projection on some plane.

Once i can get this i can use rotation matrix to calculate the new position of vertices. but i am a bit stuck at 2nd step. this is my code:

import pygame
import math

(width, height) = (600, 500)
screen = pygame.display.set_mode((width, height))
pygame.display.flip()


running = True

K = 8   # view plane distance
cz = 10 # z location of circle initially.

# Pyagme 0.0 is at top left , but i want to center it at window?? is this even coorect to do or is should just continue using top left.

def translate_coords_to_center(x , y):
    return (width/2 - x, height/2 - y)

# plots a pixel
def pixel(x,y,color=(100,20,30)):
    s = pygame.Surface((1,1))
    s.fill(color)
    r,r.x,r.y = s.get_rect(),x,y
    screen.blit(s,r)


# Draw the circle
def circle(cx, cy, cz, radius):
    N = 100
    PI = 3.14
    angle = 360 / N


    for i in range(N):
        x2 = cx + radius * math.cos(PI* angle * i / 180)
        y2 = cy + radius * math.sin(PI* angle * i / 180)

        # Do a 2d projection
        x2 = K* x2 / cz
        y2 = K* y2 / cz

        pixel(x2, y2)


while running:
    x, y = translate_coords_to_center(0,0)
    circle(x, y, cz, 50)
    cz += 1
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

When i change the z position of circle, i get something like the below image, I am expecting the circle to not change its position but only its size, ( i know this cant be true as i am dividing by z ), am i missing some translation step? :

enter image description here

EDIT: Adding the translation after projection is also not working:

import pygame
import math

(width, height) = (600, 500)
screen = pygame.display.set_mode((width, height))
pygame.display.flip()


running = True

K = 8   
cz = 10 

def translate_coords_to_center(x , y):
    return (width/2 - x, height/2 - y)


def pixel(x,y,color=(100,20,30)):
    s = pygame.Surface((1,1))
    s.fill(color)
    r,r.x,r.y = s.get_rect(),x,y
    screen.blit(s,r)

def circle(cx, cy, cz, radius):
    N = 100
    PI = 3.14
    angle = 360 / N


    for i in range(N):
        x2 = cx + radius * math.cos(PI* angle * i / 180)
        y2 = cy + radius * math.sin(PI* angle * i / 180)

        # Do a 2d projection
        x2 = K* x2 / cz
        y2 = K* y2 / cz
        sx, sy = translate_coords_to_center(x2, y2)

        pixel(sx, sy)



while running:
    
    circle(0,0, cz, 50) # this works correctly, but circles are centered at top left corner of screen,
    cz += 1
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
$\endgroup$

1 Answer 1

1
$\begingroup$

Your translate_coords_to_center(0,0) function should be done after you have done the projection from 3d to 2d.

e.g.

for i in range(N):
        x2 = cx + radius * math.cos(PI* angle * i / 180)
        y2 = cy + radius * math.sin(PI* angle * i / 180)

        # Do a 2d projection
        x2 = K* x2 / cz
        y2 = K* y2 / cz

        sx, sy = translate_coords_to_center(x2, y2)

        pixel(sy, sy)

while running:
    circle(0, 0, cz, 50)
    cz += 1
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

The effect you are seeing is caused by 2 things.

  1. Because a constant x/y offset is incorrectly added in 3d world space the array of circles will appear to the right and below of the camera's position.
  2. Because the 0,0 origin of view/camera space is not the centre of the display, instead it's at the top-left (Adding the window centre coords AFTER projection fixes that)
$\endgroup$
3
  • $\begingroup$ after adding the translation after projection , i get a straight line from center to the top left corner of screen $\endgroup$
    – anekix
    Commented Nov 3, 2020 at 10:40
  • $\begingroup$ Can you post your modified code so I can check it for you ? $\endgroup$
    – PaulHK
    Commented Nov 3, 2020 at 10:48
  • $\begingroup$ Did you remove the translation before projection ? (so circle has 0,0 passed for its X,Y coord) $\endgroup$
    – PaulHK
    Commented Nov 3, 2020 at 10:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.