【计算机图形学】2-3.5 基本图形颜色的填充 和 当前代码汇总

本文介绍了一个使用C语言实现的图形绘制系统,包括点、线、矩形、圆形和椭圆的绘制方法。通过不同的算法如DDA、中点画线算法和Bresenham算法来绘制直线,并详细展示了如何填充这些图形。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    到现在为止,对于已有的矩形和椭圆,由于我们知道边界的位置,且它们都是凸多边形,所以区域填色非常容易。

    在这里简单汇聚一下代码,由于没加双缓冲等问题,现在的图形遮挡和刷新的闪烁现象都很难让我们接受,目前只是理论上的解决方式,这些问题将在今后更改。

    为了阅读方便,代码完全用C语言编写,但没有任何注释。

定义方面

define.h

#ifndef DEFINE_H_INCLUDED
#define DEFINE_H_INCLUDED

typedef short               int16;
typedef int                 int32;
typedef long long           int64;
typedef unsigned short      uint16;
typedef unsigned int        uint32;
typedef unsigned long long  uint64;

#define swap(x, y) x ^= y, y ^= x, x ^= y;

#include "define_device.h"
#include "define_operation.h"
#include "define_menu.h"

#endif // DEFINE_H_INCLUDED

define_device.h

#ifndef DEFINE_DEVICE_H_INCLUDED
#define DEFINE_DEVICE_H_INCLUDED

#define MOUSE_LEFT      0
#define MOUSE_MIDDLE    1
#define MOUSE_RIGHT     2
#define MOUSE_DOWN      3
#define MOUSE_UP        4

#define KEY_STATE_DOWN  0
#define KEY_STATE_UP    1

#endif // DEFINE_DEVICE_H_INCLUDED

define_operation.h

#ifndef DEFINE_OPERATION_H_INCLUDED
#define DEFINE_OPERATION_H_INCLUDED

#define OP_DRAW_NULL                0
#define OP_DRAW_POINT_FREE          1
#define OP_DRAW_LINE_FREE           2
#define OP_DRAW_LINE_CLICK1         3
#define OP_DRAW_CIRCLE_FREE         4
#define OP_DRAW_CIRCLE_CLICK1       5
#define OP_DRAW_ELLIPSE_FREE        6
#define OP_DRAW_ELLIPSE_CLICK1      7
#define OP_DRAW_RECTANGLE_FREE      8
#define OP_DRAW_RECTANGLE_CLICK1    9
#define OP_DRAW_POLYGON_FREE        10
#define OP_DRAW_POLYGON_CLICK       11

#endif // DEFINE_OPERATION_H_INCLUDED

define_menu.h

#ifndef DEFINE_MENU_H_INCLUDED
#define DEFINE_MENU_H_INCLUDED

#define MENU_TYPE_POPUP         0
#define MENU_TYPE_STRING        1
#define MENU_TYPE_POPUP_END     2
#define MENU_TYPE_END           3

#endif // DEFINE_MENU_H_INCLUDED



界面方面

gui.h

#ifndef GUI_H_INCLUDED
#define GUI_H_INCLUDED

#include "define.h"

#if defined(SYSTEM_WIN)
#include "gui_windows.h"
#endif
#include "gui_menu.h"

#endif // GUI_H_INCLUDED

gui_windows.h

#ifndef GUI_WINDOWS_H_INCLUDED
#define GUI_WINDOWS_H_INCLUDED

#include <assert.h>
#include <windows.h>
#include <commctrl.h>
#include "define.h"

#define main fake_main

int fake_main();

int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int);
LRESULT CALLBACK gui_mainProcess(HWND, UINT, WPARAM, LPARAM);
void gui_createMainWindow(const char *);
void gui_setMainWindowPosition(int32 x, int32 y);
void gui_setMainWindowSize(int32 w, int32 h);
void gui_setMainWindowToCenter(void);
void gui_setMainWindowMinimize(void);
void gui_setMainWindowMaximize(void);
void gui_setMainWindowRestore(void);
void gui_mainLoop(void);

int32 gui_appendSubMenu(HMENU menu, const char *text[], const int32 id[], const int32 type[]);
void gui_appendMainMenu(const char *text[], const int32 id[], const int32 type[]);
void gui_createStatusBar(void);
void gui_setStatusBarText(int32 pos, const char *text);

void gui_repaint(void);
void gui_setPixel_2i1u(int32 x, int32 y, uint32 color);
void gui_setPixel_5i(int32 x, int32 y, uint32 r, uint32 g, uint32 b);
uint32 gui_getPixel(int32 x, int32 y);

void gui_setDisplayFunction(void (*func)(void));
void gui_setReshapeFunction(void (*func)(int32 w, int32 h));
void gui_setKeyboardFunction(void (*func)(int32 key, int32 state, int32 x, int32 y));
void gui_setMouseFunction(void (*func)(int32 button, int32 state, int32 x, int32 y));
void gui_setMotionFunction(void (*func)(int32 x, int32 y));
void gui_setMenuFunction(void (*func)(int32 id));

void gui_informationBox(const char *title, const char *text);

#endif // GUI_WINDOWS_H_INCLUDED

gui_windows.c

#include "gui_windows.h"

static HINSTANCE mainInstance;
static HWND handleMainWindow;
static HWND handleMainStatusBar;
static HMENU handleMainMenu;
static HDC handleMainWindowDeviceContext;
//static HDC mainWindowBuffer;
static RECT mainWindowRect;
static int32 systemWidth, systemHeight;

static void (*mainWindowDisplayFunction)();
static void (*mainWindowReshapeFunction)(int32, int32);
static void (*mainWindowKeyboardFunction)(int32, int32, int32, int32);
static void (*mainWindowMouseFunction)(int32, int32, int32, int32);
static void (*mainWindowMotionFunction)(int32, int32);
static void (*mainWindowMenuFunction)(int32);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   PSTR szCmdLine,
                   int iCmdShow)
{
    mainInstance = hInstance;
    systemWidth = GetSystemMetrics(SM_CXSCREEN);
    systemHeight = GetSystemMetrics(SM_CYSCREEN);
    InitCommonControls();
    return fake_main();
}

