You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于BGI的C语言图形面积计算:单位方格计数代码修正需求

问题分析与修复方案

你的代码在计算四边形面积(统计单位方格数)时存在几个关键问题,导致结果错误:

核心问题点

  • 点-in-多边形判断逻辑残缺:
    你只在点处于边的包围盒内时才计算叉积,而且仅判断叉积<0就标记为外部,这会漏掉大量应该被统计的点,同时也没处理点在边上的情况。正确的做法是对所有边计算位置关系,同时单独检测点是否在边上。
  • 遍历范围未包含边界:
    循环条件i < maxX和j < maxY会漏掉maxX、maxY对应的行/列,导致图形最右侧和最下方的方格未被统计。
  • 无意义的除法操作:
    最后输出时toplamBirimKare / 100完全错误,统计的单位方格数就是面积值,不需要除以100。
  • 未统计边经过的方格:
    当前逻辑只统计内部点,边经过的方格没有被纳入统计,需要补充边的方格检测。

修正后的代码

#include <stdio.h>
#include <graphics.h>

// 判断点(x,y)是否在线段(x1,y1)-(x2,y2)上
int nokta_cizgide_mi(int x, int y, int x1, int y1, int x2, int y2) {
    // 先判断点是否在线段的包围盒内
    if (x < (x1 < x2 ? x1 : x2) || x > (x1 > x2 ? x1 : x2))
        return 0;
    if (y < (y1 < y2 ? y1 : y2) || y > (y1 > y2 ? y1 : y2))
        return 0;
    // 叉积为0说明共线,确认点在线段上
    return (x - x1) * (y2 - y1) == (y - y1) * (x2 - x1);
}

// 判断点(x,y)是否在四边形内部或边上
int icinde_veya_uzerinde_mi(int x, int y, int x_dizi[], int y_dizi[]) {
    int kesisim_sayisi = 0;
    int kenar_sayisi = 4;
    for (int k = 0; k < kenar_sayisi; k++) {
        int x1 = x_dizi[k], y1 = y_dizi[k];
        int x2 = x_dizi[(k+1)%kenar_sayisi], y2 = y_dizi[(k+1)%kenar_sayisi];
        
        // 先判断点是否在当前边上
        if (nokta_cizgide_mi(x, y, x1, y1, x2, y2)) {
            return 1;
        }
        
        // 射线法:统计点向右的射线与边的交点数,奇数则在内部
        if (((y1 > y) != (y2 > y)) && 
            (x < (x2 - x1) * (float)(y - y1) / (y2 - y1) + x1)) {
            kesisim_sayisi++;
        }
    }
    return kesisim_sayisi % 2 == 1;
}

void dortgen_alani(int sekil_ciz[][2]) {
    int x[4], y[4];

    for (int i = 0; i < 4; i++) {
        x[i] = sekil_ciz[i][0];
        y[i] = sekil_ciz[i][1];
        putpixel(x[i], y[i], WHITE); // 标记顶点
    }

    int toplamBirimKare = 0;

    int minX = x[0], minY = y[0];
    int maxX = x[0], maxY = y[0];

    for (int i = 1; i < 4; i++) {
        if (x[i] < minX) minX = x[i];
        if (x[i] > maxX) maxX = x[i];
        if (y[i] < minY) minY = y[i];
        if (y[i] > maxY) maxY = y[i];
    }
 
    // 遍历包含边界的所有方格
    for (int i = minX; i <= maxX; i++) {
        for (int j = minY; j <= maxY; j++) {
            if (icinde_veya_uzerinde_mi(i, j, x, y)) {
                putpixel(i, j, BLUE);
                toplamBirimKare++;
            }
        }
    }

    printf("Dortgenin alani (birim karelerle): %d birim kare\n", toplamBirimKare);
}

修正说明

  1. 新增边检测函数:nokta_cizgide_mi专门判断点是否在边上,确保边经过的方格被统计。
  2. 改用射线法判断内部点:icinde_veya_uzerinde_mi使用射线法,通过统计点向右射线与边的交点数,奇数则判定为内部点,同时优先处理点在边上的情况。
  3. 修正遍历范围:将i < maxX改为i <= maxX,j < maxY改为j <= maxY,包含所有边界方格。
  4. 移除错误除法:直接输出统计的toplamBirimKare值,这就是实际的单位方格数(面积)。

内容的提问来源于stack exchange,提问作者erkan2541

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 06:35:37