多边形的面积(使用 Python 递归)

2023-11-27

我正在尝试解决《探索Python》书中的一个练习。但是,我想我不理解递归的概念。我写了一些递归函数。所以我知道一些方面。但是,我没有足够的经验。我已经停止学习编程大约一年了。

无论如何,让我给你一个完整的问题:

多边形可以由 (x, y) 对列表表示,其中每对 是一个元组:[ (x1, y1), (x2, y2), (x3, y3) , ... (xn, yn)]。写一个 计算多边形面积的递归函数。这可以是 通过“切断”三角形来完成,利用以下事实: 具有角 (x1, y1)、(x2, y2)、(x3, y3) 的三角形的面积为 (x1y1 + x2y2 + x3y2 – y1x2 –y2x3 – y3x1) / 2。

尽管问题已经给出了公式,但我使用了另一个公式。因为,我对多边形的面积进行了一些研究。如果你看一下here公式不同。

一步步描述我的程序会更好,以便解释我想要什么。 好吧,由于递归,我必须声明全局作用域:

area = 0
x = [0] * 3
y = [0] * 3 

然后,我创建了一个递归函数。该函数始终返回零作为结果。所以我真正的问题是:

def areaofpolygon(polygon, i):
    global area, x, y # My variables 
    try: # I prefered using try statement from using if-else statements. So it is the easier I guess.
        x[i], y[i] = polygon[i] # X and Y coordinates from tuple
        area += (x[i]*y[i+1] - x[i+1]*y[i]) #My formula
    except IndexError:
        return area/2
    
    areaofpolygon(polygon, i+1)   # Here, this is my weird recursion

我的主要功能:

  def main():
      mypolygon = [(1,2), (2,5), (1,4)] # I declared polygon as tuples
      # I called my function and started to count from zero, and the result will be prompted.
      print(areaofpolygon(mypolygon,0))
        
      return 0
  if __name__ == '__main__':
      main()

这是我的完整代码,没有注释:

'''
Created on Feb 24, 2012

@author: msarialp
'''
area = 0
x = [0] * 3
y = [0] * 3
def areaofpolygon(polygon, i):
    global area, x, y
    try:
        x[i], y[i] = polygon[i]
        area += (x[i]*y[i+1] - x[i+1]*y[i])
    except IndexError:
        return area/2
    
    areaofpolygon(polygon, i+1)   
def main():
    mypolygon = [(1,2), (2,5), (1,4)]
    print(areaofpolygon(mypolygon,0))
    
    return 0
if __name__ == '__main__':
    main()

EDIT One

阅读您的答案后,我明白了我的代码出了什么问题。所以我决定分享我的程序的最后一个版本以获得一些其他帮助。 同样,我必须声明全局变量。我如何从 senderle 应用( lop_triangle )函数

area = 0
x = [0] * 3
y = [0] * 3

我的函数划分元组并获取 x 和 y 坐标。

def sides_of_polygon(polygon, i):
    global x, y
    try:
        x[i], y[i] = polygon[i]
        return sides_of_polygon(polygon, i+1)
    except IndexError:
        return x, y

我的函数计算多边形的面积(与以前相同)

def area_of_polygon(x, y, i):
    global area
    try:
        area += x[i]*y[i+1] - x[i+1]*y[i]
        return area_of_polygon(x, y, i+1)
    except IndexError:
        return area/2.0

我的主要功能...

def main():
    mypolygon = [(1,2), (2,5), (1,4)]
    dx, dy = sides_of_polygon(mypolygon, 0)
    print(area_of_polygon(dx,dy,0))
    
    return 0
if __name__ == '__main__':
    main()

请帮助我改进我的代码而不给出完整的解决方案。

EDIT Two

经过与senderle的讨论,我明白了问题出在哪里,并且senderle的解决方案比我的更好,所以我建议你应该使用它。 不管怎样,他帮助我使我的代码正确。我不得不再次更改我的公式。

area += x[i]*y[(i+1) % 3] - x[(i+1) % 3]*y[i]

他还补充说,对于较长的多边形,3 必须是 len(顶点)。 感谢大家抽出时间。


递归的本质如下:

  1. 确定一个简单的基本情况并解决它。
  2. 设想一个过程,当重复时,将更复杂的情况简化为基本情况。
  3. 将 #2 中的过程应用于问题,直到达到基本情况。