void gui_createMainWindow(const char *title)
{
    WNDCLASS mainWindow;
    mainWindow.style            = CS_HREDRAW | CS_VREDRAW;
    mainWindow.lpfnWndProc      = gui_mainProcess;
    mainWindow.cbClsExtra       = 0;
    mainWindow.cbWndExtra       = 0;
    mainWindow.hInstance        = mainInstance;
    mainWindow.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
    mainWindow.hCursor          = LoadCursor(NULL, IDC_ARROW);
    //mainWindow.hbrBackground    = NULL;
    mainWindow.hbrBackground    = (HBRUSH)GetStockObject(WHITE_BRUSH);
    mainWindow.lpszMenuName     = "mainMenu";
    mainWindow.lpszClassName    = "mainWindow";
    if(!RegisterClass(&mainWindow))
    {
        MessageBox(NULL, TEXT("Cannot register class for main window."), TEXT(title), MB_ICONERROR);
        exit(0);
    }
    handleMainMenu = CreateMenu();
    handleMainWindow = CreateWindow("mainWindow",
                                    title,
                                    WS_OVERLAPPEDWINDOW,
                                    CW_USEDEFAULT,
                                    CW_USEDEFAULT,
                                    CW_USEDEFAULT,
                                    CW_USEDEFAULT,
                                    NULL,
                                    handleMainMenu,
                                    mainInstance,
                                    NULL);
    SetMenu(handleMainWindow, handleMainMenu);
    ShowWindow(handleMainWindow, 1);
    UpdateWindow(handleMainWindow);
}

void gui_setMainWindowPosition(int32 x, int32 y)
{
    assert(handleMainWindow != NULL);
    SetWindowPos(handleMainWindow, NULL, x, y, 0, 0, SWP_NOSIZE);
}

void gui_setMainWindowSize(int32 w, int32 h)
{
    assert(handleMainWindow != NULL);
    SetWindowPos(handleMainWindow, NULL, 0, 0, w, h, SWP_NOMOVE);
}

void gui_setMainWindowToCenter(void)
{
    assert(handleMainWindow != NULL);
    RECT rect;
    GetWindowRect(handleMainWindow, &rect);
    int32 w = rect.right - rect.left;
    int32 h = rect.bottom - rect.top;
    gui_setMainWindowPosition((systemWidth - w) >> 1, (systemHeight - h) >> 1);
}

void gui_setMainWindowMinimize(void)
{
    assert(handleMainWindow != NULL);
    SendMessage(handleMainWindow, WM_SYSCOMMAND, SC_MINIMIZE, (LPARAM)NULL);
}

void gui_setMainWindowMaximize(void)
{
    assert(handleMainWindow != NULL);
    SendMessage(handleMainWindow, WM_SYSCOMMAND, SC_MAXIMIZE, (LPARAM)NULL);
}

void gui_setMainWindowRestore(void)
{
    assert(handleMainWindow != NULL);
    SendMessage(handleMainWindow, WM_SYSCOMMAND, SC_RESTORE, (LPARAM)NULL);
}

void gui_mainLoop(void)
{
    assert(handleMainWindow != NULL);
    MSG message;
    while(GetMessage(&message, NULL, 0, 0))
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }
}

int32 gui_appendSubMenu(HMENU menu, const char *text[], const int32 id[], const int32 type[])
{
    int32 i;
    const char *curText;
    HMENU subMenu;
    for(i=0;;++i)
    {
        switch(type[i])
        {
        case MENU_TYPE_POPUP:
            curText = text[i];
            subMenu = CreatePopupMenu();
            i += gui_appendSubMenu(subMenu, text + i + 1, id + i + 1, type + i + 1) + 1;
            AppendMenu(menu, MF_STRING | MF_POPUP, (UINT)subMenu, curText);
            break;
        case MENU_TYPE_POPUP_END:
            AppendMenu(menu, MF_STRING, id[i], text[i]);
            return i;
        case MENU_TYPE_STRING:
        case MENU_TYPE_END:
            AppendMenu(menu, MF_STRING, id[i], text[i]);
            break;
        }
        if(type[i] == MENU_TYPE_END)
        {
            return i;
        }
    }
}

void gui_appendMainMenu(const char *text[], const int32 id[], const int32 type[])
{
    gui_appendSubMenu(handleMainMenu, text, id, type);
    SetMenu(handleMainWindow, handleMainMenu);
}

void gui_createStatusBar(void)
{
    int32 statwidths[] = {200, 400, 600, -1};
    handleMainStatusBar = CreateStatusWindow(WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
                                             "mainStatus",
                                             handleMainWindow,
                                             0);
    SendMessage(handleMainStatusBar, SB_SETPARTS, sizeof(statwidths)/sizeof(int32), (LPARAM)statwidths);
}

void gui_setStatusBarText(int32 pos, const char *text)
{
    SendMessage(handleMainStatusBar, SB_SETTEXT, pos, (LPARAM)text);
}

void gui_repaint(void)
{
    InvalidateRect(handleMainWindow, NULL, TRUE);
    /*BitBlt(handleMainWindowDeviceContext,
           mainWindowRect.left,
           mainWindowRect.top,
           mainWindowRect.right - mainWindowRect.left,
           mainWindowRect.bottom - mainWindowRect.top,
           mainWindowBuffer,
           0,
           0,
           SRCCOPY);*/
    //DeleteDC(mainWindowBuffer);
    UpdateWindow(handleMainWindow);
}

void gui_setPixel_2i1u(int32 x, int32 y, uint32 color)
{
    SetPixel(handleMainWindowDeviceContext, x, y, color);
}

void gui_setPixel_5i(int32 x, int32 y, uint32 r, uint32 g, uint32 b)
{
    COLORREF color = RGB(r, g, b);
    SetPixel(handleMainWindowDeviceContext, x, y, color);
}

uint32 gui_getPixel(int x, int y)
{
    return GetPixel(handleMainWindowDeviceContext, x, y);
}

