nyist_1011 So Easy[II]
2016-07-05 10:05
281 查看
题目:输入一个点列,顺次连接成一个封闭多边形,计算多边形的面积
分析:方法一,计算面积可以考虑定积分的形式,定积分有正有负,顺次求和,重复部分相互抵消,最后剩下的总面积的绝对值就是多边形的面积。
从线性积分后的结果可以容易的看出,直线段的积分实际上就是求该直线段与x轴所围成的区域的梯形的面积Int(P1, P2) = Int(k*x + b, P1.x, P2.x) = 0.5 * (P2.x - P1.x) * (P2.y + P1.y), 斜率k = (P1.y - P2.y) / (P1.x - P2.x),截距b = P1.y - k*P1.x;
算法的复杂度为:O(N),N为顶点的个数。
[cpp]
struct Point {
float x, y;
};
float LinearIntegration(const Point &p1, const Point &p2) {
return 0.5 * (p2.x - p1.x) * (p2.y + p1.y);
}
float ComputePolygonArea(const Point points[], int length) {
if (points == NULL || length <= 0) return 0.0;
float area = 0.0;
for (int i = 0; i < length - 1; ++ i) {
area += LinearIntegration(points[i], points[i + 1]);
}
area += LinearIntegration(points[length - 1], points[0]);
return area >= 0.0 ? area : -area;
}
方法二,考虑到平面上知道三角形三个顶点的坐标可以运用行列式det直接求解三角形的面积。如P1(x1,y1),P2(x2,y2),P3(x3,y3),则
S(P1, P2, P3) = det[ x1 y1 1; x2 y2 1; x3 y3 1] * 0.5 = [(x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)] * 0.5;
可以在多边形的平面中任意的找到一个点,与多边形的每条边形成有向三角形,并顺次求取有向三角形的面积,再加和,因为是有向面积同上述定积分类似,面积有正有负可抵消重复部分,剩下的面积的绝对值即为多边形的面积。
[cpp]
struct Point {
float x, y;
Point() {x = 0.0; y = 0.0;}
Point(float _x, float _y) {x = _x; y = _y;}
};
float ComputeTriangleArea(const Point &p1, const Point &p2, const Point &p3) {
return 0.5 * ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y));
}
float ComputePolygonAreaTri(const Point points[], int length) {
if (points == NULL || length <= 0) return 0.0;
Point p0(0.0, 0.0);
float area = 0.0;
for (int i = 0; i < length - 1; ++ i) {
area += ComputeTriangleArea(p0, points[i], points[i + 1]);
}
area += ComputeTriangleArea(p0, points[length - 1], points[0]);
return area >= 0.0 ? area : -area;
}
分析:方法一,计算面积可以考虑定积分的形式,定积分有正有负,顺次求和,重复部分相互抵消,最后剩下的总面积的绝对值就是多边形的面积。
从线性积分后的结果可以容易的看出,直线段的积分实际上就是求该直线段与x轴所围成的区域的梯形的面积Int(P1, P2) = Int(k*x + b, P1.x, P2.x) = 0.5 * (P2.x - P1.x) * (P2.y + P1.y), 斜率k = (P1.y - P2.y) / (P1.x - P2.x),截距b = P1.y - k*P1.x;
算法的复杂度为:O(N),N为顶点的个数。
[cpp]
struct Point {
float x, y;
};
float LinearIntegration(const Point &p1, const Point &p2) {
return 0.5 * (p2.x - p1.x) * (p2.y + p1.y);
}
float ComputePolygonArea(const Point points[], int length) {
if (points == NULL || length <= 0) return 0.0;
float area = 0.0;
for (int i = 0; i < length - 1; ++ i) {
area += LinearIntegration(points[i], points[i + 1]);
}
area += LinearIntegration(points[length - 1], points[0]);
return area >= 0.0 ? area : -area;
}
方法二,考虑到平面上知道三角形三个顶点的坐标可以运用行列式det直接求解三角形的面积。如P1(x1,y1),P2(x2,y2),P3(x3,y3),则
S(P1, P2, P3) = det[ x1 y1 1; x2 y2 1; x3 y3 1] * 0.5 = [(x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)] * 0.5;
可以在多边形的平面中任意的找到一个点,与多边形的每条边形成有向三角形,并顺次求取有向三角形的面积,再加和,因为是有向面积同上述定积分类似,面积有正有负可抵消重复部分,剩下的面积的绝对值即为多边形的面积。
[cpp]
struct Point {
float x, y;
Point() {x = 0.0; y = 0.0;}
Point(float _x, float _y) {x = _x; y = _y;}
};
float ComputeTriangleArea(const Point &p1, const Point &p2, const Point &p3) {
return 0.5 * ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y));
}
float ComputePolygonAreaTri(const Point points[], int length) {
if (points == NULL || length <= 0) return 0.0;
Point p0(0.0, 0.0);
float area = 0.0;
for (int i = 0; i < length - 1; ++ i) {
area += ComputeTriangleArea(p0, points[i], points[i + 1]);
}
area += ComputeTriangleArea(p0, points[length - 1], points[0]);
return area >= 0.0 ? area : -area;
}
相关文章推荐
- 解决问题的步骤
- 分治策略
- Java环境jdk安装
- PostgreSQL远程连接配置
- Java lambda 以及 Lambda在集合中的使用
- Jtest工具介绍及使用案例
- 在必须创建Activity的情况下又如何让Activity不显示
- 清理iOS工程里无用的图片,可瘦身ipa
- Spring定时任务,Spring4整合quartz2.2,quartz-scheduler定时任务
- javascript:console.log()是什么js库里的?
- C程序之修改Windows的控制台颜色(转载)
- poj 2186 Popular Cows
- 2016.7.5 安防界面layout的相关问题
- Python3 学习手册(二) 流程控制语句
- sql server 2008 代理服务提供的凭据无效
- 滚动选择WheelView
- C#信号量用法简单示例
- Camera的前后摄像头调换
- Android 设计模式 笔记 - 深入了解WindowManager
- Nescafé2 月之谜 题解