| home | contents | previous | next page | send comment | send link | add bookmark |

4. Plotter class source code

Create a file to contain the main application named user_name.cpp to solve any numerical plotting problem as follows:

/*----------------------------------------------------------------------------* 
**  This is the main windows file for creating the numerical plotter used in
**  the tuturial.
**
**  To build this in Visual C++ 6.0 perform the following steps:
**
**  1. Select New from File menu.
**
**  2. In the New dialog box select "Win32 Application" and enter 
**     a project name.  Then press the "Ok" button.
**
**  3. In the Win32 Application dialog box select "A simple Win32 Application" 
**     then press the "Finish" button.  
**
**  4. Press "Ok" in the New Project Information dialog box.
**
**  5. Open the *.cpp file for entry of the program.  (We do not edit StdAfx.h
**     or StdAfx.cpp; VC++ requires these files.)
*/

#include "stdafx.h"
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <windowsx.h>
#include "..\plotter\plotter.h"
#include "..\vector\vector.h"

plotter np( "Plotter", "Numerical Plotter" ); 

/*----------------------------------------------------------------------------*
**  "WinMain" is the program entry point
**
**  returns: message parameter
*/
int APIENTRY WinMain( HINSTANCE inst,           // window instance
                      HINSTANCE prev,           // previous window
                      LPSTR     cmdl,           // command line string
                      int       show )          // initial display
{
    np.initialize( inst );
    
    if( !np.window_class() )
	return 0;
  
    np.create( show );
 
    return np.message_loop();
}
    
/*----------------------------------------------------------------------------*
**  "WindowFunc" processes messages to this application
**
**  returns: 0 if message processed, else default value
*/
LRESULT CALLBACK WindowFunc( HWND   hwnd,       // handle to window of message
                             UINT   msg,        // message code
                             WPARAM wp,         // short message amplifier
                             LPARAM lp )        // long message amplifier
{
    switch( msg )
    {
    case WM_CREATE:
        np.on_create( hwnd );
        break;

    case WM_DESTROY:
        np.on_destroy();
        break;

    case WM_SIZE:
        np.on_size( hwnd );
        break;

    case WM_HSCROLL:
        np.on_hscroll( hwnd, wp );
        break;

    case WM_VSCROLL:
        np.on_vscroll( hwnd, wp );
        break;

    case WM_PAINT:
        np.on_paint( hwnd );
        break;

    case WM_COMMAND:
        np.on_command( hwnd, wp );
        break;

    default:
        return DefWindowProc( hwnd, msg, wp, lp );
    }

    return 0;
}

/*----------------------------------------------------------------------------*\
**              Put your mathematical functions to plot here.                 **
\*----------------------------------------------------------------------------*/

.
.
.

This is the source file plotter.h which declares the plotter class

#define ID_FILE_SAVE                    40001
#define ID_FILE_EXIT                    40002
#define ID_PROGRAM_RUN                  40011
#define ID_PROGRAM_RESET                40012
#define ID_HELP_ABOUT                   40021

class plotter
{
public:
    plotter( char *, char * );
    void initialize( HINSTANCE );
    void create( int );
    bool window_class();
    int  message_loop();

    void on_command( HWND, WPARAM );
    void on_create( HWND );
    void on_destroy();
    void on_hscroll( HWND, WPARAM );
    void on_paint( HWND );
    void on_size( HWND );
    void on_vscroll( HWND, WPARAM );
    
    void  draw_axes();
    void  plot_region( double, double, double, double );
    void  red_curve( POINT *, int );
    void  green_curve( POINT *, int );
    void  blue_curve( POINT *, int );
    POINT plot_point( double, double );

private:
    void  about( HWND );
    int   file_save_dlg( HWND, PSTR, PSTR );
    BOOL  save_bitmap( HDC, HBITMAP, PSTR );
    HMENU menu();
    
    HINSTANCE hInstance;                        // instance of this program
    char class_name[64];
    char plotter_name[64];
    RECT current;                               // current client dimensions
    HDC hMemoryDC;                              // handle of memory DC
    HBITMAP hbit;                               // handle of compatible bitmap
    HPEN hOldpen;                               // handle of saved drawing pen
    HPEN hRedpen, hGreenpen, hBluepen;          // drawing pens
    
    int X_max_pixels, Y_max_pixels;             // full screen dimensions
    int X_org, Y_org;                           // origin for painting bitmap
    
    int X0_pixel, Y0_pixel;                     // coordinate origin in pixels
    double dX, dY;                              // pixels per unit
    bool plot_region_defined;                   // when true, plot region setup
};