LRESULT CALLBACK gui_mainProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    switch (message)
    {
    case WM_PAINT:
        handleMainWindowDeviceContext = BeginPaint(hwnd, &ps);
        //mainWindowBuffer = CreateCompatibleDC(handleMainWindowDeviceContext);
        GetClientRect(hwnd, &mainWindowRect);
        if(mainWindowDisplayFunction)
        {
            mainWindowDisplayFunction();
        }
        EndPaint(hwnd, &ps) ;
        break;
    case WM_COMMAND:
        if(mainWindowMenuFunction)
        {
            mainWindowMenuFunction(LOWORD(wParam));
        }
        break;
    case WM_SIZE:
        if(mainWindowReshapeFunction)
        {
            mainWindowReshapeFunction(LOWORD(lParam), HIWORD(lParam));
        }
        break;
    case WM_MOUSEMOVE:
        if(mainWindowMotionFunction)
        {
            mainWindowMotionFunction(LOWORD(lParam), HIWORD(lParam));
        }
        break;
    case WM_LBUTTONDOWN:
        if(mainWindowMouseFunction)
        {
            mainWindowMouseFunction(MOUSE_LEFT, MOUSE_DOWN, LOWORD(lParam), HIWORD(lParam));
        }
        break;
    case WM_LBUTTONUP:
        if(mainWindowMouseFunction)
        {
            mainWindowMouseFunction(MOUSE_LEFT, MOUSE_UP, LOWORD(lParam), HIWORD(lParam));
        }
        break;
    case WM_RBUTTONDOWN:
        if(mainWindowMouseFunction)
        {
            mainWindowMouseFunction(MOUSE_RIGHT, MOUSE_DOWN, LOWORD(lParam), HIWORD(lParam));
        }
        break;
    case WM_RBUTTONUP:
        if(mainWindowMouseFunction)
        {
            mainWindowMouseFunction(MOUSE_RIGHT, MOUSE_UP, LOWORD(lParam), HIWORD(lParam));
        }
        break;
    case WM_MBUTTONDOWN:
        if(mainWindowMouseFunction)
        {
            mainWindowMouseFunction(MOUSE_MIDDLE, MOUSE_DOWN, LOWORD(lParam), HIWORD(lParam));
        }
        break;
    case WM_MBUTTONUP:
        if(mainWindowMouseFunction)
        {
            mainWindowMouseFunction(MOUSE_MIDDLE, MOUSE_UP, LOWORD(lParam), HIWORD(lParam));
        }
        break;
    case WM_KEYDOWN:
        break;
    case WM_KEYUP:
        break;
    case WM_MOUSEWHEEL:
        break;
    case WM_DESTROY:
        PostQuitMessage(0) ;
        break;
    }
    return DefWindowProc (hwnd, message, wParam, lParam) ;
}

void gui_setDisplayFunction(void (*func)(void))
{
    mainWindowDisplayFunction = func;
}

void gui_setReshapeFunction(void (*func)(int32 w, int32 h))
{
    mainWindowReshapeFunction = func;
}

void gui_setKeyboardFunction(void (*func)(int32 key, int32 state, int32 x, int32 y))
{
    mainWindowKeyboardFunction = func;
}

void gui_setMouseFunction(void (*func)(int32 button, int32 state, int32 x, int32 y))
{
    mainWindowMouseFunction = func;
}

void gui_setMotionFunction(void (*func)(int32 x, int32 y))
{
    mainWindowMotionFunction = func;
}

void gui_setMenuFunction(void (*func)(int32 id))
{
    mainWindowMenuFunction = func;
}

void gui_informationBox(const char *title, const char *text)
{
    MessageBox(handleMainWindow, text, title, MB_ICONINFORMATION);
}

gui_menu.h

#ifndef GUI_MENU_H_INCLUDED
#define GUI_MENU_H_INCLUDED

#include "define.h"
#include "gui.h"

#define MENU_MAIN_TOP           0
#define MENU_FILE               1000
#define MENU_FILE_EXIT          1001
#define MENU_TOOLS              2000
#define MENU_TOOLS_POINT        2001
#define MENU_TOOLS_LINE         2002
#define MENU_TOOLS_RECTANGLE    2003
#define MENU_TOOLS_CIRCLE       2004
#define MENU_TOOLS_ELLIPSE      2005
#define MENU_TOOLS_POLYGON      2006
#define MENU_HELP               3000
#define MENU_HELP_ABOUT         3001

void gui_menu_createMenu(void);

#endif // GUI_MENU_H_INCLUDED

gui_menu.c

#include "gui_menu.h"

static const char *gui_menu_text[] =
{
    "File(&F)",
    "Exit(&E)",
    "Tools(&T)",
    "Point",
    "Line",
    "Rectangle",
    "Circle",
    "Ellipse",
    "Polygon",
    "Help(&H)",
    "About..."
};

static const int32 gui_menu_id[] =
{
    MENU_FILE,
    MENU_FILE_EXIT,
    MENU_TOOLS,
    MENU_TOOLS_POINT,
    MENU_TOOLS_LINE,
    MENU_TOOLS_RECTANGLE,
    MENU_TOOLS_CIRCLE,
    MENU_TOOLS_ELLIPSE,
    MENU_TOOLS_POLYGON,
    MENU_HELP,
    MENU_HELP_ABOUT,
};

static const int32 gui_menu_type[] =
{
    MENU_TYPE_POPUP,
    MENU_TYPE_POPUP_END,
    MENU_TYPE_POPUP,
    MENU_TYPE_STRING,
    MENU_TYPE_STRING,
    MENU_TYPE_STRING,
    MENU_TYPE_STRING,
    MENU_TYPE_STRING,
    MENU_TYPE_POPUP_END,
    MENU_TYPE_POPUP,
    MENU_TYPE_END
};

void gui_menu_createMenu(void)
{
    gui_appendMainMenu(gui_menu_text, gui_menu_id, gui_menu_type);
}

绘制方面

draw.h

#ifndef DRAW_H_INCLUDED
#define DRAW_H_INCLUDED

#include "draw_point.h"
#include "draw_pen.h"
#include "draw_brush.h"
#include "draw_line.h"
#include "draw_rectangle.h"
#include "draw_circle.h"
#include "draw_ellipse.h"
#include "draw_polygon.h"

