Jump to content

how use Math for create 3D games?


Recommended Posts

i need 1 correction: the screen only use 2D(X, Y) and not 3D(X, Y, Z)... so how can i create the perspective?

is these math correct:

PosX2D = PosX3D /(FocalDistance+PosZ3D);

PosY2D = PosY3D /(FocalDistance+PosZ3D)

?

i have seen several tutorials and seems that they have their own Perspective.
understand these, i can create my own polygon and move front-back, and left-right.

 

Link to comment
Share on other sites


done code:

#include <windows.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <math.h>

using namespace std;

HDC HDCConsole = GetWindowDC(GetConsoleWindow());


struct position
{
    float Pos3DX;
    float Pos3DY;
    float Pos3DZ;
    float PosX;
    float PosY;
    POINT Perspective(int FocalDistance, POINT Center={0,0})
    {
        float PosX2D = Pos3DX /(FocalDistance+Pos3DZ)+ Center.x;
        float PosY2D = Pos3DY /(FocalDistance+Pos3DZ)+Center.y;
        POINT pos;
        pos.x=round(PosX2D);
        pos.y=round(PosY2D);
        return pos;
    }
};


void DrawPolygon(HDC HDCDestination, vector<position> Points, HPEN &LineColor, HBRUSH &PlaneColor)
{
    HPEN hOldPen = (HPEN)SelectObject(HDCDestination, LineColor);
    HBRUSH hOldBrush = (HBRUSH)SelectObject(HDCDestination, PlaneColor);
    POINT pos[Points.size()];
    for(unsigned int index=0; index<Points.size(); index++)
    {
        pos[index]=Points[index].Perspective(300,{0,0});
    }
    if(Polygon(HDCDestination,pos,4)==FALSE) MessageBox(NULL,"error","error", MB_OK);


    SelectObject(HDCDestination, hOldPen);
    SelectObject(HDCDestination, hOldBrush);
}


int main()
{
    vector<position> Rec;
    Rec.push_back({0,0,0});
    Rec.push_back({10,0,0});
    /*Rec.push_back({10,10,0});
    Rec.push_back({0,10,0});
    Rec.push_back({0,0,0});*/
    HPEN hPen1 = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
    HBRUSH hPlane = CreateSolidBrush(RGB(0,255,0));
    do
    {
        DrawPolygon(HDCConsole,Rec,hPen1,hPlane);

    }while(!(GetKeyState(VK_ESCAPE) & 0x8000));
    DeleteObject(hPen1);
    DeleteObject(hPlane);
    return 0;
}

see the perspetive():

POINT Perspective(int FocalDistance, POINT Center={0,0})
    {
        float PosX2D = Pos3DX /(FocalDistance+Pos3DZ)+ Center.x;
        float PosY2D = Pos3DY /(FocalDistance+Pos3DZ)+Center.y;
        POINT pos;
        pos.x=round(PosX2D);
        pos.y=round(PosY2D);
        return pos;
    }

see on the Polygon():

POINT pos[Points.size()];
    for(unsigned int index=0; index<Points.size(); index++)
    {
        pos[index]=Points[index].Perspective(300,{0,0});
    }
    if(Polygon(HDCDestination,pos,4)==FALSE) MessageBox(NULL,"error","error", MB_OK);

if the center is {0,0} the line isn't showed.

if the center is {100,100}... the line is showed. The X seems ok... but Y ins't... the line seems drawed much more than window.