LRESULT CALLBACK WindowFunc( HWND, UINT, WPARAM, LPARAM );

This is the source file plotter.cpp which defines methods for the plotter class

#include "stdafx.h"
#include "plotter.h"
#include <assert.h>
#include <commdlg.h>
#include <stdlib.h>

void run();                                     // user defined function

/*----------------------------------------------------------------------------*
**  "plotter" constructor sets class and application names. 
**
**  returns: nothing
*/
plotter::plotter( char *cn, char *an )
{
    strcpy( class_name, cn );
    strcpy( plotter_name, an );
    
    // initial origin for painting bitmap
    X_org = 0;
    Y_org = 0;
    plot_region_defined = false;
}

/*----------------------------------------------------------------------------*
**  "initialize" stores the instance of the application. 
**
**  returns: nothing
*/
void plotter::initialize( HINSTANCE inst )
{
    hInstance = inst;
}

/*----------------------------------------------------------------------------*
**  "window_class" defines and registers a window class for the application. 
**
**  returns: true on success
*/
bool plotter::window_class()
{
    WNDCLASS wcl;

    // define the window class
    wcl.hInstance     = hInstance;
    wcl.lpszClassName = class_name;
    wcl.lpfnWndProc   = WindowFunc;
    wcl.style         = 0;
    wcl.hIcon         = LoadIcon( hInstance, IDI_WINLOGO );
    wcl.hCursor       = LoadCursor( NULL, IDC_ARROW );
    wcl.lpszMenuName  = 0;
    wcl.cbClsExtra    = 0;
    wcl.cbWndExtra    = 0;
    wcl.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );

    if( !RegisterClass( &wcl ) )
        return false;

    return true;
}
 
/*----------------------------------------------------------------------------*
**  "menu" defines the initial application menu
**  displayed at the top of the window
**
**  returns: handle to menu
*/
HMENU plotter::menu()
{
    HMENU hMenu = CreateMenu();
    HMENU hMenuPopup = CreateMenu();
    
    AppendMenu( hMenuPopup, MF_STRING,    ID_FILE_SAVE,  "&Save" );
    AppendMenu( hMenuPopup, MF_STRING,    ID_FILE_EXIT,  "E&xit" );
    AppendMenu( hMenu, MF_POPUP, (UINT)hMenuPopup,       "&File" );
    
    hMenuPopup = CreateMenu();
    AppendMenu( hMenuPopup, MF_STRING, ID_PROGRAM_RUN,   "&Run" );
    AppendMenu( hMenuPopup, MF_STRING, ID_PROGRAM_RESET, "Re&set" );
    AppendMenu( hMenu, MF_POPUP, (UINT)hMenuPopup,       "&Program" );

    hMenuPopup = CreateMenu();
    AppendMenu( hMenuPopup, MF_STRING, ID_HELP_ABOUT,    "&About" );
    AppendMenu( hMenu, MF_POPUP, (UINT)hMenuPopup,       "&Help" );

    return hMenu;
}

/*----------------------------------------------------------------------------*
**  "create" creates and opens a window for the application.
**
**  returns: nothing
*/
void plotter::create( int open )
{
    HWND hwnd;

    hwnd = CreateWindow( class_name,            // class name
                         plotter_name,          // name of this program 
                         WS_OVERLAPPEDWINDOW |  // normal window 
                         WS_HSCROLL |           //  with horizontal and
                         WS_VSCROLL,            //  vertical scroll bars
                         CW_USEDEFAULT,         // x - origin
                         CW_USEDEFAULT,         // y - origin
                         CW_USEDEFAULT,         // width
                         CW_USEDEFAULT,         // height
                         HWND_DESKTOP,          // no parent
                         menu(),                // initial menu
                         hInstance,             // this 
                         NULL );                // no arguments

    ShowWindow( hwnd, open );
    UpdateWindow( hwnd );
}

/*----------------------------------------------------------------------------*
**  "about" generates the about box for this application.
**
**  returns:  nothing
*/
void plotter::about( HWND hwnd )
{
    MSGBOXPARAMS ab;

    ab.cbSize             = sizeof( MSGBOXPARAMS );     
    ab.hwndOwner          = hwnd; 
    ab.hInstance          = hInstance;     
    ab.lpszCaption        = "About"; 
    ab.lpszText           = "Numerical Plotter, version 1.0 - January 2000\n\n"
                            "Stephen R. Schmitt\n";
    ab.dwStyle            = MB_OK ;     
    ab.lpszIcon           = NULL;     
    ab.dwContextHelpId    = 0; 
    ab.lpfnMsgBoxCallback = 0;     
    ab.dwLanguageId       = 0; 

    MessageBoxIndirect( &ab );
}

