【问题标题】:Calculate area of Rectilinear Polygon in C计算C中直线多边形的面积
【发布时间】:2021-04-15 18:50:40
【问题描述】:

我必须为一组给定的输入值开发一个 C 程序,我们通过指定一个起点和四个基本方向上的一系列运动来描述矩形图形的边界——就好像我们在绕着队形走一样沿着它的边界。
我们输入每个移动的方向(WESN)和长度——“W 3”表示从当前位置向西移动三步(左)。

图 1 中的图形可以从右上角开始描述为:

"W 6, S 2, W 3, S 2, E 1, S 2, E 2, N 1, E 2, N 1, E 2, N 1, W 2, N 1, E 3,S 3,E 1,N 5"。

我的问题是:

  1. 这种形状在几何学中叫什么?
  2. 如何计算这种形状的面积?我有 W6、S4 等所有边的长度。

谢谢。

【问题讨论】:

  • 这看起来更像是Mathematics 问题。一旦你学会了如何在几何中做到这一点,如何将其转换为 C 应该就变得很明显了。
  • 称为多边形。
  • 更具体地说它是一个凹多边形
  • 您可以垂直(或水平)逐个扫描。一旦您越过边界一次,您就会知道您在多边形“内部”。一旦你再次穿过它 - 你就在外面。等等。所以计算“内部”的方块。
  • 使用A = ... 适用于任何多边形 - 有效地将其分解为三角形。

标签: c math geometry area


【解决方案1】:

这可以称为直线多边形。

计算任何多边形面积的通用算法是:

  • 让 (xo, yo) 成为起点(“o”代表旧)。
  • 将总和 S 初始化为零。
  • 对于每个动作:
    • 根据运动和旧点计算新点 (xn, yn)(“n”代表新点)。
    • 将 xn•yo−xo•yn 添加到 S.
    • 设置 xo=xn 和 yo=yn。
  • 多边形内的面积是|S|/2。

上面假设最后一次移动关闭了多边形,所以最后一点是起点。如果不是,则应保存起点的副本并用于与最后一点的总和。

这使用了sum/algorithmchux指出的。

【讨论】:

    【解决方案2】:

    形状称为polyomino。这是多边形的特例。

    找到面积的问题可以从点(0,0)开始,用一个面积为0的多边形来解决。接下来,在水平移动的同时将区域扩展为矩形。

    假设当前点是(x,y)。向东移动d 单位意味着在点(x,0) -> (x,y) -> (x + d, y) -> (x + d, 0) 处添加一个矩形。矩形的面积是d * y。 向西移动时,需要减去矩形。

    如果路径是顺时针方向,则最终区域为正数;如果路径为逆时针方向,则最终区域为负数。

    这种方法产生了一个非常简单的程序:

    #include <stdio.h>
    
    int main() {
        int x = 0, y = 0, A = 0, d;
        int c;
        while ((c = getchar()) != EOF) { 
            if        (c == 'W' && scanf(" %d", &d) == 1) {
                x += d;
                A += d * y;
            } else if (c == 'E' && scanf(" %d", &d) == 1) {
                x -= d;
                A -= d * y;
            } else if (c == 'N' && scanf(" %d", &d) == 1) {
                y += d;
            } else if (c == 'S' && scanf(" %d", &d) == 1) {
                y -= d;
            }
        }
        if (A < 0) A = -A;
        printf("%d\n", A);
        return 0;
    }
    

    问题的输入给出了33 的预期答案。

    【讨论】:

    • 感谢您的帮助。是否有可能检查步行中的线是否在某个点相交、接触或交叉。谢谢
    • @AhsanAli,如果需要 O(n) 或 O(n log n) 算法,则要复杂得多。我会想办法解决的
    猜你喜欢
    • 2014-09-05
    • 2013-11-13
    • 2015-06-29
    • 2013-10-24
    • 2011-01-03
    • 2010-11-26
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多