<p>Your translate_coords_to_center(0,0) function should be done after you have done the projection from 3d to 2d.</p>
<p>e.g.</p>
<pre><code>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
</code></pre>
<p>The effect you are seeing is caused by 2 things.</p>
<ol>
<li>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.</li>
<li>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)</li>
</ol>

CC BY-SA 4.0
2020-11-03T10:40:57.663Z
after adding the translation after projection , i get a straight line from center to the top left corner of screen
anekix
CC BY-SA 4.0
2020-11-03T10:48:51.277Z
Can you post your modified code so I can check it for you ?
PaulHK
CC BY-SA 4.0
2020-11-03T10:56:49.590Z
Did you remove the translation before projection ? (so circle has 0,0 passed for its X,Y coord)
PaulHK
CC BY-SA 4.0
2020-11-03T07:56:04.907Z
2020-11-03T10:35:38.030Z
2020-11-03T10:35:38.030Z
PaulHK
<p>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 &amp; rotate it along some axis. I understand the basics theory.</p>
<ol>
<li>position circle somewhere in 3d space.</li>
<li>calculate its projection on some plane.</li>
</ol>
<p>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:</p>
<pre><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
</code></pre>
<p>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 <code>z</code> ), am i missing some translation step? :</p>
<p><a href="https://i.sstatic.net/rQrsr.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/rQrsr.png" alt="enter image description here" /></a></p>
<p><strong>EDIT:  Adding the translation after projection is also not working:</strong></p>
<pre><code>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
</code></pre>

<3d><2d>
projecting 3d onto 2d plane is not showing up correctly
anekix
# projecting 3d onto 2d plane is not showing up correctly

(Asked by: username_0 on 2020-11-02)

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](https://i.sstatic.net/rQrsr.png)](https://i.sstatic.net/rQrsr.png)

**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

```

**Tags:** 3d, 2d


---

## 1 answers

### Answer by username_1 on 2020-11-03. Score: 1

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)

> **Comments:**
> **username_0**: after adding the translation after projection , i get a straight line from center to the top left corner of screen  
> **username_1**: Can you post your modified code so I can check it for you ?  
> **username_1**: Did you remove the translation before projection ? (so circle has 0,0 passed for its X,Y coord)  

---