/*----------------------------------------------------------------------------*
**  "message_loop" processes messages received by the window
**
**  returns: last message wParam
*/
int plotter::message_loop()
{
    MSG msg;

    // the message loop
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }

    // all done
    return msg.wParam;
}

/*----------------------------------------------------------------------------*
**  "on_create" initializes the graphics parameters for the application.
**
**  returns:  nothing
*/
void plotter::on_create( HWND hwnd )
{
    HDC hdc = GetDC( hwnd );

    // get screen size
    X_max_pixels = GetSystemMetrics( SM_CXSCREEN );
    Y_max_pixels = GetSystemMetrics( SM_CYSCREEN );

    // make a compatible bitmap
    hMemoryDC = CreateCompatibleDC( hdc );
    hbit = CreateCompatibleBitmap( hdc, X_max_pixels, Y_max_pixels );
    SelectObject( hMemoryDC, hbit );
    SelectObject( hMemoryDC, (HBRUSH)GetStockObject( WHITE_BRUSH ) );
    PatBlt( hMemoryDC, 0, 0, X_max_pixels, Y_max_pixels, PATCOPY );
    
    // create drawing pens
    hRedpen    = CreatePen( PS_SOLID, 1, RGB( 255,   0,   0 ) );
    hGreenpen  = CreatePen( PS_SOLID, 1, RGB(   0, 255,   0 ) );
    hBluepen   = CreatePen( PS_SOLID, 1, RGB(   0,   0, 255 ) );

    // save default pen
    hOldpen = (HPEN)SelectObject( hMemoryDC, hRedpen );
    SelectObject( hMemoryDC, hOldpen );

    ReleaseDC( hwnd, hdc );
}

/*----------------------------------------------------------------------------*
**  "on_destroy" frees the graphics resource allocated in on_create() and
**  ends program.
**
**  returns:  nothing
*/
void plotter::on_destroy()
{
    DeleteObject( hRedpen );
    DeleteObject( hGreenpen );
    DeleteObject( hBluepen );
    DeleteDC( hMemoryDC );

    // end the program
    PostQuitMessage( 0 );
}

/*----------------------------------------------------------------------------*
**  "on_size" sets the scroll bar parameters.
**
**  returns:  nothing
*/
void plotter::on_size( HWND hwnd )
{
    SCROLLINFO si;

    // get current client dimensions and reset origin
    GetClientRect( hwnd, &current );

    while( X_org + current.right > X_max_pixels )
        X_org--;

    while( Y_org + current.bottom > Y_max_pixels )
        Y_org--;

    // reset scroll bars
    si.cbSize = sizeof( SCROLLINFO );
    si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
    si.nMin   = 0;
    
    si.nMax   = X_max_pixels;
    si.nPos   = X_org;
    si.nPage  = current.right;
    SetScrollInfo( hwnd, SB_HORZ, &si, TRUE );
    
    si.nMax   = Y_max_pixels;
    si.nPos   = Y_org;
    si.nPage  = current.bottom;
    SetScrollInfo( hwnd, SB_VERT, &si, TRUE );       

    InvalidateRect( hwnd, NULL, FALSE );
}

/*----------------------------------------------------------------------------*
**  "on_hscroll" scrolls the client area of the application horizontally.
**
**  returns:  nothing
*/
void plotter::on_hscroll( HWND hwnd, WPARAM wParam )
{
    SCROLLINFO si;

    switch( LOWORD( wParam ) )
    {
    case SB_THUMBTRACK:
        X_org = HIWORD( wParam );
        break;

    case SB_LINERIGHT:
        if( X_org < X_max_pixels - current.right )
            X_org++;
        break;

    case SB_PAGERIGHT:
        if( X_org +  8 < X_max_pixels - current.right )
            X_org += 8;
        break;

    case SB_LINELEFT:
        if( X_org > 0 )
            X_org--;
        break;

    case SB_PAGELEFT:
        if( X_org -  8 > 0 )
            X_org -= 8;
        break;
    }

    si.cbSize = sizeof( SCROLLINFO );
    si.fMask  = SIF_POS;
    si.nMin   = 0;
    si.nMax   = X_max_pixels;
    si.nPos   = X_org;
    si.nPage  = current.right;
    SetScrollInfo( hwnd, SB_HORZ, &si, TRUE );

    InvalidateRect( hwnd, NULL, FALSE );        // force repaint
}

