C语言中ellipse函数如何绘制椭圆?

99ANYc3cd6
预计阅读时长 18 分钟
位置: 首页 C语言 正文

使用EasyX图形库(Windows平台)

EasyX是Windows平台下的轻量级图形库,适合初学者。

c语言 ellipse
(图片来源网络,侵删)
#include <graphics.h>  // EasyX头文件
#include <conio.h>
int main() {
    initgraph(640, 480);  // 创建640x480的绘图窗口
    // 绘制椭圆:中心点(x, y),长半轴rx,短半轴ry
    ellipse(320, 240, 100, 50);  // 中心(320,240),长轴200,短轴100
    getch();  // 等待按键
    closegraph();  // 关闭绘图窗口
    return 0;
}

说明:

  • ellipse(x, y, rx, ry):以(x, y)为中心,绘制长半轴为rx、短半轴为ry的椭圆。
  • 需要先安装EasyX库(官网:easyx.cn)。

使用Win32 API(Windows平台)

直接调用Windows系统API绘制椭圆。

#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    HWND hWnd;
    MSG msg;
    WNDCLASS wc = {0};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = "EllipseWindow";
    RegisterClass(&wc);
    hWnd = CreateWindow("EllipseWindow", "Ellipse Demo", WS_OVERLAPPEDWINDOW, 
                        100, 100, 640, 480, NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, nCmdShow);
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    HDC hdc;
    PAINTSTRUCT ps;
    switch (message) {
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            // 绘制椭圆:左上角坐标(220,190),宽200,高100
            Ellipse(hdc, 220, 190, 420, 290);
            EndPaint(hWnd, &ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

说明:

  • Ellipse(hdc, x1, y1, x2, y2):绘制一个矩形内切椭圆,(x1,y1)(x2,y2)是矩形对角点坐标。

使用SDL库(跨平台)

SDL(Simple DirectMedia Layer)支持跨平台图形绘制。

c语言 ellipse
(图片来源网络,侵删)
#include <SDL2/SDL.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* window = SDL_CreateWindow("Ellipse Demo", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);  // 红色
    for (int i = 0; i < 100; i++) {
        // 使用点阵近似绘制椭圆(Bresenham算法)
        int x = 320 + (int)(100 * cos(i * 0.1));
        int y = 240 + (int)(50 * sin(i * 0.1));
        SDL_RenderDrawPoint(renderer, x, y);
    }
    SDL_RenderPresent(renderer);
    SDL_Delay(5000);  // 显示5秒
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

说明:

  • 需要安装SDL2库(SDL官网)。
  • 此示例通过绘制点阵近似椭圆,实际开发中可用SDL_RenderDrawLine结合数学公式实现更精确的椭圆。

手动实现椭圆绘制(Bresenham算法)

不依赖图形库,用纯C代码实现(控制台输出)。

#include <stdio.h>
#include <math.h>
void drawEllipse(int xc, int yc, int rx, int ry) {
    float dx, dy, d1, d2, x, y;
    x = 0;
    y = ry;
    // 初始化误差
    d1 = (ry * ry) - (rx * rx * ry) + (0.25 * rx * rx);
    dx = 2 * ry * ry * x;
    dy = 2 * rx * rx * y;
    // 绘制第一部分(斜率>1)
    while (dx < dy) {
        printf("(%d, %d) ", xc + (int)x, yc + (int)y);
        printf("(%d, %d) ", xc - (int)x, yc + (int)y);
        printf("(%d, %d) ", xc + (int)x, yc - (int)y);
        printf("(%d, %d)\n", xc - (int)x, yc - (int)y);
        x++;
        dx = 2 * ry * ry * x;
        if (d1 < 0) {
            d1 = d1 + dx + (ry * ry);
        } else {
            y--;
            dy = 2 * rx * rx * y;
            d1 = d1 + dx - dy + (ry * ry);
        }
    }
    // 绘制第二部分(斜率<1)
    d2 = ((ry * ry) * ((x + 0.5) * (x + 0.5))) + 
         ((rx * rx) * ((y - 1) * (y - 1))) - (rx * rx * ry * ry);
    while (y >= 0) {
        printf("(%d, %d) ", xc + (int)x, yc + (int)y);
        printf("(%d, %d) ", xc - (int)x, yc + (int)y);
        printf("(%d, %d) ", xc + (int)x, yc - (int)y);
        printf("(%d, %d)\n", xc - (int)x, yc - (int)y);
        y--;
        dy = 2 * rx * rx * y;
        if (d2 > 0) {
            d2 = d2 - dy + (rx * rx);
        } else {
            x++;
            dx = 2 * ry * ry * x;
            d2 = d2 + dx - dy + (rx * rx);
        }
    }
}
int main() {
    drawEllipse(0, 0, 10, 5);  // 中心(0,0),长半轴10,短半轴5
    return 0;
}

说明:

  • 输出椭圆的坐标点(可替换为实际绘图操作)。
  • 基于Bresenham算法优化,适合嵌入式或无图形库环境。

方法 适用场景 优点 缺点
EasyX Windows初学者 简单易用 仅限Windows
Win32 API Windows原生开发 高性能,系统级支持 代码复杂,仅Windows
SDL 跨平台游戏/图形应用 跨平台,功能丰富 需额外安装库
手动实现 无图形库环境 无依赖,灵活 需要数学基础,实现复杂

根据需求选择合适的方法,如果是快速原型开发,推荐EasyX或SDL;如果是底层学习,手动实现算法更有价值。

-- 展开阅读全文 --
头像
织梦如何调用三级栏目?
« 上一篇 昨天
dede文化传播模板如何适配多终端?
下一篇 » 昨天

相关文章

取消
微信二维码
支付宝二维码

目录[+]