• 79-多边形的面积-计算几何


    http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=3

                          多边形重心问题

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:5
     
    描述
    在某个多边形上,取n个点,这n个点顺序给出,按照给出顺序将相邻的点用直线连接, (第一个和最后一个连接),所有线段不和其他线段相交,但是可以重合,可得到一个多边形或一条线段或一个多边形和一个线段的连接后的图形; 
    如果是一条线段,我们定义面积为0,重心坐标为(0,0).现在求给出的点集组成的图形的面积和重心横纵坐标的和;
     
    输入
    第一行有一个整数0<n<11,表示有n组数据;
    每组数据第一行有一个整数m<10000,表示有这个多边形有m个顶点;
    输出
    输出每个多边形的面积、重心横纵坐标的和,小数点后保留三位;
    样例输入
    3
    3
    0 1
    0 2
    0 3
    3
    1 1
    0 0
    0 1
    4
    1 1
    0 0
    0 0.5
    0 1
    样例输出
    0.000 0.000
    0.500 1.000
    0.500 1.000

    思路:

    首先得知道两个定理。

    已知三角形各顶点A(Xi,Yi)( i=1,2,3)
    S=((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1));
    重心坐标(Xg,Yg)为
    Xg=(x1+x2+x3)/3;
    Yg=(y1+y2+y3)/3;
    有两种方法,我用的第二种。

    算法一:一般适合凸多边形
          n边多边形可以分成n-2个三角形,将这些三角形看做质点(质点的位置是三角形的重心x1,x2,..,质量是面积s1,s2,..),
          那么多边形就由这些质点组成,质点坐标以其质量为权的加权算术平均数即是多边形重心坐标x。

    x=(x1*s1+x2*s2+...)/(s1+s2+...)
    y=(y1*s1+y2*s2+...)/(s1+s2+...)
    s=s1+s2+...

    算法二:任意多边形


           将算法一改进,n边多边形中每两个点(有顺序)加上原点可构成n个三角形,
           将这些三角形看做质点(质点的位置是三角形的重心x1,x2...,质量是面积(有正负)s1,s2,...),
           那么多边形就由这些质点组成,质点坐标以其质量为权的加权算术平均数即是多边形重心坐标x。
           多边形的面积s是这n个三角形面积(有正负)的代数和的绝对值。

    x=(x1*s1+x2*s2+...)/(s1+s2+...)
    x=(x1*s1+x2*s2+...)/(s1+s2+...)
    s=|s1+s2+...|

    #include <iostream>
    #include <cmath>
    #include <cstdio> 
    using namespace std;
    
    int main(){
    	int t, n;
    	double sumx, sumy, area, x[3], y[3];
    	cin >> t;
    	while(t--){
    		sumx = sumy = area = 0;
    		cin >> n;
    		cin >> x[0] >> y[0] >> x[1] >> y[1];
    		n -= 2;
    		while(n--){
    			cin >> x[2] >> y[2]; //从第三个顶点开始读入并计算 
    			//新三角形面积 
    			double s = (x[1] - x[0]) * (y[2] - y[0]) - (x[2] - x[0]) * (y[1] - y[0]);
    			s /= 2;
    			sumx += s * (x[0] + x[1] + x[2]) / 3; //每个小三角形的重心坐标乘以权重(面积) 
    			sumy += s * (y[0] + y[1] + y[2]) / 3;
    			//总面积 
    			area += s;
    			x[1] = x[2], y[1] = y[2];
    		}
    		double ans;	
    		if(area == 0)
    			sumx = 0, sumy = 0, ans = 0;
    		else
    			ans = (sumx + sumy) / area;
    		printf("%.3lf %.3lf
    ", fabs(area), ans);
    	}
    	return 0;
    } 
    

      

  • 相关阅读:
    Unix/Linux环境C编程入门教程(32) 环境变量那些事儿
    Unix/Linux环境C编程入门教程(34) 编程管理系统中的用户
    Unix/Linux环境C编程入门教程(30) 字符串操作那些事儿
    Unix/Linux环境C编程入门教程(29) 内存操作那些事儿
    Unix/Linux环境C编程入门教程(28) 日期时间那些事儿
    Unix/Linux环境C编程入门教程(27) 内存那些事儿
    模板函数冲突
    C语言的本质(30)——C语言与汇编之ELF文件格式
    C语言的本质(29)——C语言与汇编之寄存器和寻址方式
    DG观察日志传输
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/9527454.html
Copyright © 2020-2023  润新知