Marcus -> Programmando cose inutili

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
Ho pensato che fosse una buona idea tenere un topic con le cose che faccio giusto per il piacere di, in seguito, guardare indietro e vedere i progressi xD
Progetto del giorno: siccome sto cercando di capire un pò meglio la trigonometria, oggi mi son messo a fare un client che mostra "l'onda" (spero sia il termine italiano corretto) di qualsiasi funzione trigonometrica gli venga passata, nel caso dell'immagine sotto, cos(angle) :)
7mBlUrD.gif
 
Ultima modifica:
  • Mi piace
Reazioni: Mursey
M

Mursey

Ospite
Sarebbe bello se mettessi anche qualche frammento di codice (magari di una parte un pò complicata) spiegando come lo hai implementato.
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
Sicuro, anche se non c'è davvero nulla di complicato quindi non sò quando possa risultare interessante :S

La parte più interessante credo sia la rappresentazione della sine wave che è un insieme di punti, per rappresentarlo sto registrando nel tempo i risultati di una data funzione trigonometrica e conservandoli dentro una
CSS:
    std::deque<D2D1_POINT_2F> mWavePoints;
D2D1_POINT_2F è una classe Direct2D, uno struct con dentro 2 float, x ed y. Nella x conservo il tempo alla creazione del punto, nella y il risultato della funzione (in questo caso coseno(angolo)) che vanno da -1 a 1.

La scelta della deque è perchè permette di inserire nuovi punti sul retro ed eliminare quelli che "hanno vissuto troppo" dal davanti, proprio come appare nel grafico visto che sto disegnando tutti i punti dentro la deque.

e tutto l'update avviene dentro l'update function

CSS:
void TrigClient::Update(float dt)
{
    mAngle += mAngleChange*dt;

    float oneCircleTime = 360 / mAngleChange; //time required to complete 1 revolution, in seconds
    unsigned pointResolution = 30;
    float pointsPerSecond = 1 / pointResolution; //how often points are added, in seconds

    static float addPointTimer = 0;
    addPointTimer += dt;
    //evaluate every t | determines wave resolution
    if (addPointTimer >= pointsPerSecond)
    {
        //function to turn into a wave
        D2D1_POINT_2F newPoint = { mTimer.totalTime() ,cos(rad(mAngle)) };
   
        //add new point
        mWavePoints.push_back(newPoint);

        //remove old Points
        for (size_t i = 0; i < mWavePoints.size(); i++)
        {
            if (mTimer.totalTime() - mWavePoints.front().x >= oneCircleTime) {
                mWavePoints.pop_front();
            }
            else {
                break;
            }
        }

        addPointTimer = 0;
    }
}

la funzione update riceve il DeltaTime(quanto tempo è passato dall'ultimo frame) dal timer associato al mio client e lo usa per cambiare l'angolo da valutare.
Quindi se mAngleChange fosse 360 e lo moltiplico per dt, allora sto facendo un giro completo al secondo, e via dicendo.
Allo stesso modo uso dt per avanzare addPointTimer, e nel caso del codice sopra i punti vengono aggiunti/rimossi 30 volte al secondo.

CSS:
if (mTimer.totalTime() - mWavePoints.front().x >= oneCircleTime)
la linea sopra sottrae il tempo di creazione (del punto davanti alla deque) dal tempo attuale, e se il risultato è maggiore o uguale del tempo impiegato per completare una rivoluzione, allora il punto viene eliminato perchè ha vissuto troppo al lungo :S

E questa è la funzione che si occupa di disegnare la sinewave ad ogni frame
CSS:
    //draw wave
    float internalBoxMidY = internalBoxTop + ((internalBoxBottom - internalBoxTop) / 2);
    float oneCircleTime = 360 / mAngleChange;
    float graphHSpace = lineBoundRight - lineBoundLeft;
    float graphYSpace = internalBoxBottom - internalBoxTop;
    for (auto& point : mWavePoints)
    {
        float pointAge = mTimer.totalTime() - point.x;
        drawPoint(D2D1::Point2F(lineBoundLeft + ((graphHSpace / oneCircleTime) * pointAge),//X
                                internalBoxMidY + (-point.y * graphYSpace / 2.05f))//Y
                  , 2.6f, D2D1::ColorF(point.y, -point.y, -point.y, 0.85f));
    }

la largezza del rettangolo (dove viene mostrata la sine wave) è divisa per il tempo necessario per completare una rivoluzione e moltiplicato per l'età del punto in questione, per ogni punto, per ottenere le giuste coordinate X.
Per quanto riguarda il colore, la y del punto controlla il canale rosso (massima intensità quando cos(angolo)==1 quindi a 0°) mentre -y controlla il verde e blu ( per creare cyan quanto la y è -1 (-1*-1 == 1) ) e tutti i colori convergono a 0 quando y == 0 quindi ottengo il nero a 0 ed il gradient for free :P

Non mi pare ci sia molto altro da dire xD
 
Ultima modifica:
  • Mi piace
Reazioni: BAT
M

Mursey

Ospite
Ottimo.
Questa sezione è per i più esperti ma anche per i neofiti, quindi ottimo comunque :ok:
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,452
11,351
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
Carino, ma matematicamente non mi convince, nel senso che non aiuta a capire la trigonometria:
i grafici di funzione non sono animazioni (il grafico di cos(x) si chiama cosinusoide non "onda" ma questa te la perdoniamo volentieri);
c'è bisogno delle unità di misura e soprattutto di numeri che indichino l'angolo di cui si calcola il coseno
Un'idea sarebbe quella di disegnare la circonferenza goniometrica "standard" (quella di raggio 1) e mostrare dov'è il valore di cos(x) sopra il grafico FISSO di cos(x);
per esempio, muovi un puntino sulla circonferenza e fai vedere come si muove un puntino sul grafico di cos(x) in base all'angolo del puntino sulla cironferenza

P.S.
ci tengo a sottolineare che non voglio fare il guastafeste, ma se ti dico "bravo" non ti aiuto;
bravo te lo dico ugualmente per l'impegno che ci metti,
mi permetto di dare piccoli suggerimenti per essere "produttivi": così il divertimento nel programmare si abbina ad impare qualcosa di nuovo 8trigonometria in questo caso)
 
Ultima modifica:
  • Mi piace
Reazioni: Mursey e Hobet

Hobet

Utente Attivo
609
222
CPU
i5 6600k
Dissipatore
AIO H100
Scheda Madre
ASUS z170 Deluxe
HDD
1 WD Blue 1 TB; evo 850 500gb
RAM
Vengeance 4x4
GPU
GTX 1070ti MSI
Audio
Nope
Monitor
MG278Q
Case
750D Corsair
Net
Fastweb 200/30
OS
PucyBuntu
Carino, ma matematicamente non mi convince, nel senso che non aiuta a capire la trigonometira:
i grafici di funzione non sono animazioni (il grafico di cos(x) si chiama cosinusoide non "onda" ma questa te la perdoniamo volentieri);
c'è bisogno delle unità di misura e soprattutto di numeri che indichino l'angolo di cui si calcola il coseno
Un'idea sarebbe quella di disegnare la circonferenza goniometrica "standard" (quella di raggio 1) e mostrare dov'è il valore di cos(x) sopra il grafico FISSO di cos(x);
per esempio, muovi un puntino sulla circonferenza e fai vedere come si muove un puntino sul grafico di cos(x) in base all'angolo del puntino sulla cironferenza

P.S.
ci tengo a sottolineare che non voglio fare il guastafeste, ma se ti dico "bravo" non ti aiuto;
bravo te lo dico ugualmente per l'impegno che ci metti,
mi permetto di dare piccoli suggerimenti per essere "produttivi": così il divertimento nel programmare si abbina ad impare qualcosa di nuovo 8trigonometria in questo caso)
Mi hai risparmiato la parte matematica da dire :veach:. Posta tutto su GitHub se puoi
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
Carino, ma matematicamente non mi convince, nel senso che non aiuta a capire la trigonometira:
i grafici di funzione non sono animazioni (il grafico di cos(x) si chiama cosinusoide non "onda" ma questa te la perdoniamo volentieri);
c'è bisogno delle unità di misura e soprattutto di numeri che indichino l'angolo di cui si calcola il coseno
Un'idea sarebbe quella di disegnare la circonferenza goniometrica "standard" (quella di raggio 1) e mostrare dov'è il valore di cos(x) sopra il grafico FISSO di cos(x);
per esempio, muovi un puntino sulla circonferenza e fai vedere come si muove un puntino sul grafico di cos(x) in base all'angolo del puntino sulla cironferenza