就您而言,第一步很简单。最小的多边形是三角形。三角形的面积是(x1y2 + x2y3 + x3y1 – y1x2 –y2x3 – y3x1) / 2。 (看起来他们在问题中错误地表述了它......)

第二步也很简单,因为问题陈述给了你:给定一个 n 顶点多边形,剪掉一个三角形,确定其面积,并将其添加到生成的 (n-1) 顶点多边形的面积中。

我们将把它分解成几个部分。首先,一个解决#1 问题的函数:

def area_of_triangle(points):
    (x1, y1), (x2, y2), (x3, y3) = points
    return abs(x1 * y2 + x2 * y3 + x3 * y1 - y1 * x2 - y2 * x3 - y3 * x1) / 2

简单的。现在是解决#2 问题的函数。我们所需要的只是一个函数,它可以切掉一个三角形并返回它以及得到的较小的多边形:

def lop_triangle(points):
    triangle = [points[0], points[-1], points[-2]]
    polygon = points[:-1]
    return triangle, polygon

如果不明显,这只是使用多边形的第一个和最后两个点创建一个三角形。然后它删除多边形的最后一个点,这现在相当于砍掉三角形。 (绘制一个 n 多边形并将其顶点标记为 0 到 n,看看它是如何工作的。)现在我们有一个三角形和一个更简单的多边形。

现在,让我们把它们放在一起。从某些方面来说,第三步是最难的,但因为我们已经解决了前两个问题,所以第三步更容易理解。

def area_of_polygon(points):
    if len(points) == 3:
        return area_of_triangle(points)
    else:
        triangle, polygon = lop_triangle(points)
        return area_of_triangle(triangle) + area_of_polygon(polygon)

所有的魔法都发生在最后一行。每次area_of_polygon得到一个三角形,它只返回三角形的面积。但是当它得到一个更大的多边形时,它会剪掉一个三角形,获取该三角形的面积,然后将其添加到......较小多边形的面积。假设多边形有 5 个顶点。第一次area_of_polygon称为 (c1),它会剪掉一个三角形,获取其面积,然后调用area_of_polygon (c2) again,但这次是 4 顶点多边形。然后area_of_polygon三角形的垂数,并调用area_of_polygon (c3) again,但这次是一个 3 顶点多边形。然后就不必调用area_of_polygon再次。它只是将三角形的面积返回到之前的调用 (c2)。将结果与 (c2) 中的三角形相加,并将该值返回给 (c1)。然后你就有了答案。

另外,就其价值而言,钨公式可以非常清晰地写成三行:

def area_of_polygon(vertices):
    pairs = zip(vertices, vertices[1:] + vertices[0:1])
    return sum(x1 * y2 - y1 * x2 for (x1, y1), (x2, y2) in pairs) / 2
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多边形的面积(使用 Python 递归) 的相关文章