int main()
{
    vector<position> Rec;
    Rec.push_back({0,0,0});
    Rec.push_back({10,0,0});
    /*Rec.push_back({10,10,0});
    Rec.push_back({0,10,0});
    Rec.push_back({0,0,0});*/

so what is wrong with my perspective code?

Link to comment
Share on other sites

heres my perspective function:

POINT Perspective(int FocalDistance, POINT Center={0,0})
    {
        float PosX2D = Pos3DX /(FocalDistance+Pos3DZ)+ Center.x;
        float PosY2D = Pos3DY /(FocalDistance+Pos3DZ)+Center.y;
        POINT pos;
        pos.x=round(PosX2D);
        pos.y=round(PosY2D);
        return pos;
    }

these function is wrong...
how the perspective function works:
1 - we must calculate  the perspective(please use float or double types on divisions):

float Perspective = FocalLenght / (FocalLenght + PolygonPosZ);

2 - using the Perspective, we can change the shape scale or position(scale too):

float PosX2D = Pos3DX * Perspective;
float PosY2D = Pos3DY * Perspective;

3 - now we can add the center of screen to the  position:

PosX2D = PosX2D + ViewCenter.x;
PosY2D = PosY2D + ViewCenter.y;

4 - the Polygon()(for example) use the POINT pointer.. the POINT structer use LONG type(integers)... so we need use the trunc() function for convert them:

POINT pos;
pos.x=trunc(PosX2D);
pos.y=trunc(PosY2D);

now i can draw a polygon: 

vector<position> Polygon3D={ {30, 145,0}, {85, 165,0}, {105,
        110,10}, {65, 125,10}, {30, 105,0} };

    vector<POINT> polygon;

    for(int index=0; index<Polygon3D.size(); index++)
    {
        polygon.push_back(Polygon3D[index].Perspective(300,{WindowSize.right/2, WindowSize.bottom/2 }));
    }
                                             
//...                                             
DrawPolygon(HDCConsole,polygon,hPen1,hPlane);
                                             
void DrawPolygon(HDC HDCDestination, vector<POINT> points, HPEN LineColor, HBRUSH PlaneColor)
{
    HPEN hOldPen = (HPEN)SelectObject(HDCDestination, LineColor);
    HBRUSH hOldBrush = (HBRUSH)SelectObject(HDCDestination, PlaneColor);
    Polygon(HDCDestination,points.data(),points.size());
    SelectObject(HDCDestination, hOldPen);
    SelectObject(HDCDestination, hOldBrush);
}

yes the 'data()' give us in right vector type type.

see the result:
https://imgur.com/DcU5Aov

thank you so much for all.

in time i will create a wall shape for test.

 

Link to comment
Share on other sites

Model in 3D. Use your transforms to convert to a 2D viewport (window). Scale to screen coordinates.

If you are already clipping in 2D to the viewport, then you only need to clip the polygons in 3D to the viewplane (plane perpendicular to the direction the viewer is looking).

Harder but potentially more efficient is clipping polygons in 3D to the planes from the viewpoint to each of the four viewport sides.

Actually, 3D clipping is too advanced for now. Just keep all your models in positive z space until you have everything else working. And use triangles, not polygons, to simplify rendering. Later you can support rectangles and arbitrary polygons by breaking them down into triangles.

 

Link to comment
Share on other sites

Yes i'm trying clipping the 3D shape. I try avoid the Z negative. But the wrong coordenates continue happen... so what you advice more?

Anotherthing is best create my own function for draw a line?

Link to comment
Share on other sites

i think i know the problem: the polygon is a serie of lines\dots. but some can be from right to left(normaly the Destination is more far and not more close ;) ).

heres the position structure:

struct position
{
    float Pos3DX;
    float Pos3DY;
    float Pos3DZ;
    float PosX;
    float PosY;

    //Convert 3D to 2D:
    POINT Perspective(int FocalDistance=300, POINT Center={0,0})
    {
        if(Pos3DZ==0) Pos3DZ=1;
        float perspect=FocalDistance/(FocalDistance+Pos3DZ);

        float PosX2D = Pos3DX*perspect + Center.x;
        float PosY2D = Pos3DY*perspect + Center.y;
        POINT pos;
        pos.x=trunc(PosX2D);
        pos.y=trunc(PosY2D);
        return pos;
    }
};

and see the GetLineZZero() header:

position GetLineZZero(position Origin, position Destination)

imagine if the 'Destination' is a Left point and the Origin is the Right point.... how can i compare the values?
is just like:

if(Destination.Pos3DX < Origin.Pos3DX || Destination.Pos3DY < Origin.Pos3DY || Destination.Pos3DZ < Origin.Pos3DZ) SwapPosition(Origin,Destination);//Swap function not created

i'm I right?

Edited by Joaquim
Link to comment
Share on other sites

  • 10 months later...
On 8/7/2022 at 3:45 PM, Joaquim said:

i need 1 correction: the screen only use 2D(X, Y) and not 3D(X, Y, Z)... so how can i create the perspective?

is these math correct:

PosX2D = PosX3D /(FocalDistance+PosZ3D);

PosY2D = PosY3D /(FocalDistance+PosZ3D)

?

i have seen several tutorials and seems that they have their own Perspective.
understand these, i can create my own polygon and move front-back, and left-right.

 

Sure, let's simplify it:

Your formulas are a type of 3D to 2D perspective projection. However, it's more common to divide by Z alone, not the sum of focal distance and Z:

PosX2D = (FocalDistance * PosX3D) / PosZ3D; PosY2D = (FocalDistance * PosY3D) / PosZ3D;

This provides a "camera" view, with objects appearing smaller the further they are. Note, this won't handle viewport transformations, and objects at Z=0 or negative Z may cause issues.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...