多边形面积(Area_Of_Polygons)

本文介绍了一种利用向量和前缀和快速计算任意多边形面积的方法,通过实例演示了如何使用C++代码实现该算法,并讨论了在计算几何题目中的应用。

原理:

任意多边形的面积可由任意一点与多边形上依次两点连线构成的三角形矢量面积求和得出。

分析: 
由于给出的点是相对于我们的坐标原点的坐标,每个点实际上我们可以当作一个顶点相对于原点的向量,如下图所示: 


 
P(0,0)对应的顶点向量分别为:A(x0,y0),B(x1,y1),…,G(x6,y6) 
另外,△PAB△PAB的矢量面积即为


且多边形面积为:


根据上述公式可以直接求出多边形的代码从而避免了边长的复杂计算。

 例题:

https://ac.nowcoder.com/acm/contest/328/F

 

题解:计算几何裸题

 

#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,q;
double ans;
struct node{
    double x,y;
 
 
}e[N];
double a[N];
char str;
int main()
{
#ifdef DEBUG
    freopen("input.in", "r", stdin);
    //freopen("output.out", "w", stdout);
#endif
    scanf("%d%d",&n,&q);
    if(n==3){
        printf("%.6f",ans);
        return 0;
    }
    for(int i=1;i<=n;i++){
        scanf("%lf%lf",&e[i].x,&e[i].y);
    }
    for(int i=1;i<=n;i++){
        if(n==1)
        a[i]=a[i-1]+e[i].y*e[n].x-e[i].x*e[n].y;
        else
        a[i]=a[i-1]+e[i].y*e[i-1].x-e[i].x*e[i-1].y;
    }
    double sum=fabs(a[n]/2);
    //cout<<sum<<endl;
    int s,t;
    while(q--){
        scanf("%d%d",&s,&t);
 
        if(s>t)
            swap(s,t);
        if(abs(s-t)==1||s==1&&t==n)
            continue;
        double sumtmp=fabs((a[t]-a[s]+e[s].y*e[t].x-e[s].x*e[t].y)/2);
        ans=max(ans,min(sumtmp,sum-sumtmp));
    }
    printf("%.6f",ans);
    //cout << "Hello world!" << endl;
    return 0;
}
View Code

 

C++版本二

题解:

计算几何
只要叉积维护一下前缀和就好了。

 

#include <cstdio>
#include <bits/stdc++.h>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)
 
typedef long long ll;
const int maxn = 200005;
const ll INF = 1e18;
const ll mod=1e9+7;
const double eps = 1e-9;
 
int n,m;
 
struct node
{
    double x,y;
}a[maxn];
 
double sum[maxn];
 
double cross(node a,node b,node c)
{
    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
 
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf",&a[i].x,&a[i].y);
    }
    node zero;
    zero.x=0;
    zero.y=0;
    for(int i=1;i<=n;i++)
    {
        double ans=cross(zero,a[i],a[(i==n?1:i+1)]);
        sum[i]=sum[i-1]+ans;
    }
    for(int i=n+1;i<=2*n;i++)
    {
        sum[i]=sum[i-1]+sum[i-n];
    }
    double Sum=fabs(sum[n])/2.0;
    double cnt=0;
    for(int i=0;i<m;i++)
    {
        int ss,tt;
        scanf("%d%d",&ss,&tt);
        if(ss>tt) swap(ss,tt);
        double ans=sum[tt-1]-sum[ss-1];
        ans+=cross(zero,a[tt],a[ss]);
        ans=fabs(ans)/2.0;
        cnt=max(cnt,min(ans,Sum-ans));
    }
    printf("%.15f\n",cnt);
}
View Code

 

转载于:https://www.cnblogs.com/DWVictor/p/10278635.html

请给出下述python代码对应的伪代码:”import cv2 import numpy as np import random def generate_random_polygon(img_shape, max_points=20, area_num=4): """ 生成单个随机多边形(改进版) :param img_shape: 图像尺寸 (h, w, c) :param max_points: 顶点数量区间上限 :param area_num: 控制多边形大小(数值越大面积越小,建议范围2-8) :return: 按顺时针排序的顶点坐标数组 """ h, w = img_shape[:2] num_points = random.randint(3, max_points) # 根据area_num调整分布范围 sigma_w = w // max(1, area_num) # 防止除零错误 sigma_h = h // max(1, area_num) points = [] for _ in range(num_points): # 调整正态分布参数控制集中度 cx = random.gauss(w // 2, sigma_w) cy = random.gauss(h // 2, sigma_h) x = np.clip(int(cx), 0, random.randint(w-1,w+5)) y = np.clip(int(cy), 0, random.randint(w-1,w+5)) points.append((x, y)) hull = cv2.convexHull(np.array(points)) return hull + np.random.randint(-60, 60, size=hull.shape) def create_multi_mask(img, polygons): """原有函数保持不变""" mask = np.zeros_like(img) for poly in polygons: cv2.fillPoly(mask, [poly], (255, 255, 255), lineType=cv2.LINE_AA) return mask # 新增参数配置 num_c = 5 max_points = 12 area_num = 96 # ★新增的控制参数(典型值2-8,数值越大多边形越小) # 读取图像 img = cv2.imread(r'binary_image.jpg') if img is None: raise FileNotFoundError("图像未找到,请检查路径") # ★在生成时传递area_num参数 polygons = [generate_random_polygon(img.shape, max_points, area_num) for _ in range(num_c)] mask = create_multi_mask(img, polygons) cv2.imshow('Multi Polygon Mask', mask) cv2.imwrite('multi_mask.png', mask) cv2.waitKey(0) cv2.destroyAllWindows()
最新发布
03-10
在下述代码的基础上添加控制多边形大小的名为area_num参数:import cv2 import numpy as np import random def generate_random_polygon(img_shape, max_points=20): """ 生成单个随机多边形(改进版) :param img_shape: 图像尺寸 (h, w, c) :param max_points: 顶点数量区间上限 :return: 按顺时针排序的顶点坐标数组 """ h, w = img_shape[:2] num_points = random.randint(3, max_points) # 动态顶点数量 # 生成带权重分布的随机点 points = [] for _ in range(num_points): # 使用正态分布控制区域集中度(μ=中心, σ=1/4图像尺寸) cx = random.gauss(w // 2, w // 4) cy = random.gauss(h // 2, h // 4) x = np.clip(int(cx), 0, w - 1) y = np.clip(int(cy), 0, h - 1) points.append((x, y)) # 凸包处理+随机扰动 hull = cv2.convexHull(np.array(points)) return hull + np.random.randint(-10, 10, size=hull.shape) # 添加位置扰动 def create_multi_mask(img, polygons): """ 创建复合掩码 :param img: 原始图像 :param polygons: 多边形列表 :return: 叠加后的二值掩码 """ mask = np.zeros_like(img) # 使用抗锯齿填充 for poly in polygons: cv2.fillPoly(mask, [poly], (255, 255, 255), lineType=cv2.LINE_AA) return mask # 参数配置 num_c = 11 # 生成多边形数量 max_points = 5 # 单多边形最大顶点数 # 读取图像 img = cv2.imread(r'binary_image.jpg') if img is None: raise FileNotFoundError("图像未找到,请检查路径") # 生成多个多边形 polygons = [generate_random_polygon(img.shape, max_points) for _ in range(num_c)] # 创建复合掩码 mask = create_multi_mask(img, polygons) # 显示并保存结果 cv2.imshow('Multi Polygon Mask', mask) cv2.imwrite('multi_mask.png', mask) cv2.waitKey(0) cv2.destroyAllWindows()
03-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值