Thread: Math...

  1. #1
    Registered User
    Join Date
    May 2003
    Posts
    67

    Math...

    okay lets face it: I SUCK AT MATH...

    Im finally starting to get some grip on basic C programming and mad a step forward by starting the OpenGL tutorials @ NeHe (which are in my opinion very clear for someone like me), but i looked on at the chapters and he's even gonna cover bump mapping etc, but I think my math sucks too much for this, does anyone have some tips for me to brush on with my logic and math skills, i really think it would make a difference.
    (or am i just spitting BS as usual?)
    thanx

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I wouldn't let your knowledge of math or lack thereof deter you from programming. Personally I did not understand a lot of the math they taught me in school because it was just too abstract. But when you get to physically 'see' what the math is doing you will catch on very quick. Most of the math in 3D programming has already been done for you. Go over to www.gamedev.net and browse their many useful articles concerning matrices and 3D, math, etc. Most of the articles are very straightforward and do not dive into the formulas behind the 3D - though some do.

    Most of the math in 3D is based on 2 simple equations called the perspective transform.

    int screenx=(viewx*focus)/viewz;
    int screeny=(viewy*focus)/viewz;
    screenx+=center_screen_x;
    screeny+=center_screen_y;


    This will convert any 3D coord into 2D screen space. Try it for yourself and you will start to see it all come together. Then when you need more - consult some articles and try to implement them into your code as is. Later on with more knowledge you will be able to modify that code as well to suit your needs.

    The focus is simply the distance the viewer is from the screen - or the projection plane to be technical. Basically small numbers are like smashing your face against the screen and large numbers would be like slowly walking away from the screen.

    To get you started here is a very simple starfield example - I'm coding this from my head so you might wanna check it for errors.

    I'll stick to simple C structures and will not dive into the graphics portion of the code.


    Code:
    struct point2D
    {
      int x;
      int y;
    };
    
    struct point3D
    {
      double x;
      double y;
      double z;
    };
    
    struct SimpleVertex
    {
      point3D Local;
      point2D Screen;
    };
    
    #define NUMSTARS 100
    #define VIEWDIST 320
    #define CENTER_X 160
    #define CENTER_Y 100
    #define WHITE 15
    
    SimpleVertex Stars[NUMSTARS];
    
    void CreateStars(void);
    void MoveStars(double speed);
    void ProjectStars(void)
    void DrawStars(void); 
    
    
    
    void CreateStars(void);
    {
      for (int i=0;i<NUMSTARS;i++)
      {
         Stars[i].Local.x=-320+random(640);
         Stars[i].Local.y=-200+random(400);
         Stars[i].Local.z=random(100);
      }
    }
    
    void MoveStars(double speed)
    {
      for (int i=0;i<NUMSTARS;i++)
      {
        Stars[i].local.z+=speed;
        if (Stars[i].local.z>100)
        {
          Stars[i].Local.x=-320+random(640);
          Stars[i].Local.y=-200+random(400);
          Stars[i].Local.z=random(100);
        }
      }
    }
    
    void ProjectStars(void)
    {
      for (int i=0;i<NUMSTARS;i++)
      {
         double x=Stars[i].Local.x;
         double y=Stars[i].Local.y;
         double z=Stars[i].Local.z;
         
         if (z<1.0) z=1.0; 
         Stars[i].Screen.x=(int)((x*(double)VIEWDIST)/z+(double)CENTER_X);
         Stars[i].Screen.y=(int)((y*(double)VIEWDIST)/z+(double)CENTER_Y);
       }
    }
    
    void DrawStars(void)
    {
      for (int i=0;i<NUMSTARS;i++)
      {
        int x=Stars[i].Screen.x;
        int y=Stars[i].Screen.y; 
        if (x>0 && x<320)
        {
           if (y>0 && y<200)
           { 
              PlotPixel(x,y,WHITE);
           }
         }
       }
    }
    
    int main(void)
    {
       double MySpeed=.5;
       CreateStars();
       while (!kbhit())
       {
          //Clear the screen here
          MoveStars(MySpeed);
          ProjectStars();
          DrawStars();
        }
        return(0);
    }
    I did not include the graphics stuff on purpose. PlotPixel() should do just what it says. You might have some data type problems inside of ProjectStars() when converting from double to int. If you do let me know and I'll fix it. Hope it works. Then try to code this on OpenGL or something. Hope you have a DOS platform - much of the problem in graphics now is that you are forced to learn an API which has a much steeper learning curve than just plain old DOS. No I'm not a DOS advocate, but it is simpler at first.

  3. #3
    Registered User
    Join Date
    May 2003
    Posts
    67

    thanx for the replies

    thanx guys tomorrow I'll take a deeper look into it (it's so quiet at work right now)
    Code:
    // Pulsing Colors Based On Text Position
    	glColor3f(1.0f*float(cos(cnt1)),1.0f*float(sin(cnt2)),1.0f-0.5f*float(cos(cnt1+cnt2)));
    these sort of thing just confuse me

    Allright.. ive been stdying for this entire day now figuring out, and it isnt as hard as it looks thanx!!
    Last edited by TeQno; 07-24-2003 at 06:53 AM.

  4. #4
    Registered User
    Join Date
    Jan 2003
    Posts
    118
    Bubba, I am quite a newbe in graphix programming and I am very interested in that stars program you made, so I tried to make it work as much as I could but I am missing the PlotPixel function and I have no idea how to make it, if it is not very complicated and you are willing to make the function and post it here for me to include into the program, I would really appreciate it.
    This is youre program with only one error:
    Code:
    #include <iostream>
    #include <windows.h>
    #include <conio.h>
    using namespace std;
    
    #define NUMSTARS 100
    #define VIEWDIST 320
    #define CENTER_X 160
    #define CENTER_Y 100
    #define WHITE 15
    
    struct point2D
    {
    	int x;
    	int y;
    };
    
    struct point3D
    {
    	double x;
    	double y;
    	double z;
    };
    
    struct SimpleVertex
    {
    	point3D Local;
    	point2D Screen;
    };
    
    SimpleVertex Stars[NUMSTARS];
    
    void CreateStars();
    void MoveStars(double speed);
    void ProjectStars();
    void DrawStars(); 
    int Random(int Limit);
    
    void CreateStars()
    {
    	for (int i=0;i<NUMSTARS;i++)
    	{
    		Stars[i].Local.x=-320+Random(640);
    		Stars[i].Local.y=-200+Random(400);
    		Stars[i].Local.z=Random(100);
    	}
    }
    
    void MoveStars(double speed)
    {
    	for (int i=0;i<NUMSTARS;i++)
    	{
    		Stars[i].Local.z+=speed;
    		if (Stars[i].Local.z>100)
    		{
    			Stars[i].Local.x=-320+Random(640);
    			Stars[i].Local.y=-200+Random(400);
    			Stars[i].Local.z=Random(100);
    		}
    	}
    }
    
    void ProjectStars()
    {
    	for (int i=0;i<NUMSTARS;i++)
    	{
    		double x=Stars[i].Local.x;
    		double y=Stars[i].Local.y;
    		double z=Stars[i].Local.z;
         
    		if (z<1.0) z=1.0; 
    		Stars[i].Screen.x=(int)((x*(double)VIEWDIST)/z+(double)CENTER_X);
    		Stars[i].Screen.y=(int)((y*(double)VIEWDIST)/z+(double)CENTER_Y);
    	}
    }
    
    void DrawStars()
    {
    	for (int i=0;i<NUMSTARS;i++)
    	{
    		int x=Stars[i].Screen.x;
    		int y=Stars[i].Screen.y; 
    		if (x>0 && x<320)
    		{
    			if (y>0 && y<200)
    			{ 
    				PlotPixel(x,y,WHITE);
    			}
    		}
    	}
    }
    
    int Random(int Limit)
    {
    	return (rand() % Limit + 1);
    }
    
    int main()
    {
    	double MySpeed=.5;
    	CreateStars();
    
    	srand(GetTickCount());
    
    	while (!kbhit())
    	{
    		//Clear the screen here
    		system("cls");
    		MoveStars(MySpeed);
    		ProjectStars();
    		DrawStars();
        }
        return(0);
    }
    Why drink and drive when you can smoke and fly?

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Well it looks like you are in console mode which is not going to work. If you could get a small DirectX startup module working you could plot pixels via DirectX and pointers to your double buffer and primary surfaces.

    The only way in console mode is to plot periods - which looks dumb and which is reverse of graphics. Text is in row,col which is actually y,x - also the values I used in the starfield program are much too large for text mode.

    For DOS users this code will complete the program. Note that I used some assembly - but you do not have to. For flipping the back buffer to the screen you could memcpy() and for clearing the screen use memset(). Please no stupid comments about the code not being portable, only for DOS, blah, blah, blah....
    Because this code can be used inside of a DirectX framework as well as D3D - but in D3D would be a bit different. The DirectX version of this code only lacks the back buffer and primary surface code (locking, unlocking, etc)- as well as the startup section.

    Code:
    //y*320+x - most compilers should turn this into the following
    #define XYTOMEM((y<<8)+(y<<6)+(x))
    
    //BYTE typedef 
    typedef unsigned char BYTE;
    
    //Real-mode pointers to double buffer and screen
    BYTE far *Screen;
    BYTE far *Buffer;
    
    //Prototypes
    void Init(void);
    void CLS(BYTE far *tBuffer,BYTE color);
    void Flip(void);
    void PlotPixel(int x,int y,BYTE color);
    
    //Init screen mode and pointers
    void Init(void)
    {
       REGS regs;
       regs.x.ax=0x0013;
       int86(0x10,& regs,& regs);
       Screen=(BYTE far *)MK_FP(0xa000,0);
       Buffer=new BYTE[64000L];
       //Should check for Buffer validity here, but didn't
    }
    
    //Clears any 64000 byte buffer to the set color
    void CLS(BYTE far *tBuffer,BYTE color)
    {
      asm {
       
         les       di,[tBuffer]
         mov     cx,07D00h   //32000 words
         mov     ah,[color]
         mov     al,[color]
         rep      stosw
      }
    }
    
    //Copies memory - uses words, not bytes
    //Copies back buffer to video memory
    void Flip(void)
    {
       asm {
    
          push      ds
          lds         si,[Buffer]
          les         di,[Screen]
          mov       cx,07D00h
          rep        movsw
          pop       ds
       }
    }
    
    //Plots a pixel - do not call this - place this in DrawStars() as is
    //Calling this inside of the draw loop slows the program down  
    void PlotPixel(int x,int y,BYTE color)
    {
      Buffer[XYTOMEM(x,y)]=color;
    }
    Here is the new main:

    Code:
    int main(void)
    {
       double MySpeed=.5;
       CreateStars();
       while (!kbhit())
       {
          CLS(Buffer,0);
          MoveStars(MySpeed);
          ProjectStars();
          DrawStars();
          Flip();
        }
        return(0);
    }
    Here is the new DrawStars()
    Code:
    void DrawStars()
    {
      for (int i=0;i<NUMSTARS;i++)
      {
         int x=Stars[i].Screen.x;
         int y=Stars[i].Screen.y; 
         if (x>0 && x<320)
         {
            if (y>0 && y<200)
           { 
             Buffer[XYTOMEM(x,y)]=WHITE;
           }
         }
      }
    }
    Last edited by VirtualAce; 07-24-2003 at 07:45 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Math
    By knightjp in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 04-01-2009, 05:36 PM
  2. Help with C++ Math
    By aonic in forum C++ Programming
    Replies: 4
    Last Post: 01-29-2005, 04:40 AM
  3. Basic Math Problem. Undefined Math Functions
    By gsoft in forum C Programming
    Replies: 1
    Last Post: 12-28-2004, 03:14 AM
  4. Math Header?
    By Rune Hunter in forum C++ Programming
    Replies: 26
    Last Post: 09-17-2004, 06:39 AM
  5. toughest math course
    By axon in forum A Brief History of Cprogramming.com
    Replies: 12
    Last Post: 10-28-2003, 10:06 PM