P.S.
ci tengo a sottolineare che non voglio fare il guastafeste, ma se ti dico "bravo" non ti aiuto;
bravo te lo dico ugualmente per l'impegno che ci metti,
mi permetto di dare piccoli suggerimenti per essere "produttivi": così il divertimento nel programmare si abbina ad impare qualcosa di nuovo 8trigonometria in questo caso)
Thanks, il motivo per quale non ho scritte che riportano l'angolo o altre info utili è perchè non ho ancora imparato la procedura per creare testo in Direct2D (mi pare richieda creare la descrizione del font e qualche altro passaggio aggiuntivo) ma penso sia abbastanza facile da scoprire, su msdn.
Btw, non ho menzionato il punto di riferimento statico nel grafico sopra, sarebbe la linea verticale più a sinistra del grafico, quando l'angolo è 0° o 180° quel punto è rispettivamente 1 e -1 su quella linea, a 90° e 270° è 0, quindi io effettivamente guardavo quel punto nell'ottica del punto che si muove che hai descritto tu.
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
piccola modifica, aggiunto un pò di testo,lo metto dentro spoiler perchè ste gif pesano xD

E questo mostra anche il vantaggio di definire tutte le variabili in termini di altre variabili, mi basta cambiare x,y, width ed height del box con l'animazione e tutto il codice si adatta di conseguenza, niente hardcoded "magic numbers" :S
[
GWz5f7c.gif

questo invece la porzione di codice richiesta per impostare il font:
CSS:
//IDWRITE Factory
    HRESULT hr{};
    IDWriteFactory* writeFactory{};
    DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&writeFactory));
    if (hr != S_OK) {
        MessageBoxW(mhWindow, L"failed to create write factory", 0, 0);
        return false;
    }

    //text format setting
    hr = writeFactory->CreateTextFormat(
        L"Gabriola",//font family name
        NULL, //font collection
        DWRITE_FONT_WEIGHT_REGULAR,//font weight
        DWRITE_FONT_STYLE_NORMAL, //font style
        DWRITE_FONT_STRETCH_NORMAL, //font stretch
        32.0f, //font size
        L"en-us", //local name
        &mTextFormat);
    if (hr != S_OK) {
        MessageBoxW(mhWindow, L"failed to create font", 0, 0);
        return false;
    }

    //set text rendering params
    IDWriteRenderingParams* renderingParams;
    writeFactory->CreateCustomRenderingParams(
        100.f,//gamma
        0.f,//contrast
        1.f, //clear type leve, 1 is max
        DWRITE_PIXEL_GEOMETRY_RGB,//pixel geometry
        DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC,
        &renderingParams);
    mRenderTarger->SetTextRenderingParams(renderingParams);

    renderingParams->Release();
    writeFactory->Release();
 
  • Mi piace
Reazioni: BAT
M

Mursey

Ospite
P.S.
ci tengo a sottolineare che non voglio fare il guastafeste, ma se ti dico "bravo" non ti aiuto;
bravo te lo dico ugualmente per l'impegno che ci metti,
Ci tengo a precisare che il mio commento non è più a nome dello staff ma solo personale.

Ormai sono un semplice utente e non mi occupo più della sezione.
Però mi fa piacere che venga tenuta viva da topic come questo che, pur avendo qualche imprecisione o non essendo comunque lo specchio dello "stato dell'arte", aiutano chi vuole imparare e favoriscono il dialogo e lo scambio di conoscenze.

Quindi, ottimo :ok:
 
  • Mi piace
Reazioni: Marcus Aseth

BAT

Moderatore
Staff Forum
Utente Èlite
22,452
11,351
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
piccola modifica, aggiunto un pò di testo,lo metto dentro spoiler perchè ste gif pesano
Già mi piace un po' di più;
dovresti mettere tutto a sinistra nel grafico i valori +1 e -1, possibilmente anche l'asse x (che indica lo 0), in modo che sia più evidente il valore assunto dal coseno;
dovresti poi rallentare l'animazione ed inserire un piccola pausa in corrispondenza di alcuni angoli "notevoli", quelli per cui in trigonometria conviene imparare a memoria il valore delle funzioni, ossia, partendo da 0° gli angoli multipli di 45°e quelli multipli di 30° (con una pausa un po' più lunga per 0°,90°,180°,270°
 