void draw_init();

#endif // DRAW_H_INCLUDED

draw.c
#include "draw.h"

void draw_init()
{
    draw_pen_init();
    draw_brush_init();
}
draw_color.h

#ifndef DRAW_COLOR_H_INCLUDED
#define DRAW_COLOR_H_INCLUDED

#include "define.h"

static const uint32 draw_color_alpha_component  = 0xff000000;
static const uint32 draw_color_red_component    = 0x00ff0000;
static const uint32 draw_color_green_component  = 0x0000ff00;
static const uint32 draw_color_blue_component   = 0x000000ff;

typedef uint32 draw_color;
draw_color draw_color_getColor_3i(uint32 r, uint32 g, uint32 b);
draw_color draw_color_getColor_4i(uint32 r, uint32 g, uint32 b, uint32 a);
uint32 draw_color_getRed(uint32 color);
uint32 draw_color_getGreen(uint32 color);
uint32 draw_color_getBlue(uint32 color);
uint32 draw_color_getAlpha(uint32 color);

#endif // DRAW_COLOR_H_INCLUDED

draw_color.c

#include "draw_color.h"

draw_color draw_color_getColor_3i(uint32 r, uint32 g, uint32 b)
{
    return draw_color_getColor_4i(r, g, b, 255);
}

draw_color draw_color_getColor_4i(uint32 r, uint32 g, uint32 b, uint32 a)
{
    return (((((a << 8) + r) << 8) + g) << 8) + b;
}

uint32 draw_color_getAlpha(uint32 color)
{
    return (color & draw_color_alpha_component) >> 24;
}

uint32 draw_color_getRed(uint32 color)
{
    return (color & draw_color_red_component) >> 16;
}

uint32 draw_color_getGreen(uint32 color)
{
    return (color & draw_color_green_component) >> 8;
}

uint32 draw_color_getBlue(uint32 color)
{
    return color & draw_color_blue_component;
}

draw_pen.h

#ifndef DRAW_PEN_H_INCLUDED
#define DRAW_PEN_H_INCLUDED

#include <stdlib.h>
#include "define.h"
#include "draw_color.h"

typedef struct draw_pen_
{
    draw_color color;
}draw_pen_;

typedef draw_pen_ *draw_pen;

void draw_pen_init();
void draw_pen_setColor(draw_color color);
draw_color draw_pen_getColor();

#endif // DRAW_PEN_H_INCLUDED

draw_pen.c

#include "draw_pen.h"

static draw_pen draw_default_pen;

void draw_pen_init()
{
    draw_default_pen = (draw_pen) malloc(sizeof(*draw_default_pen));
}

void draw_pen_setColor(draw_color color)
{
    draw_default_pen->color = color;
}

draw_color draw_pen_getColor()
{
    return draw_default_pen->color;
}

draw_brush.h

#ifndef DRAW_BRUSH_H_INCLUDED
#define DRAW_BRUSH_H_INCLUDED

#include <stdlib.h>
#include "define.h"
#include "draw_color.h"

typedef struct draw_brush_
{
    draw_color color;
}draw_brush_;

typedef draw_brush_ *draw_brush;

void draw_brush_init();
void draw_brush_setColor(draw_color color);
draw_color draw_brush_getColor();

#endif // DRAW_BRUSH_H_INCLUDED

draw_brush.c

#include "draw_brush.h"

static draw_brush draw_default_brush;

void draw_brush_init()
{
    draw_default_brush = (draw_brush) malloc(sizeof(*draw_default_brush));
}

void draw_brush_setColor(draw_color color)
{
    draw_default_brush->color = color;
}

draw_color draw_brush_getColor()
{
    return draw_default_brush->color;
}

draw_point.h

#ifndef DRAW_POINT_H_INCLUDED
#define DRAW_POINT_H_INCLUDED

#include "define.h"
#include "gui.h"
#include "draw_color.h"
#include "draw_pen.h"
#include "draw_brush.h"

typedef struct Point_2i
{
    int32 x, y;
}Point_2i;

void draw_point_T_2i(const Point_2i point);
void draw_point_2i(int32 x, int32 y);
void draw_point_pen_2i(int32 x, int32 y);
void draw_point_brush_2i(int32 x, int32 y);

#endif // DRAW_POINT_H_INCLUDED

draw_point.c

#include "draw_point.h"

void draw_point_T_2i(const Point_2i point)
{
    draw_point_2i(point.x, point.y);
}

void draw_point_2i(int32 x, int32 y)
{
    draw_point_pen_2i(x, y);
}

void draw_point_pen_2i(int32 x, int32 y)
{
    uint32 r, g, b;
    r = draw_color_getRed(draw_pen_getColor());
    g = draw_color_getGreen(draw_pen_getColor());
    b = draw_color_getBlue(draw_pen_getColor());
    gui_setPixel_5i(x, y, r, g, b);
}

void draw_point_brush_2i(int32 x, int32 y)
{
    uint32 r, g, b;
    r = draw_color_getRed(draw_brush_getColor());
    g = draw_color_getGreen(draw_brush_getColor());
    b = draw_color_getBlue(draw_brush_getColor());
    gui_setPixel_5i(x, y, r, g, b);
}

draw_line.h

#ifndef DRAW_LINE_H_INCLUDED
#define DRAW_LINE_H_INCLUDED

#include <math.h>
#include "define.h"
#include "draw_point.h"

typedef struct Line_4i
{
    int32 x0, y0;
    int32 x1, y1;
}Line_4i;

void draw_line_T_4i(const Line_4i line);
void draw_line_4i(int32 x0, int32 y0, int32 x1, int32 y1);
void draw_line_DDA_4i(int32 x0, int32 y0, int32 x1, int32 y1);
void draw_line_MidPoint_4i(int32 x0, int32 y0, int32 x1, int32 y1);
void draw_line_Bresenham_4i(int32 x0, int32 y0, int32 x1, int32 y1);

#endif // DRAW_LINE_H_INCLUDED

draw_line.c

#include "draw_line.h"

void draw_line_T_4i(const Line_4i line)
{
    draw_line_4i(line.x0, line.y0, line.x1, line.y1);
}

