C++ 给定 n 个有序顶点的多边形的面积(Area of a polygon with given n ordered vertices)

C++ 给定 n 个有序顶点的多边形的面积(Area of a polygon with given n ordered vertices)

给定一个有 n 个顶点的多边形的有序坐标。求该多边形的面积。这里的有序是指坐标从第一个顶点到最后一个顶点按顺时针或逆时针排列。
示例: 

输入 :  X[] = {0, 4, 4, 0}, Y[] = {0, 0, 4, 4};
输出 : 16

输入 : X[] = {0, 4, 2}, Y[] = {0, 0, 4}
输出 : 8

我们可以使用鞋带公式计算多边形的面积。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

Area

[Tex]=\frac{1}{2}\left | \sum_{i=1}^{n-1}x_iy_(_i+_1_)+x_ny1-\sum_{i=1}^{n-1}x_(_i+_1_)y_i-x_1y_n \right |[/Tex]

= | 1/2 [ (x1y2 + x2y3 + ... + xn-1yn + xny1) - (x2y1 + x3y2 + ... + xnyn-1 + x1yn) ] |

上述公式是通过对顶点进行叉积来推导多边形中三角形面积的。 
以下是上述公式的具体实现。 

示例代码:

// C++ program to evaluate area of a polygon using
// shoelace formula
#include <bits/stdc++.h>
using namespace std;

// (X[i], Y[i]) are coordinates of i'th point.
double polygonArea(double X[], double Y[], int n)
{
    // Initialize area
    double area = 0.0;

    // Calculate value of shoelace formula
    int j = n - 1;
    for (int i = 0; i < n; i++)
    {
        area += (X[j] + X[i]) * (Y[j] - Y[i]);
        j = i;  // j is previous vertex to i
    }

    // Return absolute value
    return abs(area / 2.0);
}

// Driver program to test above function
int main()
{
    double X[] = {0, 2, 4};
    double Y[] = {1, 3, 7};

    int n = sizeof(X)/sizeof(X[0]);

    cout << polygonArea(X, Y, n);
}

输出 : 

2

时间复杂度: O(n) 

辅助空间: O(1),因为没有占用额外的空间。

为什么叫鞋带公式? 

这个公式的命名源于我们计算它的方式。 

例如: 

设输入顶点为
 (0, 1), (2, 3), and (4, 7). 

评估过程与系鞋带的过程相匹配。

我们将顶点写成如下所示
  0    1
  2    3
  4    7
  0    1  [写两次]

我们评估正项如下
  0  \  1
  2  \  3
  4  \  7
  0     1  
即, 0*3 + 2*7 + 4*1 = 18 

我们评估负项如下
  0     1
  2  /  3
  4  /  7
  0  /  1  
即, 0*7 + 4*3 + 2*1 = 14

面积 = 1/2 (18 - 14) = 2 

查看此页以获得更清晰的图像。

这是怎么回事? 
我们总是可以将一个多边形分成三角形。面积公式如下:取每条边 AB,计算顶点位于原点 O 的三角形 ABO 的面积(有符号),然后取叉积(得出平行四边形的面积)除以 2。绕多边形旋转时,这些面积为正负的三角形会重叠,原点和多边形之间的面积会被抵消,总和为 0,只剩下参考三角形内部的面积。[来源:维基百科

为了更好地理解,请看下图:

使用叉积计算三角形面积

将多边形划分为更小的三角形来计算面积

类似地,对于不规则多边形,我们可以形成三角形来计算面积

相关文章: 
最小成本多边形三角剖分, 
为给定的点集寻找简单闭合路径

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

Read more

C++:模板的幻觉 —— 实例化、重定义与隐藏依赖势中

C++:模板的幻觉 —— 实例化、重定义与隐藏依赖势中

一、表象之下:模板真的“生成代码”吗? 很多人第一次学 C++ 模板时,会这样理解: “模板是一种代码生成机制,编译器在编译时会根据不同类型生成不同版本的函数或类。” 乍一看没错,比如: template<typename T> void print(T x) { std::cout << x << std::endl; } int main() { print(42); print("Hello"); } 似乎编译器确实“生成了两份函数”: print<int>(int) 与 print<const

By Ne0inhk
【C++贪心】P8769 [蓝桥杯 2021 国 C] 巧克力|普及+

【C++贪心】P8769 [蓝桥杯 2021 国 C] 巧克力|普及+

本文涉及知识点 C++贪心 [蓝桥杯 2021 国 C] 巧克力 题目描述 小蓝很喜欢吃巧克力,他每天都要吃一块巧克力。 一天小蓝到超市想买一些巧克力。超市的货架上有很多种巧克力,每种巧克力有自己的价格、数量和剩余的保质期天数,小蓝只吃没过保质期的巧克力,请问小蓝最少花多少钱能买到让自己吃 x x x 天的巧克力。 输入格式 输入的第一行包含两个整数 x x x, n n n,分别表示需要吃巧克力的天数和巧克力的种类数。 接下来 n n n 行描述货架上的巧克力,其中第 i i i 行包含三个整数 a i a_i ai , b i b_i bi

By Ne0inhk

揭秘C++26新特性:CPU亲和性控制如何让多线程性能飙升(专家级指南)

第一章:C++26 CPU亲和性与性能优化概述 在高性能计算和实时系统开发中,CPU亲和性控制成为提升程序执行效率的关键技术之一。C++26标准正在积极引入对硬件资源调度的底层支持,允许开发者通过标准化接口绑定线程到特定CPU核心,从而减少上下文切换开销、提高缓存命中率,并优化多核并行任务的执行性能。 为何关注CPU亲和性 * 降低线程迁移带来的缓存失效问题 * 增强实时应用的可预测性与响应速度 * 配合NUMA架构实现内存访问局部性优化 标准库中的预期接口设计 虽然C++26尚未最终定稿,但委员会提案P2173R4建议引入std::execution_context与std::set_affinity等设施。未来可能的用法如下: #include <thread> #include <execution> int main() { std::jthread worker([](std::stop_token st) { // 将当前线程绑定到CPU核心0 std::set_affinity(std::this_thread::get_

By Ne0inhk
C++杂说——命名空间,输入与输出,缺省参数,make/makefile

C++杂说——命名空间,输入与输出,缺省参数,make/makefile

希望你开心,希望你健康,希望你幸福,希望你点赞! 最后的最后,关注喵,关注喵,关注喵,大大会看到更多有趣的博客哦!!! 喵喵喵,你对我真的很重要! 命名空间 命名空间编译默认查找顺序: a、当前局部域 : 自留地 b、全局域找 : 村子野地 c, 不会到其他命名空间中去找 : 隔壁张大爷自留地 命名空间展开三种 1、指定访问 2、全展开 //// 展开命名空间 //using namespace bit; //using namespace xjh; 3、指定展开某一个(经常使用,可以展开它一个) // 指定展开某一个 //using bit::x; 命名空间可以为: // 局部域 // 全局域 // 命名空间域 // 不同域可以定义同名的变量/函数/类型 两个私有的命名空间最好不要同时展开,

By Ne0inhk