/*----------------------------------------------------------------------------*
**  "on_vscroll" scrolls the client area of the application vertically.
**
**  returns:  nothing
*/
void plotter::on_vscroll( HWND hwnd, WPARAM wParam )
{
    SCROLLINFO si;                              // scroll bar information

    switch( LOWORD( wParam ) )
    {
    case SB_THUMBTRACK:
        Y_org = HIWORD( wParam );
        break;

    case SB_LINEDOWN:
        if( Y_org < Y_max_pixels - current.bottom )
            Y_org++;
        break;

    case SB_PAGEDOWN:
        if( Y_org +  8 < Y_max_pixels - current.bottom )
            Y_org += 8;
        break;

    case SB_LINEUP:
        if( Y_org > 0 )
            Y_org--;
        break;

    case SB_PAGEUP:
        if( Y_org -  8 > 0 )
            Y_org -= 8;
        break;
    }

    si.cbSize = sizeof( SCROLLINFO );
    si.fMask  = SIF_POS;
    si.nMin   = 0;
    si.nMax   = Y_max_pixels;
    si.nPos   = Y_org;
    si.nPage  = current.bottom;
    SetScrollInfo( hwnd, SB_VERT, &si, TRUE );
    
    InvalidateRect( hwnd, NULL, FALSE );        // force repaint
}

/*----------------------------------------------------------------------------*
**  "on_paint" repaints the client area of the application by copying the
**  memory device into the window device.
**
**  returns:  nothing
*/
void plotter::on_paint( HWND hwnd )
{
    PAINTSTRUCT ps;    
    HDC hdc = BeginPaint( hwnd, &ps );

    BitBlt( hdc,                                // destination 
            ps.rcPaint.left, 
            ps.rcPaint.top, 
            ps.rcPaint.right  - ps.rcPaint.left, 
            ps.rcPaint.bottom - ps.rcPaint.top, 
            hMemoryDC,                          // source  
            ps.rcPaint.left + X_org, 
            ps.rcPaint.top  + Y_org, 
            SRCCOPY );
	
    EndPaint( hwnd, &ps );
}

/*----------------------------------------------------------------------------*
**  "on_command" executes user commands for the application.
**
**  returns:  nothing
*/
void plotter::on_command( HWND hwnd, WPARAM wParam )
{
    char path[_MAX_PATH];
    char name[_MAX_FNAME + _MAX_EXT];

    switch( LOWORD( wParam ) )
    {
    case ID_FILE_SAVE:
        path[0] = 0;
        name[0] = 0;
    
        if( file_save_dlg( hwnd, path, name ) )
        {
            if( !save_bitmap( hMemoryDC, hbit, path ) )
                MessageBox( hwnd, "Could not save bitmap", NULL, MB_OK );
        }
        break;

    case ID_FILE_EXIT:
        SendMessage( hwnd, WM_CLOSE, 0, 0 );
        break;

    case ID_PROGRAM_RUN:
        run();
        InvalidateRect( hwnd, NULL, FALSE );
        break;

    case ID_PROGRAM_RESET:
        PatBlt( hMemoryDC, 0, 0, X_max_pixels, Y_max_pixels, PATCOPY );
        InvalidateRect( hwnd, NULL, FALSE );
        break;

    case ID_HELP_ABOUT:
        about( hwnd );
        break;
    }
}

/*------------------------------------------------------------------------*
**  "file_save_dlg" creates a file save dialog box.
**
**  returns:  non-zero on OK, else zero
*/
int plotter::file_save_dlg( HWND hwnd, PSTR file, PSTR title )
{
    OPENFILENAME dlg;
    static char filter[] =  "Bitmap Files (*.bmp)\0*.bmp\0\0";

    dlg.lStructSize       = sizeof( OPENFILENAME );
    dlg.hwndOwner         = hwnd;
    dlg.hInstance         = NULL;
    dlg.lpstrFilter       = filter;
    dlg.lpstrCustomFilter = NULL;
    dlg.nMaxCustFilter    = 0;
    dlg.nFilterIndex      = 0;
    dlg.lpstrFile         = file;
    dlg.nMaxFile          = _MAX_PATH;
    dlg.lpstrFileTitle    = title;
    dlg.nMaxFileTitle     = _MAX_FNAME + _MAX_EXT;
    dlg.lpstrInitialDir   = NULL;
    dlg.lpstrTitle        = NULL;
    dlg.Flags             = OFN_OVERWRITEPROMPT;
    dlg.nFileOffset       = 0;
    dlg.nFileExtension    = 0;
    dlg.lpstrDefExt       = "bmp";
    dlg.lCustData         = 0L;
    dlg.lpfnHook          = NULL;
    dlg.lpTemplateName    = NULL;

    return GetSaveFileName( &dlg );
}