void draw_line_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
    draw_line_Bresenham_4i(x0, y0, x1, y1);
}

void draw_line_DDA_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
    float ky, ty;
    int32 kx;
    if(abs(y1 - y0) < abs(x1 - x0))
    {
        kx = x1 > x0 ? 1 : -1;
        ky = (float)kx * (y1 - y0) / (x1 - x0);
        ty = y0;
        while(x0 != x1)
        {
            draw_point_pen_2i(x0, round(ty));
            x0 += kx;
            ty += ky;
        }
    }
    else if(abs(y1 - y0) > abs(x1 - x0))
    {
        kx = y1 > y0 ? 1 : -1;
        ky = (float)kx * (x1 - x0) / (y1 - y0);
        ty = x0;
        while(y0 != y1)
        {
            draw_point_pen_2i(round(ty), y0);
            y0 += kx;
            ty += ky;
        }
    }
    else
    {
        draw_point_pen_2i(x0, y0);
    }
}

void draw_line_MidPoint_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
    int32 a, b, c;
    int32 d, d1, d2;
    int32 kx, ky;
    a = y0 - y1;
    b = x1 - x0;
    c = x0 * y1 - x1 * y0;
    kx = x1 > x0 ? 1 : -1;
    ky = y1 > y0 ? 1 : -1;
    draw_point_pen_2i(x0, y0);
    if(abs(y1 - y0) < abs(x1 - x0))
    {
        a *= kx;
        b *= ky;
        d = (a << 1) + b;
        d1 = (a << 1) * kx;
        d2 = ((a + b) << 1) * kx;
        while(x0 != x1)
        {
            x0 += kx;
            if((ky > 0 && d < 0) || (ky < 0 && d > 0))
            {
                y0 += ky;
                d += d2;
            }
            else
            {
                d += d1;
            }
            draw_point_pen_2i(x0, y0);
        }
    }
    else
    {
        a *= ky;
        b *= kx;
        d = a + (b << 1);
        d1 = (b << 1) * ky;
        d2 = ((a + b) << 1) * ky;
        while(y0 != y1)
        {
            y0 += ky;
            if((ky > 0 && d > 0) || (ky < 0 && d < 0))
            {
                x0 += kx;
                d += d2;
            }
            else
            {
                d += d1;
            }
            draw_point_pen_2i(x0, y0);
        }
    }
}

void draw_line_Bresenham_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
    int32 dx, dy, e;
    if(abs(y1 - y0) < abs(x1 - x0))
    {
        if(x0 > x1)
        {
            swap(x0, x1);
            swap(y0, y1);
        }
        dx = (x1 - x0) << 1;
        dy = (y1 - y0) << 1;
        if(y0 < y1)
        {
            e = - (dx >> 1);
            while(x0 != x1)
            {
                draw_point_pen_2i(x0, y0);
                ++ x0;
                e = e + dy;
                if(e > 0)
                {
                    ++ y0;
                    e -= dx;
                }
            }
        }
        else
        {
            e = dx >> 1;
            while(x0 != x1)
            {
                draw_point_pen_2i(x0, y0);
                ++ x0;
                e = e + dy;
                if(e < 0)
                {
                    -- y0;
                    e += dx;
                }
            }
        }
    }
    else
    {
        if(y0 > y1)
        {
            swap(x0, x1);
            swap(y0, y1);
        }
        dx = (x1 - x0) << 1;
        dy = (y1 - y0) << 1;
        if(x0 < x1)
        {
            e = - (dy >> 1);
            while(y0 != y1)
            {
                draw_point_pen_2i(x0, y0);
                ++ y0;
                e = e + dx;
                if(e > 0)
                {
                    ++ x0;
                    e -= dy;
                }
            }
        }
        else
        {
            e = dy >> 1;
            while(y0 != y1)
            {
                draw_point_pen_2i(x0, y0);
                ++ y0;
                e = e + dx;
                if(e < 0)
                {
                    -- x0;
                    e += dy;
                }
            }
        }
    }
    draw_point_pen_2i(x0, y0);
}

draw_rectangle.h

#ifndef DRAW_RECTANGULAR_H_INCLUDED
#define DRAW_RECTANGULAR_H_INCLUDED

#include "define.h"
#include "draw_line.h"

typedef struct Rectangle_4i
{
    int32 x0, y0;
    int32 x1, y1;
}Rectangle_4i;

void draw_rectangle_T_4i(const Rectangle_4i rectangle);
void draw_rectangle_4i(int32 x0, int32 y0, int32 x1, int32 y1);

#endif // DRAW_RECTANGULAR_H_INCLUDED

draw_rectangle.c

#include "draw_rectangle.h"

void draw_rectangle_T_4i(const Rectangle_4i rectangle)
{
    draw_rectangle_4i(rectangle.x0, rectangle.y0,
                      rectangle.x1, rectangle.y1);
}

void draw_rectangle_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
    int32 i, j;
    draw_line_4i(x0, y0, x1, y0);
    draw_line_4i(x0, y1, x1, y1);
    draw_line_4i(x0, y0, x0, y1);
    draw_line_4i(x1, y0, x1, y1);
    if(x0 > x1)
    {
        swap(x0, x1);
    }
    if(y0 > y1)
    {
        swap(y0, y1);
    }
    ++ x0, -- x1;
    ++ y0, -- y1;
    for(i=x0;i<=x1;++i)
    {
        for(j=y0;j<=y1;++j)
        {
            draw_point_brush_2i(i, j);
        }
    }
}

draw_circle.h

#ifndef DRAW_CIRCLE_H_INCLUDED
#define DRAW_CIRCLE_H_INCLUDED

#include <math.h>
#include "define.h"
#include "draw_point.h"

typedef struct Circle_3i
{
    int32 x, y;
    int32 r;
}Circle_3i;

void draw_circle_T_3i(const Circle_3i circle);
void draw_circle_3i(int32 x, int32 y, int32 r);
void draw_circle_Coordinate_3i(int32 x, int32 y, int32 r);
void draw_circle_MidPoint_3i(int32 x, int32 y, int32 r);
void draw_circle_Bresenham_3i(int32 x, int32 y, int32 r);