随机推荐

  • 如何从 Laravel URL 中删除 /public/ [重复]

    这个问题在这里已经有答案了 我想删除 public 来自我的 Laravel 5 URL 的片段 我不想运行虚拟机 这在项目之间切换时看起来很尴尬 我不想将文档根目录设置为公共文件夹 这在项目之间切换时也很尴尬 我尝试过 htaccess
  • p:steps 但启用点击所有步骤

    我有使用标签的 primefaces 步骤
  • 如何解决 Java 泛型中由交集类型引起的不明确方法?

    我最近发现您可以在单个类型参数绑定中指定多个类型 请参阅示例 与任何新工具一样 我一直在尝试探索如何使用 和滥用 它的可能性 我精心设计了这个例子来帮助说明 在下面的示例中 编译器给我一个错误 调度 新 AlphabetSoup 方法dis
  • CSS 背景不透明度[重复]

    这个问题在这里已经有答案了 我正在使用类似于以下代码的东西 div style background image url div Text div div 我预计这将使背景的不透明度为 0 4 文本的不透明度为 100 相反 它们的不透明度
  • 使div边框的一部分透明html

    我可以使 div 边框的一部分 从 x1 到 x2 透明吗 如果没有 您可以建议什么方法 我的想法 非常糟糕 是在 canvas 元素中绘制边框并将其放置在 div 元素上 画布主体是透明的 由于 DIV 只有 4 个元素 上 下 左 右
  • 如何四舍五入到最接近的 10(或 100 或 X)?

    我正在编写一个函数来绘制数据 我想为 y 轴指定一个很好的整数max大于数据集的最大值 具体来说 我想要一个函数foo执行以下操作 foo 4 5 foo 6 1 10 maybe 7 would be better foo 30 1 40
  • Google OAuth 2.0 include_granted_scopes 不适用于已安装的应用程序

    我正在尝试使用新的增量授权对于已安装的应用程序 以便将范围添加到现有授权 同时保留现有范围 这是使用新的完成的include granted scopes true范围 但是 无论我尝试什么 重新授权总是会完全覆盖范围 这是我编写的用于演示
  • 删除我的 Rails 答案中不必要的 HTTP 标头

    我目前正在开发一个 API 其中大小很重要 我希望答案包含尽可能少的字节 我优化了 JSON 答案 但 Rails 仍然响应许多奇怪的标头 HTTP 1 1 200 OK Server nginx 0 7 67 Not from Rails
  • 创建一个运行程序的新任务

    我需要定义一个自定义任务来计算主类的名称然后运行它 我在想这样的事情 customTask mainClass compute main class name based on env runMain mainClass jvm args
  • 使用 ggplot2 绘制二部网络图

    我有以下数据框 structure list X1 structure c 1L 1L 1L 1L 1L 1L 1L 1L 2L 2L 2L 2L 2L 2L 2L 2L 2L 2L 3L 3L 3L 3L 4L 4L 4L 4L 4L 5
  • 在 Java 中将 ExecutorService 转为守护进程

    我正在 Java 1 6 中使用 ExecutoreService 只需通过以下方式启动 ExecutorService pool Executors newFixedThreadPool THREADS 当我的主线程完成 以及线程池处理的
  • OPENgl - GL/glut.h 没有这样的文件或目录

    任何人都可以帮我解决以下错误 GL glut h 没有这样的文件或目录 我所做的事情是 安装 MinGW 后 我已将 Path 添加到路径中 环境变量 将 glut h 添加到 C MinGW Include GL 将 glut32 dll
  • XAML 中的 Metro(Windows 应用商店应用程序)日期时间格式

    我有一个 DateTime 属性 这是绑定到文本框的
  • 引导崩溃。如何一次只展开一个div

    我怎样才能一次展示一个 Demo http jsfiddle net tvvq59wv collapser click function this next collapse toggle div div
  • 如何使用 Autofac 注入 AutoMapper?

    将 AutoMapper 注入其他层的正确方法是什么 我读了这个博客post 但是这段代码导致下面的异常 AutoMapper dll 中发生 AutoMapper AutoMapperMappingException 类型的异常 但未在用
  • 限制在 contenteditable 中粘贴(HTML / JS)

    我想阻止用户将不允许的标记粘贴到contenteditable div 我想将粘贴限制为粗体 斜体 删除线 下划线和链接 最好的方法是什么 我正在使用jQuery 这不是重复的JQuery 文本编辑器粘贴而不带格式 我不想在没有格式化的情况
  • Python Selenium Webdriver 检查元素是否不存在需要时间

    在几次 GUI 操作后尝试验证某些按钮不存在 预计不存在 我正在使用 find element by xpath 但它非常慢 超时有什么解决办法吗 实际上 如果未找到指定的元素 WebDriver 的 find element 方法将等待该
  • 有人可以向我解释一下 class << self 吗?

    我第一次进入 Rails 编程 在查看我下载的一些库的代码时 我偶尔会注意到这些代码 class lt lt self def func stuff end end 我尝试在网上搜索解释 但是 在红宝石中 class lt lt foo打开
  • 如何在 WP7 中将多个值数据绑定到单个 TextBlock.Text?

    如何将 2 个属性绑定到单个 TextBlock Text 例如名字和姓氏或当前值和最大值 就像是 IValueConverter public object Convert return string Format 0 max 1 cur
  • 多边形的面积(使用 Python 递归)

    我正在尝试解决 探索Python 书中的一个练习 但是 我想我不理解递归的概念 我写了一些递归函数 所以我知道一些方面 但是 我没有足够的经验 我已经停止学习编程大约一年了 无论如何 让我给你一个完整的问题 多边形可以由 x y 对列表表示