Ultima modifica:

signore del tempo

Utente Èlite
3,228
491
CPU
Intel Core i5 4670K
Scheda Madre
Asus Z87-Plus
HDD
WD Caviar Green 500GB
RAM
G.Skill Ares 2x4GB 1600MHz
GPU
Sapphire 7850 1GB @ 1050MHz
Audio
Integrata
Monitor
Acer V193w
PSU
XFX ProSeries 550W Core Edition
Case
CM HAF 912 plus
OS
ArchLinux + KDE - Windows 10
Una curiosità: perché D2D piuttosto che GDI, SFML, SDL ecc.? Dico perché è abbastanza low-level come cosa.
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
Una curiosità: perché D2D piuttosto che GDI, SFML, SDL ecc.? Dico perché è abbastanza low-level come cosa.
Perchè sto leggendo 3D Games Programming With DirectX11, ho il framework D3D11 pronto e sono ad un punto dove si inizia a discutere più nel dettaglio l'uso delle matrici, siccome sospettavo che avrei avuto problemi a capire a fondo le rotazioni con le matrici ho messo in pausa il libro e preso in mano 3d Math Primer.
Ho pensato che esempi con le matrici verranno introdotti prima in 2D e dato che stavo leggendo la parte iniziale del libro riguardo alle varie funzioni trigonometriche, ho aperto una piccola parentesi e ne ho approfittato per provare a creare il framework D2D e testarlo su quello, quindi la scelta di D2D è per mantenere lo studio nell'ambito DirectX e per vedere un pò la differenza tra D3D e D2D. La scelta di librerie utili come SDL è fuori discussione perchè se il tema di studio attuale è DirectX, voglio quanta meno roba possibile tra me e DirectX :P
 

filoippo97

Utente Èlite
14,067
7,617
CPU
Intel Core I7 4930K @4.5GHz
Dissipatore
EKWB supremacy nickel
Scheda Madre
ASUS Rampage IV Black Edition
HDD
OCZ vertex 4 512GB | WD RE4 Enterprise Storage 2TB
RAM
16GB Corsair Dominator Platinum 2133MHz cas9 OC @2400MHz 9-11-11-31-2 1.65V
GPU
2-way SLI GTX 780Ti DirectCUII OC
Audio
TEAC UD-503 MUSES + HiFiMan HE-560 V2 + Anaview AMS1000 + Tannoy Revolution XT8F
Monitor
ASUS VG278HR 144Hz 3D 1920x1080p
PSU
Corsair AX1200i Fully sleeved red
Case
Corsair Graphite 760T Arctic White
Periferiche
Corsair K95 | Steelseries Rival
OS
windows 10 Pro
piccola modifica, aggiunto un pò di testo,lo metto dentro spoiler perchè ste gif pesano xD

E questo mostra anche il vantaggio di definire tutte le variabili in termini di altre variabili, mi basta cambiare x,y, width ed height del box con l'animazione e tutto il codice si adatta di conseguenza, niente hardcoded "magic numbers" :S
[
GWz5f7c.gif

questo invece la porzione di codice richiesta per impostare il font:
CSS:
//IDWRITE Factory
    HRESULT hr{};
    IDWriteFactory* writeFactory{};
    DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&writeFactory));
    if (hr != S_OK) {
        MessageBoxW(mhWindow, L"failed to create write factory", 0, 0);
        return false;
    }

    //text format setting
    hr = writeFactory->CreateTextFormat(
        L"Gabriola",//font family name
        NULL, //font collection
        DWRITE_FONT_WEIGHT_REGULAR,//font weight
        DWRITE_FONT_STYLE_NORMAL, //font style
        DWRITE_FONT_STRETCH_NORMAL, //font stretch
        32.0f, //font size
        L"en-us", //local name
        &mTextFormat);
    if (hr != S_OK) {
        MessageBoxW(mhWindow, L"failed to create font", 0, 0);
        return false;
    }

    //set text rendering params
    IDWriteRenderingParams* renderingParams;
    writeFactory->CreateCustomRenderingParams(
        100.f,//gamma
        0.f,//contrast
        1.f, //clear type leve, 1 is max
        DWRITE_PIXEL_GEOMETRY_RGB,//pixel geometry
        DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC,
        &renderingParams);
    mRenderTarger->SetTextRenderingParams(renderingParams);

    renderingParams->Release();
    writeFactory->Release();