#endif // DRAW_CIRCLE_H_INCLUDED

draw_circle.c

#include "draw_circle.h"

void draw_circle_T_3i(const Circle_3i circle)
{
    draw_circle_3i(circle.x, circle.y, circle.r);
}

void draw_circle_3i(int32 x, int32 y, int32 r)
{
    draw_circle_Bresenham_3i(x, y, r);
}

void draw_circle_Coordinate_3i(int32 x, int32 y, int32 r)
{
    int32 i, k, t, rr = (int32)ceil(r / sqrt(2.0));
    for(i=0;i<=rr;++i)
    {
        t = (int32)sqrt(r * r - i * i);
        for(k=y-i+1;k<y+i;++k)
        {
            draw_point_brush_2i(x + t, k);
            draw_point_brush_2i(x - t, k);
        }
        for(k=y-t+1;k<y+t;++k)
        {
            draw_point_brush_2i(x + i, k);
            draw_point_brush_2i(x - i, k);
        }
        draw_point_2i(x + i, y + t);
        draw_point_2i(x + i, y - t);
        draw_point_2i(x + t, y + i);
        draw_point_2i(x - t, y + i);
        draw_point_2i(x - i, y + t);
        draw_point_2i(x - i, y - t);
        draw_point_2i(x + t, y - i);
        draw_point_2i(x - t, y - i);
    }
}

void draw_circle_MidPoint_3i(int32 x, int32 y, int32 r)
{
    int32 d, i, j, k;
    int32 rr = (int32)ceil(r / sqrt(2.0));
    j = r;
    d = - (j<<2) + 5;
    for(i=0;i<=rr;++i)
    {
        for(k=y-i+1;k<y+i;++k)
        {
            draw_point_brush_2i(x + j, k);
            draw_point_brush_2i(x - j, k);
        }
        for(k=y-j+1;k<y+j;++k)
        {
            draw_point_brush_2i(x + i, k);
            draw_point_brush_2i(x - i, k);
        }
        draw_point_2i(x + i, y + j);
        draw_point_2i(x + i, y - j);
        draw_point_2i(x + j, y + i);
        draw_point_2i(x - j, y + i);
        draw_point_2i(x - i, y + j);
        draw_point_2i(x - i, y - j);
        draw_point_2i(x + j, y - i);
        draw_point_2i(x - j, y - i);
        if(d > 0)
        {
            d -= (i << 3) + 4;
        }
        else
        {
            -- j;
            d -= (i - j + 1) << 3;
        }
    }
}

void draw_circle_Bresenham_3i(int32 x, int32 y, int32 r)
{
    int32 e, i, j, k;
    int32 rr = (int32)ceil(r / sqrt(2.0));
    j = r;
    e = 3 - (r << 1);
    for(i=0;i<=rr;++i)
    {
        for(k=y-i+1;k<y+i;++k)
        {
            draw_point_brush_2i(x + j, k);
            draw_point_brush_2i(x - j, k);
        }
        for(k=y-j+1;k<y+j;++k)
        {
            draw_point_brush_2i(x + i, k);
            draw_point_brush_2i(x - i, k);
        }
        draw_point_2i(x + i, y + j);
        draw_point_2i(x + i, y - j);
        draw_point_2i(x + j, y + i);
        draw_point_2i(x - j, y + i);
        draw_point_2i(x - i, y + j);
        draw_point_2i(x - i, y - j);
        draw_point_2i(x + j, y - i);
        draw_point_2i(x - j, y - i);
        if(e < 0)
        {
           e += (i << 2) + 6;
        }
        else
        {
            e += ((i - j)<<2) + 10;
            -- j;
        }
    }
}

draw_ellipse.h

#ifndef DRAW_ELLIPSE_H_INCLUDED
#define DRAW_ELLIPSE_H_INCLUDED

#include <math.h>
#include "define.h"
#include "draw_point.h"

typedef struct Ellipse_4i
{
    int32 x0, y0;
    int32 x1, y1;
}Ellipse_4i;

void draw_ellipse_T_4i(const Ellipse_4i ellipse);
void draw_ellipse_4i(int32 x0, int32 y0, int32 x1, int32 y1);
void draw_ellipse_Coordinate_4i(int32 x0, int32 y0, int32 x1, int32 y1);
void draw_ellipse_Bresenham_4i(int32 x0, int32 y0, int32 x1, int32 y1);

#endif // DRAW_ELLIPSE_H_INCLUDED

draw_ellipse.c

#include "draw_ellipse.h"

void draw_ellipse_T_4i(const Ellipse_4i ellipse)
{
    draw_ellipse_4i(ellipse.x0, ellipse.y0, ellipse.x1, ellipse.y1);
}

void draw_ellipse_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
    draw_ellipse_Bresenham_4i(x0, y0, x1, y1);
}

void draw_ellipse_Coordinate_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
    int32 i, j, t;
    int32 x = (x0 + x1) >> 1;
    int32 y = (y0 + y1) >> 1;
    int32 a = abs(x0 - x1) >> 1;
    int32 b = abs(y0 - y1) >> 1;
    int32 aa = a * a;
    int32 bb = b * b;
    for(i=0;i<=a;++i)
    {
        t = (int32)sqrt(bb - 1.0 * bb / aa * i * i);
        for(j=y-t+1;j<y+t;++j)
        {
            draw_point_brush_2i(x + i, j);
            draw_point_brush_2i(x - i, j);
        }
        draw_point_2i(x + i, y + t);
        draw_point_2i(x + i, y - t);
        draw_point_2i(x - i, y + t);
        draw_point_2i(x - i, y - t);
    }
    for(i=0;i<=b;++i)
    {
        t = (int32)sqrt(aa - 1.0 * aa / bb * i * i);
        for(j=y-i+1;j<y+i;++j)
        {
            draw_point_brush_2i(x + t, j);
            draw_point_brush_2i(x - t, j);
        }
        draw_point_2i(x + t, y + i);
        draw_point_2i(x - t, y + i);
        draw_point_2i(x + t, y - i);
        draw_point_2i(x - t, y - i);
    }
}

