多边形坐标点记录是顺时针还是逆时针的判断
参考链接:http://hi.baidu.com/op_kaixinguo/item/e5c9ed3c9a8adb079dc65ee5
工作中遇到了之前在尝试针对一个多边形拆分成多个三角形以供三维显示的问题,最后渲染不出来,发现时三角形方向相反,导致背面画布上去。因此从网上找了些相关资料,判断一个多边形描述顶点是顺时针还是逆时针的方法。简单描述如下:
极值计算法——因为多边形中任意三个相邻顶点所构成的顺序和整体多边形相同,所以在构成多边形的顶点中,我们选择最右边(最上,最左,最下都可)的顶点P1,然后取与其相临的两个顶点(P2,P3),由着三个点来做判断。
具体方法,我们参照三维中向量叉积的说明,两个向量叉积,可以获得其法线的方向。那么通过简单的坐标计算可以获得由三个点构成的向量。
V1=P1-P2;
V2=p3-p1;
VResult = V1*V2。因为我们是在二维抽象出来的三维向量,所以V1,V2的z值都为0,因此Vresult指向的方向,机其Z值的正负便可用来做顺时针,逆时针的判断标准。
实现理论描述到此,下面给出一个AS编写的判断方法:参数是指定的多边形的顶点,这里因为多边形在一个平面上,所以传入三维点的z值都为0.
private function convertClockwise(points:Vector.<Vector3D>):void
{
//点首尾重叠,总数大于4才说明有面(说明下:小弟这里使用的数据定义中多边形首位是同一个点,即三角形需要四个点定义,四边形需要5个点定义等等,,,飞这种情况的大家自己修改下就OK了)
if(points && points.length >= 4)
{
//找到最大点的索引
var maxNum:Number = Number.NEGATIVE_INFINITY;
var maxIndex:int = -1;
for(var i:int = 0; i < points.length; i++)
{
if(points[i].x > maxNum)
{
maxNum = points[i].x;
maxIndex = i;
}
}
if(maxIndex == -1)
{
return;
}
//根据最大 X 前后两点与最大点构成的面积是正还是负来判断点的方向
var maxPoint:Vector3D = points[maxIndex];
var prePoint:Vector3D;
var nextPoint:Vector3D;
for(var j:int = maxIndex - 1; j != maxIndex; j--)
{
//逆序找前一个点
if(j == -1) j = points.length - 1;
if(points[j].x != maxPoint.x)
{
prePoint = points[j];
break;
}
else
{
maxIndex--;
maxPoint = points[j];
}
}
if(maxIndex == points.length - 1)
{
nextPoint = points[0];
}
else
{
nextPoint = points[maxIndex + 1];
}
if(null == prePoint || prePoint == nextPoint)
{
return;
}
//计算面积,叉积
var vector1:Vector3D = prePoint.subtract(maxPoint);
var vector2:Vector3D = maxPoint.subtract(nextPoint);
vector1.z = 0;
vector2.z = 0;
// vector1.normalize();
// vector2.normalize();
var sub:Vector3D = vector1.crossProduct(vector2);
if(sub.z > 0)
{
points.reverse();
}
}
}