questo potrebbe essere utile anche quando devi spiegare fasori e moto armonico alla gente :+1:
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
Esperimento del giorno, cercavo di capire ed utilizzare le matrici, in questo caso cercavo di ruotare un'immagine usando una 3x3Matrix moltiplicata per i punti dell'immagine. Codice e .gif sotto, suggerisco a chiunque di non prendere spunto dal codice orribile, specialmente dove ri-inizializzo i punti dell'immagine ad ogni frame dentro draw(), cosa assolutamente pessima ed unitile, semplicemente volevo vedere tutto in una singola pagina quindi ho messo tutto lì e lo scopo di ciò è soltanto per me di capire meglio come funziona la moltiplicazione dei punti con la matrice e non di creare buoni esempi per chi legge :S

VY5wCU3.gif

CSS:
void Matrix2DClient::Update(float dt)
{
    mHandle->update();
}

void Matrix2DClient::Draw()
{
    mRenderTarget->Clear(D2D1::ColorF(0.34f, 0.36f, 0.4f, 1.0f));
    makeGrid(100, 45.f);

    mHandle->draw();


    float angle = mHandle->getHandleAngle();//angle in degree

    D2D1_POINT_2F basisX = { cos(rad(angle)), sin(rad(-angle)) }; //for angle == 0°,  (1,0)
    D2D1_POINT_2F basisY = { -sin(rad(-angle)), cos(rad(angle)) };//for angle == 0°,  (0,1)
    {
        float displayLenght = 100;
        //draw basisX
        mBrush->SetColor(D2D1::ColorF(0.86f, 0.1f, 0.2f, 1.f));
        float basisXnewX = mOriginX + basisX.x * displayLenght; //draw axis at origin
        float basisXnewY = mOriginY + basisX.y * displayLenght; //draw axis at origin
        mRenderTarget->DrawLine(D2D1::Point2F(mOriginX, mOriginY),
                                D2D1::Point2F(basisXnewX, basisXnewY), mBrush, 2.f);
        mRenderTarget->DrawTextW(L"x", 1, mTextFormat, D2D1::RectF(basisXnewX, basisXnewY, 1000, 1000), mBrush);
     
        //draw basisY
        mBrush->SetColor(D2D1::ColorF(0.1f, 0.86f, 0.2f, 1.f));
        float basisYnewX = mOriginX + -basisY.x * displayLenght; //draw axis at origin
        float basisYnewY = mOriginY + -basisY.y * displayLenght; //draw axis at origin
        mRenderTarget->DrawLine(D2D1::Point2F(mOriginX, mOriginY),
                                D2D1::Point2F(basisYnewX, basisYnewY), mBrush, 2.f);
        mRenderTarget->DrawTextW(L"y", 1, mTextFormat, D2D1::RectF(basisYnewX, basisYnewY, 1000, 1000), mBrush);
    }

    //star image points
    const unsigned points = 5;
    float r = 100.f;
    D2D1_POINT_2F linePoint[points] = {
    D2D1::Point2F(   r*cos(rad(90))  ,    r* -sin(rad( 90))),//1
    D2D1::Point2F(   r*cos(rad(234)) ,   -(r*sin(rad(234)))),//2
    D2D1::Point2F(    r*cos(rad( 18)),     r*-sin(rad( 18))),//3
    D2D1::Point2F(    r*cos(rad(162)),     r*-sin(rad(162))),//4
    D2D1::Point2F(    r*cos(rad(306)),  -(r* sin(rad(306)))),//5
    };
    //offset
    float offsetX = 200;
    float offsetY = 20;
    for (auto& p : linePoint)
    {
        p.x += offsetX;
        p.y -= offsetY;
    }

    //rotation matrix|  3rd column is for translate the points to the origin (center of screen)
                //columns-> |   1   | |   2   |  |   3   |
    float R[3][3] = /*row1*/{ basisX.x, basisY.x, mOriginX ,

                    /*row2*/  basisX.y, basisY.y, mOriginY ,

                    /*row3*/    0    ,     0   ,       1
    };

    //for every point, apply rotation matrix
    for (size_t i = 0; i < points; i++)
    {
        D2D1_POINT_2F newPoint = D2D1::Point2F(
            R[0][0] * linePoint[i].x + R[0][1] * linePoint[i].y + R[0][2] * 1,//X
            R[1][0] * linePoint[i].x + R[1][1] * linePoint[i].y + R[1][2] * 1 //Y
        );
        linePoint[i] = newPoint;
    }

    //draw line
    mBrush->SetColor(D2D1::ColorF(0.87f, 0.3f, 0.36f, 1.f));
    for (size_t i = 0; i < points; i++)
    {
        if (i == points - 1) {//connect last point with first
            mRenderTarget->DrawLine(linePoint[i], linePoint[0], mBrush, 2.f);
        } else {
            mRenderTarget->DrawLine(linePoint[i], linePoint[i + 1], mBrush, 2.f);
        }

    }

}
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
Ed ecco la terza dimensione, in Direct2d :D
Comincio a capire come funziona la moltiplicazione tra matrici, e vettori, adesso sta tutto nel fare piu pratica (far funzionare quello nell'immagine sotto mi ha preso un bel pò di tempo e trial & error :S)

rGoTTgn.gif


Btw, per quelli che volessero capire cosa succede nell'immagine sopra, codice sotto. Il codice è davvero orribile, perchè sto facendo tutto dentro la draw() function (per poter vedere tutto quello che succede nel suo insieme) e tutto in maniera esplicità, senza funzioni di mezzo che moltiplicano matrici o altro, per vedere piu chiaramente dove e come quell'operazione si piazza nel contesto generale.
E tutto commentato quindi dovrebbe capirsi ugualmente.
CSS:
void Matrix2DClient::Draw()
{
    mRenderTarget->Clear(D2D1::ColorF(0.34f, 0.39f, 0.4f, 1.0f));
    makeGrid(100);

    mHandle->draw();

    //constant rotation between 0 and 360°
    static float constRotation;
    constRotation += constRotation + 1.7 < 360 ? 1.7 : -constRotation;

    float angle = mHandle->getHandleAngle(); //Wheel Handle angle in degree
 
    //cube points
    const unsigned points = 8;
    std::array<std::array<float, 3>, points> cubePoint = {
       -70.82,   -112.90,   -40.75,//0
       -0.34 ,   -170.82,      0.2,//1
         0.11,   -112.90,    81.71,//2
       -70.59,    -54.97,    40.75,//3
         0.34,      2.38,     -0.2,//4
         0.11,    -55.54,   -81.71,//5
        70.59,   -113.46,   -40.75,//6
        70.82,    -55.54,    40.75 //7
    };
    //rotation matrix on axis X
    float RX[3][3] = { 1     ,      0     ,     0     ,

                         0       ,cos(rad(0)) ,sin(rad(0)),

                         0     ,-sin(rad(0)),cos(rad(0))
    };
    //rotation matrix on axis Y
    float RY[3][3] = { cos(rad(constRotation)),     0     ,-sin(rad(constRotation)),

                               0      ,             1     ,           0            ,

                       sin(rad(constRotation)),     0,      cos(rad(constRotation))
    };
    //rotation matrix on axis Z
    float RZ[3][3] = { cos(rad(angle)),  sin(rad(angle)),  0,

                      -sin(rad(angle)),  cos(rad(angle)),  0,

                             0        ,         0       ,  1
    };

    std::array<std::array<float, 3>, 3> finalMatrix = mBasisVectors;
    std::array<std::array<float, 3>, 3> intermediateMatrix1 = mBasisVectors;
    std::array<std::array<float, 3>, 3> intermediateMatrix2 = mBasisVectors;

    //rotate on axis X  (basisVectors x RotationX) = intermediateMatrix1
    for (size_t i = 0; i < 3; i++)
    {
        for (size_t j = 0; j < 3; j++)
        {
            float sum = 0;
            for (size_t k = 0; k < 3; k++)
            {
                sum += mBasisVectors[i][k] * RX[k][j];
            }
            intermediateMatrix1[i][j] = sum;
        }
    }
    //rotate on axis Y (intermediateMatrix1 x RotationY) = intermediateMatrix2

    for (size_t i = 0; i < 3; i++)
    {
        for (size_t j = 0; j < 3; j++)
        {
            float sum = 0;
            for (size_t k = 0; k < 3; k++)
            {
                sum += intermediateMatrix1[i][k] * RY[k][j];
            }
            intermediateMatrix2[i][j] = sum;
        }
    }

    //rotate on axis Z (intermediateMatrix2 x RotationZ) = finalMatrix
    for (size_t i = 0; i < 3; i++)
    {
        for (size_t j = 0; j < 3; j++)
        {
            float sum = 0;
            for (size_t k = 0; k < 3; k++)
            {
                sum += intermediateMatrix2[i][k] * RZ[k][j];
            }
            finalMatrix[i][j] = sum;
        }
    }

    //for every point, apply the rotation finalMatrix
    std::array<std::array<float, 3>, 8> temporaryPoints = cubePoint;
    for (size_t i = 0; i < points; i++)
    {
        cubePoint[i][0] = temporaryPoints[i][0] * finalMatrix[0][0] + temporaryPoints[i][1] * finalMatrix[0][1] + temporaryPoints[i][2] * finalMatrix[0][2];//X
        cubePoint[i][1] = temporaryPoints[i][0] * finalMatrix[1][0] + temporaryPoints[i][1] * finalMatrix[1][1] + temporaryPoints[i][2] * finalMatrix[1][2];//Y
        cubePoint[i][2] = temporaryPoints[i][0] * finalMatrix[2][0] + temporaryPoints[i][1] * finalMatrix[2][1] + temporaryPoints[i][2] * finalMatrix[2][2];//Z
    }

    //draw cube. The points are calculated using x,y,z and the lines are drawn on screen using only x and y
    mBrush->SetColor(D2D1::ColorF(0.17f, 0.83f, 0.96f, 1.f));
    float strokeSize = 2.f;
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[0][0], mOriginY + cubePoint[0][1]), D2D1::Point2F(mOriginX + cubePoint[1][0], mOriginY + cubePoint[1][1]), mBrush, strokeSize);
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[1][0], mOriginY + cubePoint[1][1]), D2D1::Point2F(mOriginX + cubePoint[6][0], mOriginY + cubePoint[6][1]), mBrush, strokeSize);
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[6][0], mOriginY + cubePoint[6][1]), D2D1::Point2F(mOriginX + cubePoint[5][0], mOriginY + cubePoint[5][1]), mBrush, strokeSize);
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[5][0], mOriginY + cubePoint[5][1]), D2D1::Point2F(mOriginX + cubePoint[0][0], mOriginY + cubePoint[0][1]), mBrush, strokeSize);
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[1][0], mOriginY + cubePoint[1][1]), D2D1::Point2F(mOriginX + cubePoint[2][0], mOriginY + cubePoint[2][1]), mBrush, strokeSize);
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[6][0], mOriginY + cubePoint[6][1]), D2D1::Point2F(mOriginX + cubePoint[7][0], mOriginY + cubePoint[7][1]), mBrush, strokeSize);
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[5][0], mOriginY + cubePoint[5][1]), D2D1::Point2F(mOriginX + cubePoint[4][0], mOriginY + cubePoint[4][1]), mBrush, strokeSize);
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[0][0], mOriginY + cubePoint[0][1]), D2D1::Point2F(mOriginX + cubePoint[3][0], mOriginY + cubePoint[3][1]), mBrush, strokeSize);
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[3][0], mOriginY + cubePoint[3][1]), D2D1::Point2F(mOriginX + cubePoint[2][0], mOriginY + cubePoint[2][1]), mBrush, strokeSize);
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[2][0], mOriginY + cubePoint[2][1]), D2D1::Point2F(mOriginX + cubePoint[7][0], mOriginY + cubePoint[7][1]), mBrush, strokeSize);
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[7][0], mOriginY + cubePoint[7][1]), D2D1::Point2F(mOriginX + cubePoint[4][0], mOriginY + cubePoint[4][1]), mBrush, strokeSize);
    mRenderTarget->DrawLine(D2D1::Point2F(mOriginX + cubePoint[4][0], mOriginY + cubePoint[4][1]), D2D1::Point2F(mOriginX + cubePoint[3][0], mOriginY + cubePoint[3][1]), mBrush, strokeSize);
}
 
Ultima modifica:
  • Mi piace
Reazioni: Mursey

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili