#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    12
    Rep Power
    0

    Help optimize Infinite bouncing program.


    Hi,

    I had created a program to cause an object to bounce infinitely within a 40x20 grid. Upon colliding with the boundary, it will change the object trajectory with a new vector that is preset from a list randomly according to the boundary restrictions.

    However, the vectors are hardcoded and I wonder if there is any intelligent way to optimize it?

    This is the code, thanks!!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    
    typedef struct
    {
        int x,y;
    }ObjCoord;
    
    void randDir(ObjCoord *vec, int randcounter);
    void intBeep(ObjCoord *vec); // prints vector information on hit
    
    int main()
    {
        srand(time(NULL));
    
        int gridscale = 2;
    
        ObjCoord obj;
        ObjCoord vec;
    
        obj.x=10*gridscale;
        obj.y=5*gridscale;
    
        vec.x=2;
        vec.y=1;
    
    
        do
        {
            if(obj.x>20*gridscale)  // If obj shoots out of border when vector = 2, set back to 0.
                obj.x=20*gridscale;
            else if(obj.y>10*gridscale)
                obj.y=10*gridscale;
            else if(obj.x<0)
                obj.x=0;
            else if(obj.y<0)
                obj.y=0;
    
    
    
            Sleep(50);  // refresh rate.
            system("cls");  // refresh the screen.
    
    
            printf("Obj.x: %i", obj.x/2);       // Print Coord data
            if (obj.x>20*gridscale || obj.x<0)
                printf("ERROR\n");
            else
                printf("\n");
            printf("Obj.y: %i", obj.y);
            if (obj.y>10*gridscale || obj.y<0)
                printf("ERROR\n");
            else
                printf("\n\n");
    
            for (int i = 0; i<obj.y; i++)
                printf("\n");
            for (int i = 0; i<obj.x; i++)   // Print the empty space till obj
                printf(" ");
    
    
            printf("%c%c", 178,178);    //Print the obj
    
            int randcounter;
    
            if(obj.x>20*gridscale-1 && obj.y>10*gridscale-1) // IF greater than bottom right
            {
                do
                {
                    randcounter=(rand() %16)+1;
                    randDir(&vec,randcounter);
                }
                while(randcounter ==1 || randcounter ==3 || randcounter ==5 || randcounter ==6 || randcounter ==7 || randcounter ==8 || randcounter ==9 || randcounter ==10 || randcounter ==13 || randcounter ==14 || randcounter ==15);
    
                intBeep(&vec);
            }
            else if(obj.x<1 && obj.y<1) // IF greater than top left
            {
    
                do
                {
                    randcounter=(rand() %16)+1;
                    randDir(&vec,randcounter);
                }
                while(randcounter ==2 || randcounter ==4 || randcounter ==7 || randcounter ==8 || randcounter ==9 || randcounter ==10 || randcounter ==11 || randcounter ==12 || randcounter ==14 || randcounter ==15 || randcounter ==16);
    
                intBeep(&vec);
            }
            else if(obj.x>20*gridscale-1 && obj.y<1) // IF greater than top right
            {
                do
                {
                    randcounter=(rand() %16)+1;
                    randDir(&vec,randcounter);
                }
                while(randcounter ==2 || randcounter ==3 || randcounter ==5 || randcounter ==6 || randcounter ==9 || randcounter ==10 || randcounter ==11 || randcounter ==12 || randcounter ==13 || randcounter ==14 || randcounter ==16);
    
                intBeep(&vec);
            }
            else if(obj.x<1 && obj.y>10*gridscale-1) // IF greater than bottom left
            {
    
                do
                {
                    randcounter=(rand() %16)+1;
                    randDir(&vec,randcounter);
                }
                while(randcounter ==1 || randcounter ==4 || randcounter ==5 || randcounter ==6 || randcounter ==7 || randcounter ==8 || randcounter ==11 || randcounter ==12 || randcounter ==13 || randcounter ==15 || randcounter ==16);
    
                intBeep(&vec);
            }
            else if(obj.x<1)    // IF greater than left
            {
                if (   !((vec.x == 0 && vec.y == 1)||(vec.x == 0 && vec.y == -1))    )
                {
                    do
                    {
                        randcounter=(rand() %16)+1;
                        randDir(&vec,randcounter);
                    }
                    while(randcounter ==4 || randcounter ==7 || randcounter ==8 || randcounter ==11 || randcounter ==12 || randcounter ==15 || randcounter ==16);
    
                    intBeep(&vec);
                }
            }
            else if(obj.y<1)    // IF greater than top
            {
                if (   !((vec.x == 2 && vec.y == 0)||(vec.x == -2 && vec.y == 0))    )
                {
                    do
                    {
                        randcounter=(rand() %16)+1;
                        randDir(&vec,randcounter);
                    }
                    while(randcounter ==2 || randcounter ==9 || randcounter ==10 || randcounter ==11 || randcounter ==12 || randcounter ==14 || randcounter ==16);
    
                    intBeep(&vec);
                }
    
            }
            else if(obj.x>20*gridscale-1)   // IF greater than right
            {
                if (   !((vec.x == 0 && vec.y == 1)||(vec.x == 0 && vec.y == -1))    )
                {
                    do
                    {
                        randcounter=(rand() %16)+1;
                        randDir(&vec,randcounter);
                    }
                    while(randcounter ==3 || randcounter ==5 || randcounter ==6 || randcounter ==9 || randcounter ==10 || randcounter ==13 || randcounter ==14);
    
                    intBeep(&vec);
                }
    
            }
            else if(obj.y>10*gridscale-1)   // IF greater than bottom
            {
                if (   !((vec.x == 2 && vec.y == 0)||(vec.x == -2 && vec.y == 0))    )
                {
                    do
                    {
                        randcounter=(rand() %16)+1;
                        randDir(&vec,randcounter);
                    }
                    while(randcounter ==1 || randcounter ==5 || randcounter ==6 || randcounter ==7 || randcounter ==8 || randcounter ==13 || randcounter ==15);
    
                    intBeep(&vec);
                }
    
            }
    
    
            obj.x=obj.x+vec.x;  //add vector to obj for next frame
            obj.y=obj.y+vec.y;
    
    
        }
        while(gridscale<100); //seet infinite loop
    
        return 0;
    }
    
    void randDir(ObjCoord *vec, int randcounter)
    {
    
    
        switch (randcounter) // List of all possible vectors
        {
            case 1:
            {
                vec->x=0;
                vec->y=1;
                break;
            }
            case 2:
            {
                vec->x=0;
                vec->y=-1;
                break;
            }
            case 3:
            {
                vec->x=2;
                vec->y=0;
                break;
            }
            case 4:
            {
                vec->x=-2;
                vec->y=0;
                break;
            }
            case 5:
            {
                vec->x=2;
                vec->y=1;
                break;
            }
            case 6:
            {
                vec->x=4;
                vec->y=1;
                break;
            }
            case 7:
            {
                vec->x=-2;
                vec->y=1;
                break;
            }
            case 8:
            {
                vec->x=-4;
                vec->y=1;
                break;
            }
            case 9:
            {
                vec->x=2;
                vec->y=-1;
                break;
            }
            case 10:
            {
                vec->x=4;
                vec->y=-1;
                break;
            }
            case 11:
            {
                vec->x=-2;
                vec->y=-1;
                break;
            }
            case 12:
            {
                vec->x=-4;
                vec->y=-1;
                break;
            }
            case 13:
            {
                vec->x=2;
                vec->y=2;
                break;
            }
            case 14:
            {
                vec->x=2;
                vec->y=-2;
                break;
            }
            case 15:
            {
                vec->x=-2;
                vec->y=2;
                break;
            }
            case 16:
            {
                vec->x=-2;
                vec->y=-2;
                break;
            }
        }
    
    }
    
    void intBeep(ObjCoord *vec) // prints vector information on hit
    {
        printf("%i,", vec->x/2);
        printf("%i", vec->y);
        Beep(500,100);
    }
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,403
    Rep Power
    1871
    First I would do something like this (case statements which look like arrays should be arrays)
    Code:
    void randDir(ObjCoord *vec, int randcounter)
    {
      static ObjCoord dirs[] = {
        { 0, 0 },
        { 0, 1 },
        { 0, -1 },
        { 2, 0 },
        { -2, 0 },
        { 2, 1 },
        { 4, 1 },
        { -2, 1 },
        { -4, 1 },
        { 2, -1 },
        { 4, -1 },
        { -2, -1 },
        { -4, -1 },
        { 2, 2 },
        { 2, -2 },
        { -2, 2 },
        { -2, -2 },
      };
      *vec = dirs[randcounter];
    }
    Then I would eliminate the guessing loops, by having an array of valid values
    Code:
            if(obj.x>20*gridscale-1 && obj.y>10*gridscale-1) // IF greater than bottom right
            {
              static int r[] = { 2, 4, 11, 12, 16 };        // valid directions
              randcounter=(rand() % (sizeof(r)/sizeof(*r)); // a random array element
              randDir(&vec,r[randcounter]);                 // a random valid direction
              intBeep(&vec);
            }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    12
    Rep Power
    0
    Great thanks!! Never thought that size of can be used this way!
  6. #4
  7. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,403
    Rep Power
    1871
    Originally Posted by KaiserBreath
    Great thanks!! Never thought that size of can be used this way!
    Yes, but it only works when you have a true array in scope.

    It does NOT work if you just have a pointer to an array, say if you called a function with an array parameter.

    Comments on this post

    • codergeek42 agrees : Very handy, if with a huge caveat. Thanks.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    12
    Rep Power
    0
    Originally Posted by salem
    Yes, but it only works when you have a true array in scope.

    It does NOT work if you just have a pointer to an array, say if you called a function with an array parameter.
    Yep I understand that because it only reads the size of the 1st element and not the total amount of elements.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2008
    Posts
    259
    Rep Power
    128
    Yeah, sure is a way to optimize the program. So long as by optimize, you don't mean in terms of execution speed..

    You could use vector reflection to calculate the new direction based on (1) a direction vector of the item to bounce and (2) the surface normal of the surface being bounced off.

    Here's the code to reflect a vector around another. I use this code for calculating the reflected vector of a light source on a 3d plane, but it's the same math for 2d vectors.

    Code:
    vec3 reflectVector(vec3 &surfaceNormal, vec3 &lightDir)
    {
        vec3 reflected;
        vec3 N, L;
        double NdotL;
    
        N = normalize(surfaceNormal);
        L = normalize(lightDir);
        NdotL = dotProduct(N, L);
    
        reflected = L - (N * 2.0 * NdotL);
    
        return reflected;
    }
    Calling the function with a surface normal of (0,1,0) and a direction vector of (-1,-1,0) results in a reflected vector of (-1,1,0)

    That is to say, if we bounce an object moving downwards and to the left, it's reflection on the floor causes it to continue moving to the left, but moving upwards instead of down.

    Here's the auxillary code - just remove the .z term from the dotProduct and you're basically done. I actually have it all wrapped up as a class, but that should be of no consequence for the purposes of this discussion. Though you will notice the definition of the * operator for a vec3 and a double.

    Code:
    struct vec3
    {
        double x,y,z;
    };
    
    double dotProduct(vec3 &a, vec3 &b)
    {
        return a.x*b.x + a.y*b.y + a.z*b.z;
    }
    double vecLen(vec3 &a)
    {
        return sqrt(dotProduct(a,a));
    }
    vec3 normalize(vec3 &a)
    {
        vec3 result;
        double len = vecLen(a), scale=0;
        scale = 1.0 / len;
        result = a * scale;
        return result;
    }
    
    vec3 vec3::operator*(const double &rhs)
    {
        return vec3(x*rhs,y*rhs,z*rhs);
    }
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    12
    Rep Power
    0
    Hi, can you explain the last 2 line? I tired inputing (0,1,0) and (-1,-1,0) but the reflected vector is not (-1,1,0).
    Also, you can multiply the whole struct by a variable?

    Code:
    vec3 reflectVector(vec3 &surfaceNormal, vec3 &lightDir)
    {
        vec3 reflected;
        vec3 N, L;
        double NdotL;
    
        N = normalize(surfaceNormal);	//Gets normalized vector of surface to unit length (0,1,0). Surface is pointing upwards towards y.
        L = normalize(lightDir);		//Gets normalized vector of dir to unit length (-0.707106,-0.707106,0). Light approaching surface 45degree in south-west direction.
        NdotL = dotProduct(N, L);		//Gets (0,-0.707106,0)?? What is this for?
    
    
        reflected = L - (N * 2.0 * NdotL);	//(-0.707,-0.707,0) - [(0,1,0)*2*(0,-0.707,0)] = (-0.707,-0.707,0) - (0, -1.414, 0) = (-0.707, -2.12, 0)?? Totally don't understand this formula.
    
        return reflected;
    }
    Do have have any sites or books to recommend to learn such stuffs more in depth?

    Thanks!
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2008
    Posts
    259
    Rep Power
    128
    Originally Posted by KaiserBreath
    Hi, can you explain the last 2 line? I tired inputing (0,1,0) and (-1,-1,0) but the reflected vector is not (-1,1,0).
    Also, you can multiply the whole struct by a variable?

    Do have have any sites or books to recommend to learn such stuffs more in depth?

    Thanks!
    Yeah sure.
    The problem appears to be in the term you are using for NdotL. Notice, it's actually a scalar, not a vector (its 1D, not 3D)

    I just added code to print N, L and NdotL. They're:
    Code:
    N = < 0.000, 1.000, 0.000>
    L = <-0.707,-0.707, 0.000>
    NdotL = -0.707107
    So, this would make the calculation of reflected look something like this:

    Code:
    R = L - (N * 2.0 * NdotL) 
    
    reflected = <-0.707,-0.707,0> - ( <0, 1, 0> * 2 * -0.707 )
                 = <-0.707,-0.707,0> - ( <0, 1, 0> * -1.414 )
                 = <-0.707,-0.707,0> - <0, -1.414, 0> 
                 = <-0.707, 0.707,0>
    Ah! I just realized that there is something implied but not said - the reflected vector is a unit vector. It's the same direction, but of unit length. To make sure that the reflected vector is <-1, 1, 0>, you have to multiply <-0.707, 0.707, 0> by the length of the original L ( <-1, -1, 0> ), which is sqrt(2), which is 1.414

    So VecLen(L) = 1.414
    VecLen(L) * Reflected = reflected vector of same length as L
    1.414 * <-0.707,0.707,0> = <-1, 1, 0>

    And nah, I don't have any books or sites to recommend. I just use google for whatever is presenting itself as a problem at the time. I bought a few books back in the 90s, but technology changes so fast I barely get any use. They'd be good references for vector/matrix math and for some shading equations, but I can get that online, and the books authors were still using PHIGS as a 3d library with their VAX 11/780's

    Here's a a quick sampler I whipped up, give it a try. It draws a horizontal line in the middle of the box which acts as the mirror. It then draws a blue line from your mouse cursor to the middle of the mirror and a red line that indicates the reflection of the blue line.

    main.cpp
    Code:
    #include <windows.h>
    #include "vec3.h"
    
    //  Declare Windows procedure
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK outputWindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
    
    //  Make the class name into a global variable
    char szClassName[ ] = "vectorReflectionApp";
    
    int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
    {
        HWND hwnd;               // This is the handle for our window
        MSG messages;            // Here messages to the application are saved
        WNDCLASSEX wincl;        // Data structure for the windowclass
    
        // The Window structure
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      // This function is called by windows
        wincl.style = CS_DBLCLKS;                 // Catch double-clicks
        wincl.cbSize = sizeof (WNDCLASSEX);
    
        // Use default icon and mouse-pointer
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_CROSS);
        wincl.lpszMenuName = NULL;                 // No menu
        wincl.cbClsExtra = 0;                      // No extra bytes after the window class
        wincl.cbWndExtra = 0;                      // structure or the window instance
        // Use Windows's default colour as the background of the window
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        // Register the window class, and if it fails quit the program
        if (!RegisterClassEx (&wincl))
            return 0;
    
        RECT mRect = {0,0,276,276};
        DWORD dwStyle, dwExStyle;
        dwStyle = WS_CAPTION | WS_VISIBLE | WS_SYSMENU;// GetWindowLong(hwnd, GWL_STYLE);
        dwExStyle = NULL; //GetWindowLong(hwnd, GWL_EXSTYLE);
        AdjustWindowRectEx(&mRect,dwStyle,false,dwExStyle);
    
    
        // The class is registered, let's create the program
        hwnd = CreateWindowEx (
               0,                   // Extended possibilites for variation
               szClassName,         // Classname
               "vectorReflection",       // Title Text
               WS_CAPTION | WS_VISIBLE | WS_SYSMENU, // default window
               CW_USEDEFAULT,       // Windows decides the position
               CW_USEDEFAULT,       // where the window ends up on the screen
               mRect.right-mRect.left, //544,                 // The programs width
               mRect.bottom-mRect.top, //375,                 // and height in pixels
               HWND_DESKTOP,        // The window is a child-window to desktop
               NULL,                // No menu
               hThisInstance,       // Program Instance handler
               NULL                 // No Window Creation data
               );
    
        CreateWindow("static","",WS_CHILD|WS_VISIBLE,10,10,256,256,hwnd,(HMENU)1000,hThisInstance,NULL);
    
        SetWindowLong(GetDlgItem(hwnd, 1000), GWL_WNDPROC, (long)outputWindowProcedure);
    
        // Make the window visible on the screen
        ShowWindow (hwnd, nCmdShow);
    
        // Run the message loop. It will run until GetMessage() returns 0
        while (GetMessage (&messages, NULL, 0, 0))
        {
            // Translate virtual-key messages into character messages
            TranslateMessage(&messages);
            // Send message to WindowProcedure
            DispatchMessage(&messages);
        }
    
        // The program return-value is 0 - The value that PostQuitMessage() gave
        return messages.wParam;
    }
    
    vec3 makeVec(int posX, int posY, int originX, int originY)
    {
        return vec3(originX-posX,originY-posY,0);
    }
    
    //  This function is called by the Windows function DispatchMessage()
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  // handle the messages
        {
            case WM_CREATE:
                return 0;
    
            case WM_DESTROY:
                PostQuitMessage (0);       // send a WM_QUIT to the message queue
                break;
            default:                      // for messages that we don't deal with
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
        return 0;
    }
    
    LRESULT CALLBACK outputWindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        PAINTSTRUCT ps;
        HDC hdc;
        RECT mRect;
        HBRUSH mBrush;
        HPEN mPen, oldPen;
        static POINT mousePos;
        static bool mouseOver = false;
        vec3 norm(0,1,0), incoming, reflected;
        double len;
        switch (message)
        {
            case WM_ERASEBKGND:
            return 0;
    
            case WM_SETCURSOR:      // use parent's cursor
            return 0;
    
            case WM_MOUSEMOVE:
                mouseOver = true;
                mousePos.x = LOWORD(lParam);
                mousePos.y = HIWORD(lParam);
                InvalidateRect(hwnd,NULL,false);
            return 0;
    
            case WM_PAINT:
                BeginPaint(hwnd, &ps);
                mBrush = (HBRUSH)CreateSolidBrush(RGB(255,200,200));
                mRect = {0,0,256,256};
                FillRect(ps.hdc, &mRect, mBrush);
                DeleteObject(mBrush);
                MoveToEx(ps.hdc, 0,128,NULL);
                LineTo(ps.hdc,256,128);
                if (mouseOver)
                {
                    incoming = makeVec(mousePos.x,mousePos.y,128,128);
                    len = vecLen(incoming);
                    reflected = reflectVector(norm, incoming) * len;
                    reflected.x += 128;
                    reflected.y += 128;
                    mPen = CreatePen(PS_SOLID,1,RGB(0,0,255));
                    oldPen = (HPEN)SelectObject(ps.hdc, mPen);
                    MoveToEx(ps.hdc,mousePos.x,mousePos.y,NULL);
                    LineTo(ps.hdc,128,128);
                    SelectObject(ps.hdc,oldPen);
                    DeleteObject(mPen);
                    mPen = CreatePen(PS_SOLID,1,RGB(255,0,0));
                    SelectObject(ps.hdc, mPen);
                    LineTo(ps.hdc,reflected.x,reflected.y);
                    SelectObject(ps.hdc,oldPen);
                    DeleteObject(mPen);
                }
                EndPaint(hwnd, &ps);
            return 0;
    
            case WM_DESTROY:
            return 0;
        }
        return DefWindowProc (hwnd, message, wParam, lParam);
    }

    vec3.h
    Code:
    #ifndef VEC3_H
    #define VEC3_H
    
    class vec3
    {
        public:
    //        vec3();
            vec3():x(0),y(0),z(0){}
            vec3(double initX, double initY, double initZ): x(initX),y(initY),z(initZ) {}
    
            ~vec3();
            vec3(const vec3& other);
            vec3& operator=(const vec3& other);
    
            vec3 operator*(const double &scale);
            vec3 operator-(const vec3 &rhs);
    
            void print();
    
            double x; //!< Member variable "x;"
            double y; //!< Member variable "y;"
            double z; //!< Member variable "z;"
    };
    
    vec3 reflectVector(vec3 &surfaceNormal, vec3 &lightDir);
    vec3 reflect(vec3 &d, vec3 &n);
    vec3 reflect(vec3 &light, vec3 &eye, vec3 &pnt, vec3 &norm);
    
    double dotProduct(vec3 &a, vec3 &b);
    vec3 crossProduct(vec3 &a, vec3 &b);
    vec3 normalize(vec3 &a);
    double vecLen(vec3 &a);
    
    #endif // VEC3_H
    vec3.cpp
    Code:
    #include "vec3.h"
    #include <math.h>
    #include <stdio.h>
    
    vec3::~vec3()
    {
        //dtor
    }
    
    vec3::vec3(const vec3& other)
    {
        //copy ctor
        x=other.x;
        y=other.y;
        z=other.z;
    }
    
    vec3& vec3::operator=(const vec3& rhs)
    {
        if (this == &rhs) return *this; // handle self assignment
        //assignment operator
        x = rhs.x;
        y = rhs.y;
        z = rhs.z;
        return *this;
    }
    vec3 vec3::operator*(const double &rhs)
    {
        return vec3(x*rhs,y*rhs,z*rhs);//*this;
    }
    vec3 vec3::operator-(const vec3 &rhs)
    {
        return  vec3(x-rhs.x,y-rhs.y,z-rhs.z);//*this;
    }
    
    double vecLenSq(vec3 &a)
    {
        return a.x*a.x + a.y*a.y + a.z*a.z;
    }
    
    double vecLen(vec3 &a)
    {
        return sqrt(dotProduct(a,a));
    }
    
    vec3 normalize(vec3 &a)
    {
        vec3 result;
        double len = vecLen(a), scale=0;
        scale = 1.0 / len;
        result = a * scale;
        return result;
    }
    
    //vec3 reflectVector(vec3 &aroundMe, vec3 &refletMe)
    vec3 reflectVector(vec3 &surfaceNormal, vec3 &lightDir)
    {
        vec3 reflected;
        vec3 N, L;
        double NdotL;
    
        N = normalize(surfaceNormal);
        L = normalize(lightDir);
        NdotL = dotProduct(N, L);
    
        reflected = L - (N * 2.0 * NdotL);
        return reflected;
    }
    
    void vec3::print()
    {
        printf("<%6.3f,%6.3f,%6.3f>\n", x, y, z);
    }
    
    double dotProduct(vec3 &a, vec3 &b)
    {
        return a.x*b.x + a.y*b.y + a.z*b.z;
    }
    
    vec3 crossProduct(vec3 &a, vec3 &b)
    {
        return vec3(
                    a.y*b.z - b.y*a.z,
                    a.z*b.x - b.z*a.x,
                    a.x*b.y - b.x*a.y
                    );
    }
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    12
    Rep Power
    0
    Hi,

    Great stuffs!! But for a beginner like me, these are too much for me to absorb, I can't even compile it with codeblocks. Which compiler did you use?

    Anyway I think now I understand the reflection part.

    Thanks!
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2008
    Posts
    259
    Rep Power
    128
    Originally Posted by KaiserBreath
    Hi,

    Great stuffs!! But for a beginner like me, these are too much for me to absorb, I can't even compile it with codeblocks. Which compiler did you use?

    Anyway I think now I understand the reflection part.

    Thanks!
    Great, oh that's a shame. I'd hoped running the executable would help make it more understandable.

    Not sure why it wouldn't compile. I've not used any new features of c++ in it. At the moment, I'm using Code::Blocks 12.11 and gcc(g++) version v 4.7.2

    Well, if the reflection is understood, then that sounds like a win, even if it's not a resounding one.. Oh well, time for a :cadrunk:
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    12
    Rep Power
    0
    Hmm, not sure.. first error is unknown type name 'class' when read till the header.
  22. #12
  23. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,403
    Rep Power
    1871
    > Hmm, not sure.. first error is unknown type name 'class' when read till the header.
    Yeah, you get that when you try to compile C++ code with a C compiler.

    Make sure you name your files like prog.cpp.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper

IMN logo majestic logo threadwatch logo seochat tools logo