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

  • Post author:
  • Post category:其他


全篇基于平面多边形

先看

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



版权声明:本文为qiushangren原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。