向量 求 面积 calcAreaOfPolygon2D 凹凸多边形 顺时针 逆时针

全篇基于平面多边形
先看http://www.cnblogs.com/TenosDoIt/p/4047211.html
本文主要目的是说明 多边形 顶点 的 顺时针逆时针 方向 对求面积的 便利性。
二维向量叉乘,得到的新的向量是长度为原来两向量的组成的平行四边形的面积,方向为右手法则确定出来的方向。需要用三维中的行列式来求证二维向量如下:

(可设j为(0,0,1),由a,b求出来的向量为(0,0,x1*y2-x2*y1))

也就是说二维平面上,已知两点A(x1,y1)和B(x2,y2),与原点O组成的三角形面积为  |x1*y2-x2*y1|/2 。


(叉乘不同于点乘,点乘公式为a•b = |a||b|cosθ ,点乘的结果是一个标量,等于向量大小与夹角的cos值的乘积。设a为(x1,y1,z1) ,b 为(x2,y2,z2), 则a*b = x1*x2+y1*y2+z1*z2)

 

从上面的公式可以发现,向量乘积的前后顺序是z值的。向量法求平面多边形面积 与 取点的方向有关系。如果是顺时针方向,求取的面积(多边形 每条边的顶点与原点组成向量的叉积的z值 的和)值是负的,如果是逆时针方向,求取的面积值是正的。一种理解就是根据向量叉积的“右手法则”,顺时针z是向下的,逆时针z是向上的,多多边形顺时针方向取点或逆时针取点决定了累积起来的z的总的方向。注意这个规律与取的参考点(O点)是没有关系的,即使取多边形内部的点或者取多边形线上的点,都满足这个规律。可以参看下面的例子,然后自行扩展。
  (为了方便计算多边形选用直角三角形)

假设向量为(x,y,z)  A(3,6,0) B(3,2,0) C(7,3,0)  O(0,0,0) 三角形面积为4*4/2 =  8
再结合博客链接中的知识:逆时针取多边行顶点 ((OAxOB).z+(OBxOC).z+(OCxOA).z)/2 = ((3*2-6*3)+(3*3-2*7)+(7*6-3*3))/2 = 8 ,等于多边形ABC的面积;而顺时针取多边形顶点((OBxOA).z+(OAxOC).z+(OCxOB).z)/2 = ((6*3-3*2)+(2*7-3*3)+(3*3-7*6))/2 = -8 等于多变形ABC面积的负值。可以用递归法推测正确性。往多边行扩展,因为可以将多边形拆分成多个三角形,辅助的边的叉积的z值项 在最后在总的求和时 是都会被相互抵消的。实际最终的有效的求和累积项 都是 实边的顶点 与 原点 组成向量的叉乘 z值的累加。

向量法求面积可以无差错的拓展到凹多边形。

static int calcAreaOfPolygon2D(const int* verts, const int nverts)//来自于recast,注意这里是int类型,代码是特殊用途,主要用作参考
{
	int area = 0;
	for (int i = 0, j = nverts-1; i < nverts; j=i++)
	{
		const int* vi = &verts[i*4];
		const int* vj = &verts[j*4];
		area += vi[0] * vj[2] - vj[0] * vi[2];
	}
	return (area+1) / 2;
}


另外面积法判断点是否在多边形内,只对凸多边形有效,并且还必须对上面的z值 取绝对值 才能让结果有效。

 

点在多边形内,最好的办法有两个:
1、判断合适的过点的射线与多边形的交点个数,这个链接讲解比较容易理解且最高效简洁。
2、边与点的夹角和。
可参考https://blog.csdn.net/gkingzheng/article/details/81836308

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值