Würfel Vector 3D Rotation

Erste Gehversuche mit Vectoren im dreidimensionalen Raum zu spielen und diese auf 2D abzubilden am Beispiel eines 3D Würfels.

// written by André Betz 
// http://www.andrebetz.de

#include <math.h>
#define PI    3.1415927

class Object
{
public:
    Object(unsigned long ulPoints,double* pdPoints);
    ~Object();
    void Set(double dPosX,double dPosY,double dPosZ,
              double dPhiX,double dPhiY,double dPhiZ);
protected:
    unsigned long    m_ulPoints;
    double            m_dPosX;
    double            m_dPosY;
    double            m_dPosZ;
    double            m_dPhiX;
    double            m_dPhiY;
    double            m_dPhiZ;
    double*            m_pdPoints;
    double*            m_pdTempPoints;
    double*            m_pdCopyPoints;
    double            Grad2Bogen(double dGrad);
    double            MySin(double dGrad);
    double            Correct(double dGrad);
    void            Dreh(unsigned long ulPos);
    void            Transform(unsigned long ulPos);
    void            Project(unsigned long ulPos);
};

Object::Object(unsigned long ulPoints,double* pdPoints)
{
    unsigned long    ulCount;

    m_dPosX            = 0.0;
    m_dPosY            = 0.0;
    m_dPosZ            = 0.0;
    m_dPhiX            = 0.0;
    m_dPhiY            = 0.0;
    m_dPhiZ            = 0.0;
    m_ulPoints        = ulPoints;
    m_pdPoints        = pdPoints;
    m_pdCopyPoints    = new double[m_ulPoints*3];
    m_pdTempPoints    = new double[m_ulPoints*3];

    for(ulCount=0;ulCount<m_ulPoints;ulCount++)
    {
        m_pdCopyPoints[ulCount*3+0]    = m_pdPoints[ulCount*3+0];
        m_pdCopyPoints[ulCount*3+1]    = m_pdPoints[ulCount*3+1];
        m_pdCopyPoints[ulCount*3+2]    = m_pdPoints[ulCount*3+2];
    }
}

Object::~Object()
{
    delete m_pdCopyPoints; 
}

void Object::Set(double    dPosX,double dPosY,double dPosZ,
                  double    dPhiX,double dPhiY,double dPhiZ)
{
    unsigned long    ulCount;

    m_dPosX    = dPosX;
    m_dPosY    = dPosY;
    m_dPosZ    = dPosZ;
    m_dPhiX    += dPhiX;
    m_dPhiY    += dPhiY;
    m_dPhiZ    += dPhiZ;

    if(m_dPhiX>360.0)    m_dPhiX = Correct(m_dPhiX);
    if(m_dPhiY>360.0)    m_dPhiY = Correct(m_dPhiY);
    if(m_dPhiZ>360.0)    m_dPhiZ = Correct(m_dPhiZ);

    for(ulCount=0;ulCount<m_ulPoints;ulCount++)
    {
        Dreh(ulCount*3);
        Transform(ulCount*3);
        Project(ulCount*3);
    }
}

double Object::Grad2Bogen(double dGrad)
{
    double dBogen;
    dBogen = (PI * dGrad) / 180.0;
    return dBogen;
}

double Object::MySin(double dGrad)
{
    double            dSinus;
    double            dBogen;
    
    if(dGrad>=360.0)    dGrad = Correct(dGrad);
    if(dGrad==180.0)    return 0.0;
    dBogen = Grad2Bogen(dGrad);
    dSinus = sin(dBogen);

    return dSinus;
}

double Object::Correct(double dGrad)
{
    unsigned long    ulHelp;
    double            dCGrad;

    if(dGrad>360.0)
    {
        ulHelp    = (unsigned long)(dGrad / 360.0);
        dCGrad    = dGrad - 360.0 * ulHelp;
    }

    return dCGrad;
}

void Object::Dreh(unsigned long ulPos)
{
    double dSinPhiX;
    double dSinPhiY;
    double dSinPhiZ;
    double dCosPhiX;
    double dCosPhiY;
    double dCosPhiZ;

    dSinPhiX = MySin(m_dPhiX);
    dSinPhiY = MySin(m_dPhiY);
    dSinPhiZ = MySin(m_dPhiZ);
    dCosPhiX = MySin(m_dPhiX+90.0);
    dCosPhiY = MySin(m_dPhiY+90.0);
    dCosPhiZ = MySin(m_dPhiZ+90.0);

    m_pdTempPoints[ulPos+0] =    ( dCosPhiX*dCosPhiZ - dSinPhiX*dCosPhiY*dSinPhiZ) * m_pdCopyPoints[ulPos+0] +
                                            (-dCosPhiX*dSinPhiZ - dSinPhiX*dCosPhiY*dCosPhiZ) * m_pdCopyPoints[ulPos+1] +
                                              dSinPhiX*dSinPhiY                               * m_pdCopyPoints[ulPos+2];

    m_pdTempPoints[ulPos+1] =    ( dSinPhiX*dCosPhiZ + dCosPhiX*dCosPhiY*dSinPhiZ) * m_pdCopyPoints[ulPos+0] +
                                            (-dSinPhiX*dSinPhiZ + dCosPhiX*dCosPhiY*dCosPhiZ) * m_pdCopyPoints[ulPos+1] -
                                              dCosPhiX*dSinPhiY                               * m_pdCopyPoints[ulPos+2];

    m_pdTempPoints[ulPos+2] =      dSinPhiY*dSinPhiZ                               * m_pdCopyPoints[ulPos+0] + 
                                              dSinPhiY*dCosPhiZ                               * m_pdCopyPoints[ulPos+1] + 
                                              dCosPhiY                                        * m_pdCopyPoints[ulPos+2];


}

