C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old March 11th, 2013, 12:47 AM
KaiserBreath KaiserBreath is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2013
Posts: 12 KaiserBreath User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 58 m 22 sec
Reputation 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);
}

Reply With Quote
  #2  
Old March 11th, 2013, 04:00 AM
salem's Avatar
salem salem is offline
Contributed User
Click here for more information
 
Join Date: Jun 2005
Posts: 3,905 salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)  Folding Points: 153 Folding Title: Novice Folder
Time spent in forums: 2 Months 3 Weeks 4 Days 1 h 9 m 41 sec
Reputation Power: 1774
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

Reply With Quote
  #3  
Old March 11th, 2013, 04:27 AM
KaiserBreath KaiserBreath is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2013
Posts: 12 KaiserBreath User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 58 m 22 sec
Reputation Power: 0
Great thanks!! Never thought that size of can be used this way!

Reply With Quote
  #4  
Old March 11th, 2013, 08:09 AM
salem's Avatar
salem salem is offline
Contributed User
Click here for more information
 
Join Date: Jun 2005
Posts: 3,905 salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)  Folding Points: 153 Folding Title: Novice Folder
Time spent in forums: 2 Months 3 Weeks 4 Days 1 h 9 m 41 sec
Reputation Power: 1774
Quote:
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.

Reply With Quote
  #5  
Old March 11th, 2013, 08:12 AM
KaiserBreath KaiserBreath is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2013
Posts: 12 KaiserBreath User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 58 m 22 sec
Reputation Power: 0
Quote:
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.

Reply With Quote
  #6  
Old March 12th, 2013, 02:11 PM
SimonB2 SimonB2 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Apr 2008
Posts: 249 SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 3 Days 17 h 55 m 47 sec
Reputation Power: 110
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);
}

Reply With Quote
  #7  
Old March 12th, 2013, 09:59 PM
KaiserBreath KaiserBreath is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2013
Posts: 12 KaiserBreath User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 58 m 22 sec
Reputation 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!

Reply With Quote
  #8  
Old March 13th, 2013, 09:15 PM
SimonB2 SimonB2 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Apr 2008
Posts: 249 SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 3 Days 17 h 55 m 47 sec
Reputation Power: 110
Quote:
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
                );
}

Reply With Quote
  #9  
Old March 13th, 2013, 10:20 PM
KaiserBreath KaiserBreath is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2013
Posts: 12 KaiserBreath User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 58 m 22 sec
Reputation 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!

Reply With Quote
  #10  
Old March 13th, 2013, 10:34 PM
SimonB2 SimonB2 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Apr 2008
Posts: 249 SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level)SimonB2 User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 3 Days 17 h 55 m 47 sec
Reputation Power: 110
Quote:
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

Reply With Quote
  #11  
Old March 13th, 2013, 10:37 PM
KaiserBreath KaiserBreath is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2013
Posts: 12 KaiserBreath User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 58 m 22 sec
Reputation Power: 0
Hmm, not sure.. first error is unknown type name 'class' when read till the header.

Reply With Quote
  #12  
Old March 14th, 2013, 01:45 AM
salem's Avatar
salem salem is offline
Contributed User
Click here for more information
 
Join Date: Jun 2005
Posts: 3,905 salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)  Folding Points: 153 Folding Title: Novice Folder
Time spent in forums: 2 Months 3 Weeks 4 Days 1 h 9 m 41 sec
Reputation Power: 1774
> 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.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > Help optimize Infinite bouncing program.

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap