caioj1213:【计算几何】面积

首先,欢迎大家来访问我老师的OJ:小白菜OJ

你是新入门OI的小白吗?
你正在苦于网上的资料不足吗?
你正在因各种blog写得不清不楚、艰涩难懂、千篇一律、满篇术语像LB一样而烦恼吗?
欢迎来到小白菜OJ!
这里有最易懂的视频讲解、基于HustOJ和阿里云的稳定、先进OJ
并且——完全免费!
小白菜OJ——信息学竞赛在线自学系统(caioj.cn)


专业黑LB

好了说正事:我们这篇blog来讲一讲如何用叉积求一个(非自相交)多边形的面积
题面传送门(需要注册账号)

首先,众所周知叉积的大小是两个向量围成的平行四边形的面积
那么,我们把这个大小除以二不就是两个向量围成的三角形的面积了吗?

好的那么我们会求三角形的面积了。
求多边形的面积(非自相交,无论凸凹)就可以转化为求几个三角形的面积。
具体如下:

我们有一个多边形:


这个11边形表现为一个点的数组 a a a,而 a 1 a_1 a1就是那个黑点
然后我们从第三个点开始,挨个求它与上一个点、 a 1 a_1 a1围成的三角形面积——也就是求叉积的一半——然后加起来。
注意!这里的面积其实不是指真正的面积,是要包括原来叉积的正负性的!
上图:

先加上 S △ A B C S_{\triangle ABC} SABC

再加上 S △ A C D S_{\triangle ACD} SACD


但是,此时,眼尖的同学可能会发现, F F F点上面有一片本来没有的区域被覆盖了!
没关系我们继续看:

加上 S △ A D E S_{\triangle ADE} SADE

更明显了呢……
但是!
接下来我们要减去 S △ A E F S_{\triangle AEF} SAEF
减去 S △ A E F S_{\triangle AEF} SAEF后……

(图中被框起的一部分被删去)
好像解决了呢!

再来:



最终结果就是所有有颜色的部分减去天蓝色圈起来的部分

自己理解一下就好……正确性不会证明了
三角形的面积用叉积来求
然而代码也不难
上代码:

#include<cstdio>
using namespace std;
struct point
{
	int x,y;
	point operator -(point b)
	{return (point){x-b.x,y-b.y};}
}a[1100];
int cp(point a,point b,point o)
{
	a=a-o;b=b-o;
	return a.x*b.y-b.x*a.y;
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&a[i].x,&a[i].y);
	int ans=0;
	for(int i=3;i<=n;i++)
		ans+=cp(a[i-1],a[i],a[1]);//核心代码
	printf(ans&1?"%d.5000":"%d.0000",ans>>1);//如果除以二有余数,就输出x.5000,不然就输出x.0000
	return 0;
}

然而,面对有自相交的情况时,这个东西就不管用了……
所以我有时间时再打一篇blog来探究这个问题(今天跟LZY奆佬讨论了一下发现不容易啊……)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值