void draw_ellipse_Bresenham_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
    int32 i, j, k;
    int32 x = (x0 + x1) >> 1;
    int32 y = (y0 + y1) >> 1;
    int32 a = abs(x0 - x1) >> 1;
    int32 b = abs(y0 - y1) >> 1;
    int64 e, aa, bb;
    aa = a * a;
    bb = b * b;
    j = b;
    e = (bb << 2) + aa * (1 - (b << 2));
    for(i=0;i<=a;++i)
    {
        for(k=y-j+1;k<y+j;++k)
        {
            draw_point_brush_2i(x + i, k);
            draw_point_brush_2i(x - i, k);
        }
        draw_point_2i(x + i, y + j);
        draw_point_2i(x + i, y - j);
        draw_point_2i(x - i, y + j);
        draw_point_2i(x - i, y - j);
        if(e <= 0)
        {
            e += bb * (12 + (i<<3));
        }
        else
        {
            e += bb * (12 + (i<<3)) + aa * (8 - (j<<3));
            -- j;
        }
        if(bb * ((i<<1) + 2) > aa * ((j<<1) - 1))
        {
            break;
        }
    }
    e = bb * ((i<<1) + 1) * ((i<<1) + 1) + aa * ((j<<1) - 2) * ((j<<1) - 2) - ((aa * bb)<<2);
    for(;j>=0;--j)
    {
        for(k=y-j+1;k<y+j;++k)
        {
            draw_point_brush_2i(x + i, k);
            draw_point_brush_2i(x - i, k);
        }
        draw_point_2i(x + i, y + j);
        draw_point_2i(x + i, y - j);
        draw_point_2i(x - i, y + j);
        draw_point_2i(x - i, y - j);
        if(e <= 0)
        {
            e += bb * (8 + (i<<3)) + aa * (12 - (j<<3));
            ++ i;
        }
        else
        {
            e += aa * (12 - (j<<3));
        }
    }
}



main.c

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include <math.h>
#include "define.h"
#include "gui.h"
#include "draw.h"

#define MAXN 100

static char tempText[1024];
static int32 operationState;
Point_2i points[MAXN];
Line_4i lines[MAXN];
Rectangle_4i rectangles[MAXN];
Circle_3i circles[MAXN];
Ellipse_4i ellipses[MAXN];
int32 pointNumber;
int32 lineNumber;
int32 rectangleNumber;
int32 circleNumber;
int32 ellipseNumber;

void displayFunction(void)
{
    int i;
    for(i=0;i<pointNumber;++i)
    {
        draw_point_T_2i(points[i]);
    }
    for(i=0;i<lineNumber;++i)
    {
        draw_line_T_4i(lines[i]);
    }
    for(i=0;i<rectangleNumber;++i)
    {
        draw_rectangle_T_4i(rectangles[i]);
    }
    for(i=0;i<circleNumber;++i)
    {
        draw_circle_T_3i(circles[i]);
    }
    for(i=0;i<ellipseNumber;++i)
    {
        draw_ellipse_T_4i(ellipses[i]);
    }
}

void reshapeFunction(int32 w, int32 h)
{
    gui_repaint();
}

void keyboardFunction(int32 key, int32 state, int32 x, int32 y)
{
    //TODO
}

void showCurrentStatus(int32 x, int32 y)
{
    struct tm *local;
    time_t t;
    t = time(NULL);
    local = localtime(&t);
    gui_setStatusBarText(0, "Zsys Studio 2012");
    switch(operationState)
    {
    case OP_DRAW_POINT_FREE:
        gui_setStatusBarText(1, "Draw Point");
        break;
    case OP_DRAW_LINE_FREE:
    case OP_DRAW_LINE_CLICK1:
        gui_setStatusBarText(1, "Draw Line");
        break;
    case OP_DRAW_RECTANGLE_FREE:
    case OP_DRAW_RECTANGLE_CLICK1:
        gui_setStatusBarText(1, "Draw Rectangle");
        break;
    case OP_DRAW_CIRCLE_FREE:
    case OP_DRAW_CIRCLE_CLICK1:
        gui_setStatusBarText(1, "Draw Circle");
        break;
    case OP_DRAW_ELLIPSE_FREE:
    case OP_DRAW_ELLIPSE_CLICK1:
        gui_setStatusBarText(1, "Draw Ellipse");
        break;
    default:
        gui_setStatusBarText(1, "No Operation");
    }
    sprintf(tempText, "Position: (%d,  %d)", x, y);
    gui_setStatusBarText(2, tempText);
    strcpy(tempText, "Time: 00:00:00");
    if(local->tm_hour > 9)
    {
        tempText[6] = local->tm_hour / 10 + '0';
    }
    tempText[7] = local->tm_hour % 10 + '0';
    if(local->tm_min > 9)
    {
        tempText[9] = local->tm_min / 10 + '0';
    }
    tempText[10] = local->tm_min % 10 + '0';
    if(local->tm_sec > 9)
    {
        tempText[12] = local->tm_sec / 10 + '0';
    }
    tempText[13] = local->tm_sec % 10 + '0';
    gui_setStatusBarText(3, tempText);
}

