C语言如何绘制希尔伯特曲线?

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

C语言绘制希尔伯特曲线

希尔伯特曲线是一种空间填充曲线,可以通过递归的方式绘制,下面是一个用C语言实现绘制希尔伯特曲线的完整程序,使用SDL库进行图形显示。

完整代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <SDL2/SDL.h>
// 定义窗口大小
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 800
// 递归绘制希尔伯特曲线
void hilbert(SDL_Renderer *renderer, int x, int y, int xi, int xj, int yi, int yj, int n) {
    if (n <= 0) {
        // 绘制当前线段
        SDL_RenderDrawLine(renderer, x, y, x + (xi + yi) / 2, y + (xj + yj) / 2);
        return;
    }
    // 递归绘制四个子曲线
    hilbert(renderer, x, y, yi / 2, yj / 2, xi / 2, xj / 2, n - 1);
    hilbert(renderer, x + (xi + yi) / 2, y + (xj + yj) / 2, xi / 2, xj / 2, yi / 2, yj / 2, n - 1);
    hilbert(renderer, x + (xi + yi) / 2 + (xi - yi) / 2, y + (xj + yj) / 2 + (xj - yj) / 2, 
            xi / 2, xj / 2, yi / 2, yj / 2, n - 1);
    hilbert(renderer, x + (xi - yi) / 2, y + (xj - yj) / 2, -yi / 2, -yj / 2, -xi / 2, -xj / 2, n - 1);
}
int main(int argc, char *argv[]) {
    // 初始化SDL
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        fprintf(stderr, "SDL初始化失败: %s\n", SDL_GetError());
        return 1;
    }
    // 创建窗口
    SDL_Window *window = SDL_CreateWindow("希尔伯特曲线", 
                                         SDL_WINDOWPOS_UNDEFINED, 
                                         SDL_WINDOWPOS_UNDEFINED, 
                                         WINDOW_WIDTH, 
                                         WINDOW_HEIGHT, 
                                         SDL_WINDOW_SHOWN);
    if (window == NULL) {
        fprintf(stderr, "窗口创建失败: %s\n", SDL_GetError());
        SDL_Quit();
        return 1;
    }
    // 创建渲染器
    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    if (renderer == NULL) {
        fprintf(stderr, "渲染器创建失败: %s\n", SDL_GetError());
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 1;
    }
    // 设置绘制颜色
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); // 白色背景
    SDL_RenderClear(renderer);
    // 设置曲线颜色
    SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); // 蓝色曲线
    // 绘制希尔伯特曲线
    int order = 5; // 递归深度,值越大曲线越复杂
    int size = WINDOW_WIDTH * 0.8; // 曲线大小
    int margin = (WINDOW_WIDTH - size) / 2;
    hilbert(renderer, margin, margin, size, 0, 0, size, order);
    // 更新屏幕
    SDL_RenderPresent(renderer);
    // 等待用户关闭窗口
    SDL_Event event;
    int quit = 0;
    while (!quit) {
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                quit = 1;
            }
        }
        SDL_Delay(100);
    }
    // 清理资源
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

代码说明

  1. 希尔伯特曲线递归函数 hilbert():

    • 参数解释:
      • (x, y): 当前线段的起点坐标
      • (xi, xj): 方向向量x分量
      • (yi, yj): 方向向量y分量
      • n: 递归深度
  2. 主函数 main():

    • 初始化SDL库和创建窗口、渲染器
    • 设置绘制颜色和背景
    • 调用hilbert()函数绘制曲线
    • 等待用户关闭窗口

编译和运行

  1. 确保已安装SDL2库(在Linux上可以使用sudo apt-get install libsdl2-dev
  2. 编译命令:
    gcc hilbert_curve.c -o hilbert_curve -lSDL2
  3. 运行:
    ./hilbert_curve

效果

程序会显示一个窗口,其中绘制了蓝色的希尔伯特曲线,你可以通过修改order变量来改变曲线的递归深度(值越大曲线越复杂)。

其他实现方式

如果不使用SDL,也可以使用其他图形库如OpenGL或简单的控制台字符绘制,下面是一个简单的控制台版本:

#include <stdio.h>
void hilbert(int x, int y, int xi, int xj, int yi, int yj, int n) {
    if (n <= 0) {
        printf("(%d,%d) ", x + (xi + yi) / 2, y + (xj + yj) / 2);
        return;
    }
    hilbert(x, y, yi/2, yj/2, xi/2, xj/2, n-1);
    hilbert(x + (xi+yi)/2, y + (xj+yj)/2, xi/2, xj/2, yi/2, yj/2, n-1);
    hilbert(x + (xi+yi)/2 + (xi-yi)/2, y + (xj+yj)/2 + (xj-yj)/2, xi/2, xj/2, yi/2, yj/2, n-1);
    hilbert(x + (xi-yi)/2, y + (xj-yj)/2, -yi/2, -yj/2, -xi/2, -xj/2, n-1);
}
int main() {
    printf("希尔伯特曲线坐标:\n");
    hilbert(0, 0, 256, 0, 0, 256, 3);
    printf("\n");
    return 0;
}

这个版本会在控制台输出曲线的坐标点。

-- 展开阅读全文 --
头像
织梦如何删除友情链接?
« 上一篇 03-07
C语言简单计算器如何实现基础运算功能?
下一篇 » 03-07

相关文章

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

目录[+]