/*----------------------------------------------------------------------------*
**  "save_bitmap" converts a device dependent bitmat into a device 
**  independant bitmap and saves in *.bmp format.
**
**  returns: TRUE on success
*/
BOOL plotter::save_bitmap( HDC hdc, HBITMAP bitmap, PSTR file_name )
{
    int              file;
    OFSTRUCT         ofs;
    HBITMAP          temp_bmp, save_bmp;
    BITMAPFILEHEADER bmp_header;
    BITMAPINFO      *pbmi, bmi;
    void            *image;
    unsigned long    bmp_info_size;
    BOOL             ok = TRUE;

    if( !bitmap )
        return FALSE;

    // GetDIBits uses the size to determine if it's BITMAPCOREINFO or BITMAPINFO
    bmi.bmiHeader.biSize     = 40;              // size of BITMAPINFO
    bmi.bmiHeader.biBitCount =  0;              // don't get the color table
    
    if( ( GetDIBits( hdc,                       // handle to device context
                     bitmap,                    // handle to bitmap
                     0,                         // first scan line in destination bitmap
                     0,                         // number of scan lines to copy
                     (LPSTR)NULL,               // address of array for bitmap bits
                     &bmi,                      // address of structure with bitmap data
                     DIB_RGB_COLORS ) ) == 0 )  // RGB or palette index
        return FALSE;

    // allocate enough memory to hold the actual bits of the image
    image = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, bmi.bmiHeader.biSizeImage );
    if( image == NULL) 
        return FALSE;

    // save pointer to bitmap information header
    pbmi = &bmi;                         
    
    // 24 bits per pixel requires no color table, assume no color table
    bmp_info_size =  sizeof( BITMAPINFOHEADER );      

    switch( bmi.bmiHeader.biBitCount ) 
    {
    case 24:                                    // has no color table
        break;
    
    case 16:
    case 32:
        bmp_info_size += sizeof( DWORD ) * 3;
        break;
    
    default:
        bmp_info_size += sizeof( RGBQUAD ) * ( 1 << bmi.bmiHeader.biBitCount );
        break;
    }

    // Allocate memory for color table if it is not 24 bits per pixel
    if( bmp_info_size != sizeof( BITMAPINFOHEADER ) ) 
    {
        // get more memory for the color table
        pbmi = (PBITMAPINFO)GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, bmp_info_size );
        if( pbmi == NULL  ) 
        {
            ok = FALSE;
            goto no_memory_for_color_table;
        }
        
        // copy the bitmap info header data into the allocated space
        memmove( pbmi, &bmi, sizeof( BITMAPINFOHEADER ) );
    }

    // open the output file and get ready for writing
    file = OpenFile( file_name, &ofs, OF_CREATE | OF_WRITE );
    if( file == -1 ) 
    {
        ok = FALSE;
        goto no_file_open;
    }

    // fill in the info for the bmp file header
    bmp_header.bfType      = 0x4D42;            // 'BM'
    bmp_header.bfSize      = sizeof( BITMAPFILEHEADER ); 
    bmp_header.bfSize     += sizeof( BITMAPINFOHEADER ); 
    bmp_header.bfSize     += bmp_info_size + pbmi->bmiHeader.biSizeImage;
    bmp_header.bfReserved1 = 0;
    bmp_header.bfReserved2 = 0;
    bmp_header.bfOffBits   = sizeof( BITMAPFILEHEADER ) + bmp_info_size;

    // write the file header to disk
    if( _lwrite( file, (LPSTR)&bmp_header, sizeof( BITMAPFILEHEADER ) ) == -1 ) 
    {
        ok = FALSE;
        goto no_bitmap;
    }

    // Since the bitmap can't be selected into a DC when calling GetDIBits,
    // assume that the hdc is the DC where the bitmap would have been selected
    temp_bmp = CreateCompatibleBitmap( hdc,  
                                       pbmi->bmiHeader.biWidth, 
                                       pbmi->bmiHeader.biHeight );
    if( temp_bmp ) 
    {
        save_bmp = ( HBITMAP )SelectObject( hdc, temp_bmp );
        if( !GetDIBits( hdc, 
                        bitmap, 
                        0, 
                        pbmi->bmiHeader.biHeight, 
                        image, 
                        pbmi, 
                        DIB_RGB_COLORS ) )
        {
            ok = FALSE;
            goto no_file_write;
        }
    } 
    else 
    {
        ok = FALSE;
        goto no_bitmap;
    }

    // Now write out the BitmapInfoHeader and color table, if any
    if( _lwrite( file, (char *)pbmi, bmp_info_size ) == -1 ) 
    {
        ok = FALSE;
        goto no_file_write;
    }

    // write the bits also
    if( _lwrite( file, (char *)image, pbmi->bmiHeader.biSizeImage ) == -1 ) 
    {
        ok = FALSE;
        goto no_file_write;
    }

