SDL Gamer

Search this site

Simple Case‎ > ‎

Exp2. Drawing A Mathematical Formula

This example demonstrate
Download Example File here :
ATest_sEx2.zip 667k

Screen Shot


Program Code
A LineTo Function can draw a line
 // This function will draw a line on surface "scr" from (x1,y1) to (x2,y2)
inline void LineTo(SDL_Surface *scr , int x1 , int y1 , int x2 , int y2 ) {
    SDL_Rect dotRect; // For drawing a dot
    int vtx , vty; // The vector from (x1,y1) to (x2,y2)
    int x = x1 , y = y1; // The coordinate of current interpolate point
    vtx = x2 - x1 ;
    vty = y2 - y1 ;
// This can deal with the single case
    if(vtx == 0 && vty == 0 ) {
        dotRect.x = x;
        dotRect.x = x;
        dotRect.w = dotRect.h = 2;
        SDL_FillRect(scr , &dotRect , 0xFFFF22);
        return;
        }
// This can deal with the single case
    if(vtx == 0) {
        dotRect.x = x;
        if(y1 < y2) dotRect.y = y1;
        if(y2 < y1) dotRect.y = y2;
        dotRect.w = 2 ;
        dotRect.h = abs(vty) ;
        SDL_FillRect(scr , &dotRect , 0xFFFF22);
        return;
        }
// This can deal with the single case
    if(vty == 0) {
        dotRect.y = y;
        if(x1 < x2) dotRect.x = x1;
        if(x2 < x1) dotRect.x = x2;
        dotRect.w = abs(vtx) ;
        dotRect.h = 2 ;
        SDL_FillRect(scr , &dotRect , 0xFFFF22);
        return;
        }
    // Case vtx >= vty
    // Take the bigger one as basis to draw a line , so we can
    // get a continuous line instead of a broken one.

    if( abs(vtx) >= abs(vty) ) {  // abs( x ) return absolute value of x
        while( abs(x-x1) <= abs(vtx) ) {
            y = y1 + vty * (x - x1) / vtx ; // Get y base on the ratio of x -x1 / vtx
            dotRect.x = x;
            dotRect.y = y;
            dotRect.w = dotRect.h = 2 ;
            SDL_FillRect(scr , &dotRect , 0xFFFF22);
            if(vtx>0) x++;
            if(vtx<0) x--;
            } // while( y - y1 < vty ) { END
        } // if( abs(vtx) >= abs(vty) ) {END
    // Case vtx < vty
    if( abs(vtx) < abs(vty) ) {
        while( abs(y - y1) <= abs(vty) ) {
            x = x1 + vtx * (y - y1) / vty ;
            dotRect.x = x;
            dotRect.y = y;
            dotRect.w = dotRect.h = 2 ;
            SDL_FillRect(scr , &dotRect , 0xFFFF22);
            if(vty>0) y++;
            if(vty<0) y--;
            } // while( y - y1 < vty ) { END
        } // if( abs(vtx) < abs(vty) ) { END
    return;
    }
// inline void LineTo(...) { END



Some tricks when using C++

 // Some small skill that good to know
// Take Absolute Value

inline int abs(int a) {return a>=0 ? a : (-a) ; }
inline int MaxNo(int a,int b) {return a>=b ? a : b ; }
inline bool MaxNo(float a,float b) {return a>=b ? 0 : 1 ; }

This is not a very important trick but good to know.

In the main program
#include <math.h> // For using sin( x ) function.   The unit of x is radian.

int main(int argc, char *argv[])
{
 SDL_Rect fn; // For drawing the point of a function
// The coordinate of an Object
short xidx = animRect.x , yidx = animRect.y;
short dstX , dstY ; // The destination for tracing
short angle , radius ; // Current Angle & Radius in a Circular Coordinate
float PI = 3.14159;
angle = 0 ;
radius = 100;
bool bExpand = 1; // The expand status of radius

while(bRun) {
    aTick++;
    SDL_FillRect(screen , NULL , 0x221122);
    angle ++ ;
    if( angle > 360 ) angle = 0 ;
    if( bExpand ) radius ++ ;
    if( !bExpand ) radius -- ;
    if( radius > 120 ) bExpand = 0;
    if( radius <  60 ) bExpand = 1;
        
    LineTo(screen , 20 , 280 , xidx , yidx );
    for(int i=0 ; i < 360 ; i++) {
        fn.w = fn.h = 2;
        fn.x = 200 + int ( radius * sin( i * 2 * PI / 360 )) ; // The x in Polar Coord.
        fn.y = 150 + int ( radius * cos( i * 2 * PI / 360 )) ;
        SDL_FillRect(screen , &fn , 0xFFFFFF);
        if( i == angle ) { // When meet the destination angle , using Red Color
            dstX = fn.x ; // Destination for tracing
            dstY = fn.y ;
            fn.w = fn.h = 8;
            fn.x -= 4 ; // Draw the dot in the center
            fn.y -= 4 ;
            SDL_FillRect(screen , &fn , 0xFF2244);
            }
        } // for(int i=0 ; i < 360 ; i++) { END
    // Target Tracing base on a destination coordinate
    if( dstX > xidx ) xidx++;
    if( dstX < xidx ) xidx--;
    if( dstY > yidx ) yidx++;
    if( dstY < yidx ) yidx--;
    // Deal with key states
    if(bKeyUP) yidx = yidx - dx;
    if(bKeyDOWN) yidx = yidx + dx;
    if(bKeyLEFT) xidx -= dx;
    if(bKeyRIGHT) xidx += dx;
    animRect.x = xidx - 50 ; // The offset x from obj to img is -50
    animRect.y = yidx - 90 ; // The offset y from obj to img is -90
    }; // while(bRun) { END

} // int main(int argc, char *argv[]) END


In the Polar Coordinate System ,
x = r sin( theta )
y = r cos( theta )

Here demonstrate a way to draw mathematical formula in a screen.    You can modify it and try
 other functions.


In the main program , demonstrate a way to display a picture that the location lower than 0
The concept is , each object has its coordinate , named (xidx , yidx) in here.
And it's not the same as the coordinate of its picture.    They're different.    The picture of
an object , is its body , or outlook.    The coordinate of a picture should base on the object.
animRect.x = obj.xidx + offsetX ;
animRect.y = obj.yidx + offsetY;


Exp2 END
.

Copyright © 2009 bdragon All rights reserved.
bdragong@gmail.com
Č
ċ
Bdragon Ho,
Aug 16, 2009, 4:19 PM
Comments