void mouseFunction(int32 button, int32 state, int32 x, int32 y)
{
    switch(state)
    {
    case MOUSE_DOWN:
        switch(button)
        {
            case MOUSE_LEFT:
                switch(operationState)
                {
                case OP_DRAW_POINT_FREE:
                    points[pointNumber].x = x;
                    points[pointNumber].y = y;
                    ++ pointNumber;
                    break;
                case OP_DRAW_LINE_FREE:
                    lines[lineNumber].x0 = x;
                    lines[lineNumber].y0 = y;
                    lines[lineNumber].x1 = x;
                    lines[lineNumber].y1 = y;
                    ++ lineNumber;
                    operationState = OP_DRAW_LINE_CLICK1;
                    break;
                case OP_DRAW_RECTANGLE_FREE:
                    rectangles[rectangleNumber].x0 = x;
                    rectangles[rectangleNumber].y0 = y;
                    rectangles[rectangleNumber].x1 = x;
                    rectangles[rectangleNumber].y1 = y;
                    ++ rectangleNumber;
                    operationState = OP_DRAW_RECTANGLE_CLICK1;
                    break;
                case OP_DRAW_CIRCLE_FREE:
                    circles[circleNumber].x = x;
                    circles[circleNumber].y = y;
                    circles[circleNumber].r = 0;
                    ++ circleNumber;
                    operationState = OP_DRAW_CIRCLE_CLICK1;
                    break;
                case OP_DRAW_ELLIPSE_FREE:
                    ellipses[ellipseNumber].x0 = x;
                    ellipses[ellipseNumber].y0 = y;
                    ellipses[ellipseNumber].x1 = x;
                    ellipses[ellipseNumber].y1 = y;
                    ++ ellipseNumber;
                    operationState = OP_DRAW_ELLIPSE_CLICK1;
                    break;
                }
                break;
            case MOUSE_MIDDLE:
                break;
            case MOUSE_RIGHT:
                switch(operationState)
                {
                case OP_DRAW_LINE_CLICK1:
                    -- lineNumber;
                    operationState = OP_DRAW_LINE_FREE;
                    break;
                case OP_DRAW_RECTANGLE_CLICK1:
                    -- rectangleNumber;
                    operationState = OP_DRAW_RECTANGLE_FREE;
                    break;
                case OP_DRAW_CIRCLE_CLICK1:
                    -- circleNumber;
                    operationState = OP_DRAW_CIRCLE_FREE;
                    break;
                case OP_DRAW_ELLIPSE_CLICK1:
                    -- ellipseNumber;
                    operationState = OP_DRAW_ELLIPSE_FREE;
                    break;
                }
                break;
        }
        break;
    case MOUSE_UP:
        switch(button)
        {
            case MOUSE_LEFT:
                switch(operationState)
                {
                case OP_DRAW_LINE_CLICK1:
                    lines[lineNumber - 1].x1 = x;
                    lines[lineNumber - 1].y1 = y;
                    operationState = OP_DRAW_LINE_FREE;
                    break;
                case OP_DRAW_RECTANGLE_CLICK1:
                    rectangles[rectangleNumber - 1].x1 = x;
                    rectangles[rectangleNumber - 1].y1 = y;
                    operationState = OP_DRAW_RECTANGLE_FREE;
                    break;
                case OP_DRAW_CIRCLE_CLICK1:
                    circles[circleNumber - 1].r = sqrt((circles[circleNumber-1].x - x) *
                                                       (circles[circleNumber-1].x - x) +
                                                       (circles[circleNumber-1].y - y) *
                                                       (circles[circleNumber-1].y - y));
                    operationState = OP_DRAW_CIRCLE_FREE;
                    break;
                case OP_DRAW_ELLIPSE_CLICK1:
                    ellipses[ellipseNumber - 1].x1 = x;
                    ellipses[ellipseNumber - 1].y1 = y;
                    operationState = OP_DRAW_ELLIPSE_FREE;
                    break;
                }
                break;
                break;
            case MOUSE_MIDDLE:
                break;
            case MOUSE_RIGHT:
                break;
        }
        break;
    }
    showCurrentStatus(x, y);
    gui_repaint();
}

void motionFunction(int32 x, int32 y)
{
    switch(operationState)
    {
    case OP_DRAW_LINE_CLICK1:
        lines[lineNumber - 1].x1 = x;
        lines[lineNumber - 1].y1 = y;
        break;
    case OP_DRAW_RECTANGLE_CLICK1:
        rectangles[rectangleNumber - 1].x1 = x;
        rectangles[rectangleNumber - 1].y1 = y;
        break;
    case OP_DRAW_CIRCLE_CLICK1:
        circles[circleNumber - 1].r = sqrt((circles[circleNumber-1].x - x) *
                                           (circles[circleNumber-1].x - x) +
                                           (circles[circleNumber-1].y - y) *
                                           (circles[circleNumber-1].y - y));
        break;
    case OP_DRAW_ELLIPSE_CLICK1:
        ellipses[ellipseNumber - 1].x1 = x;
        ellipses[ellipseNumber - 1].y1 = y;
        break;
    }
    gui_repaint();
    showCurrentStatus(x, y);
}

void menuFunction(int32 id)
{
    switch(id)
    {
    case MENU_FILE_EXIT:
        exit(0);
        break;
    case MENU_TOOLS_POINT:
        operationState = OP_DRAW_POINT_FREE;
        break;
    case MENU_TOOLS_LINE:
        operationState = OP_DRAW_LINE_FREE;
        break;
    case MENU_TOOLS_RECTANGLE:
        operationState = OP_DRAW_RECTANGLE_FREE;
        break;
    case MENU_TOOLS_CIRCLE:
        operationState = OP_DRAW_CIRCLE_FREE;
        break;
    case MENU_TOOLS_ELLIPSE:
        operationState = OP_DRAW_ELLIPSE_FREE;
        break;
    case MENU_HELP_ABOUT:
        gui_informationBox("About...", "Zsys Studio 2012");
        break;
    }
}

int main()
{
    #ifndef DEBUG
        freopen("log.txt", "w", stdout);
    #endif
    freopen("error.txt", "w", stderr);

    gui_createMainWindow("ZPIC");
    gui_setMainWindowSize(800, 600);
    gui_setMainWindowToCenter();
    gui_menu_createMenu();
    gui_createStatusBar();

    gui_setDisplayFunction(displayFunction);
    gui_setReshapeFunction(reshapeFunction);
    gui_setKeyboardFunction(keyboardFunction);
    gui_setMouseFunction(mouseFunction);
    gui_setMotionFunction(motionFunction);
    gui_setMenuFunction(menuFunction);

    draw_init();
    draw_pen_setColor(draw_color_getColor_3i(0, 0, 0));
    draw_brush_setColor(draw_color_getColor_3i(180, 180, 200));
    operationState = OP_DRAW_NULL;
    pointNumber = 0;
    lineNumber = 0;
    rectangleNumber = 0;
    circleNumber = 0;
    ellipseNumber = 0;

    gui_mainLoop();
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值