no_file_write:
    SelectObject( hdc, save_bmp );
    DeleteObject( temp_bmp );
no_bitmap:
    _lclose( file );
no_file_open:
    GlobalFree( pbmi );
no_memory_for_color_table:
    GlobalFree( image );
    return ok;
}

/*----------------------------------------------------------------------------*
**  "plot_region" calculates parameters for the plotting area of the screen.
**
**  returns: nothing
*/
void plotter::plot_region( double left,         // left of origin is negative
                           double right,        // right of origin is positive 
                           double top,          // above origin is positive 
                           double bottom )      // below origin is negative
{
    // pixels per unit X and Y
    dX = X_max_pixels / ( right - left );
    dY = Y_max_pixels / ( top - bottom );

    // location of pixel at coordinate origin
    X0_pixel = int( -left * dX );
    Y0_pixel = int( +top  * dY );

    plot_region_defined = true;
}

/*----------------------------------------------------------------------------*
**  "draw_axes" puts the x, y coordinate axes on the screen.
**
**  returns: nothing
*/
void plotter::draw_axes()
{
    int x, y, z;

    for( y = 0; y < Y_max_pixels; y++ )
    {
        SetPixel( hMemoryDC, X0_pixel, y, RGB( 0, 0, 0 ) );

        if( ( y - Y0_pixel ) % int(dY) == 0 )
        {
            for( z = -3; z <= 3; z++ ) 
                SetPixel( hMemoryDC, X0_pixel + z, y, RGB( 0, 0, 0 ) );
        }
    }

    for( x = 0; x < X_max_pixels; x++ )
    {
        SetPixel( hMemoryDC, x, Y0_pixel, RGB( 0, 0, 0 ) );

        if( ( x - X0_pixel ) % int(dX) == 0 )
        {
            for( z = -3; z <= 3; z++ ) 
                SetPixel( hMemoryDC, x, Y0_pixel + z, RGB( 0, 0, 0 ) );
        }
    }
}

/*----------------------------------------------------------------------------*
**  "red_curve" draws a red curve on the screen.
**
**  returns: nothing
*/
void plotter::red_curve( POINT *curve, int points )
{
    hOldpen = (HPEN)SelectObject( hMemoryDC, hRedpen );
    Polyline( hMemoryDC, curve, points );
    SelectObject( hMemoryDC, hOldpen );
}

/*----------------------------------------------------------------------------*
**  "green_curve" draws a green curve on the screen.
**
**  returns: nothing
*/
void plotter::green_curve( POINT *curve, int points )
{
    hOldpen = (HPEN)SelectObject( hMemoryDC, hGreenpen );
    Polyline( hMemoryDC, curve, points );
    SelectObject( hMemoryDC, hOldpen );
}

/*----------------------------------------------------------------------------*
**  "blue_curve" draws a blue curve on the screen.
**
**  returns: nothing
*/
void plotter::blue_curve( POINT *curve, int points )
{
    hOldpen = (HPEN)SelectObject( hMemoryDC, hBluepen );
    Polyline( hMemoryDC, curve, points );
    SelectObject( hMemoryDC, hOldpen );
}

/*----------------------------------------------------------------------------*
**  "plot_point" converts a mathematical point to be plotted into the 
**  screen coordinate frame.
**
**  returns: the point in screen coordinates
*/
POINT plotter::plot_point( double x, double y )
{
    POINT p;

    assert( plot_region_defined );

    p.x = int( ( X0_pixel + x * dX ) );
    p.y = int( ( Y0_pixel - y * dY ) );

    return p;
}

| home | contents | previous | next page | send comment | send link | add bookmark |

Copyright © 2004, Stephen R. Schmitt