void Object::Transform(unsigned long ulPos)
{
    m_pdPoints[ulPos+0] = m_pdTempPoints[ulPos+0] + m_dPosX;
    m_pdPoints[ulPos+1] = m_pdTempPoints[ulPos+1] + m_dPosY;
    m_pdPoints[ulPos+2] = m_pdTempPoints[ulPos+2] + m_dPosZ;
}

void Object::Project(unsigned long ulPos)
{
    double dDist = 10;

    if(m_pdPoints[ulPos+2]!=0.0)
    {
//        m_pdPoints[ulPos+0] = m_pdPoints[ulPos+0] * dDist / m_pdPoints[ulPos+2];
//        m_pdPoints[ulPos+1] = m_pdPoints[ulPos+1] * dDist / m_pdPoints[ulPos+2];
    }
}

#include <windows.h>
#define    MD    100.0
#define SI    24

unsigned long    wx        = 400;
unsigned long    wy        = 400;
unsigned long    zahl    = 0;

double Wuerfel[SI*3] = 
{
    -MD,-MD,-MD,    -MD,-MD, MD,
    -MD,-MD,-MD,    -MD, MD,-MD,
    -MD,-MD,-MD,     MD,-MD,-MD,

     MD, MD, MD,     MD, MD,-MD,
     MD, MD, MD,     MD,-MD, MD,
     MD, MD, MD,    -MD, MD, MD,

    -MD, MD,-MD,     MD, MD,-MD,
    -MD, MD,-MD,    -MD, MD, MD,

    -MD,-MD, MD,    -MD, MD, MD,
    -MD,-MD, MD,     MD,-MD, MD,

     MD,-MD,-MD,     MD, MD,-MD,
     MD,-MD,-MD,     MD,-MD, MD
};

Object xWuerfel(SI,Wuerfel);

int Show(HWND hwnd)
{
    HDC                hdcWindow;
    HBRUSH            brush;
    HRGN            hrgn;
    BOOL            t;
    double            px = 1.6;
    double            py = 1.7;
    double            pz = 1.8;
    unsigned long    count;

    hdcWindow = GetDC(hwnd);

    hrgn = CreateRectRgn(0,0,wx,wy);
    brush = CreateHatchBrush(HS_BDIAGONAL,0x00ffffff);
    t = FillRgn(hdcWindow,hrgn,brush);

    xWuerfel.Set(200,200,200,1.3,1.5,1.7);

    for(count=0;count<SI*3;count+=6)
    {
        MoveToEx(hdcWindow,(int)Wuerfel[count+0],(int)Wuerfel[count+1],NULL);
        LineTo(hdcWindow,(int)Wuerfel[count+3],(int)Wuerfel[count+4]);
    }

    ReleaseDC(hwnd,hdcWindow);

    return 0;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT Message,WPARAM wParam,LPARAM lParam)
{
    switch(Message)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_TIMER:
            Show(hwnd);
            break;
 
        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);
   }
   return 0;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    WNDCLASSEX        WndClass;
    HWND            hwnd;
    MSG                Msg;
    char            ClassName[] = "MyWindowClass";
    UINT            idTimer1    = 1;
    UINT            nTimerDelay = 1;

    WndClass.cbSize        = sizeof(WNDCLASSEX);
    WndClass.style         = 0;
    WndClass.lpfnWndProc   = WndProc;
    WndClass.cbClsExtra    = 0;
    WndClass.cbWndExtra    = 0;
    WndClass.hInstance     = hInstance;
    WndClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    WndClass.lpszMenuName  = NULL;
    WndClass.lpszClassName = ClassName;
    WndClass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&WndClass);
    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,ClassName,"Dreh  Betz99",WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT,CW_USEDEFAULT,wx,wy,NULL,NULL,hInstance,NULL);

    ShowWindow(hwnd,nCmdShow);
    UpdateWindow(hwnd);

    SetTimer(hwnd,idTimer1,nTimerDelay,NULL);

    while(GetMessage(&Msg,NULL,0,0))
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }

    KillTimer(hwnd, idTimer1);
    
    return Msg.wParam;
}
 

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.