计算给定坐标系和各个定点坐标的凸多边形的面积

时间限制 1000 ms 内存限制 65536 KB

题目描述

Little smart QiQi is fond of coin tossing. This day, he came to a huge field, where there's a irregular convex swamp within. Little smart QiQi didn’t want to toss the coin into the swamp, and thus, she needed to know the area of this convex. Please help her.

输入格式

The input contains several test cases, ended with EOF. In each test case, an integer N(3≤N≤100) exists first, indicating the number of vertex. The following N lines give the coordinates(x,y) of each vertex.(106x,y106), x and y are real numbers.

输出格式

Output the area of each convex. The answer should be corrected to 1 decimal places.
 

输入样例

3
-1 0
0 1
1 1

输出样例

0.5

思路:计算多边形最低点 -》 将多边形移动到最低点刚好为原点 -》 计算各个顶点和原点连线的cos值,最低点赋特殊值(10)-》所有顶点按照cos值排序
-》依次计算相临两点与最低点形成的三角形的面积(公式:s = 1/2*跟号下(p(p-a)(p-b)(p-c))(其中:abc是三角形三条边))-》 将所有的这样的三
角形面积相加即得到凸多边形的面积

 

#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
#include <stdlib.h>
using namespace std;

struct node {
    double x;
    double y;
    double cos;
};
//移动多边形
void move(vector<node> &org)
{
    double xx = org[0].x;
    double yy = org[0].y;
    for (int i = 0; i < org.size(); ++i) {
        if (org[i].y < yy) {
            yy = org[i].y;
            xx = org[i].x;
        }
    }
    for (int j = 0; j < org.size(); ++j) {
        org[j].x -= xx;
        org[j].y -= yy;
    }
    cout << "move up " << endl;
    for (int j = 0; j < org.size(); ++j) {
        cout << org[j].x << " " << org[j].y << endl;
    }
}
//排序比较规则
bool comp(const node &s1, const node &s2)
{
    return s1.cos < s2.cos;
}
void countCosAndSort(vector<node> &org)
{
    for (int i = 0; i < org.size(); ++i) {
        if ((org[i].y < 0.000001 || org[i].y > -0.000001) &&
             (org[i].x < 0.000001 || org[i].x > -0.000001)) {
            org[i].cos = 10;
            continue;
        }
        double d = sqrt(org[i].x * org[i].x + org[i].y * org[i].y);
        org[i].cos = org[i].x / d;
    }
    sort(org.begin(), org.end(), comp);
    cout << "after sort" << endl;
    for (int i = 0; i < org.size(); ++i) {
        cout << org[i].x << " " << org[i].y << endl;
    }
}
//计算单个三角形面积
double singleArea(node &n1, node &n2)
{
    double len1, len2, len3;
    len1 = sqrt(n1.x * n1.x + n1.y * n1.y);
    len2 = sqrt(n2.x * n2.x + n2.y * n2.y);
    len3 = sqrt((n2.x-n1.x)*(n2.x-n1.x) + (n2.y-n1.y)*(n2.y-n1.y));
    double p = (len1+len2+len3)/2;
    double s = sqrt(p*(p-len1)*(p-len2)*(p-len3));
    return s;
}

//计算多边形面积
double sunArea(vector<node> &org)
{
    move(org);
    countCosAndSort(org);
    double sumA = 0;
    for (int i = 0; i < org.size()-1; ++i) {
        sumA += singleArea(org[i], org[i+1]);
    }
    return sumA;
}

int main()
{
    int t;
    cin >> t;
    vector<node> data;
    node tmp;
    double xx, yy;
    for (int i = 0; i < t; ++i) {
        cin >> xx >> yy;
        tmp.x = xx;
        tmp.y = yy;
        data.push_back(tmp);
    }
    cout << sunArea(data) << endl;

    return 0;
}

转载于:https://www.cnblogs.com/candycloud/p/3591818.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值