從相反的法線方向觀察,順時針還是逆時針是相反的。
多邊形的時針方向與法線方向的關系呈右手法則關系。
GoogleEarth中的面具有時針方向,法線方向為正向,反之為負向
GoogleEarth的垂面在法線方向為亮色,反向為暗色
GoogleEarth的水平面或斜面無論法線指向天空還是地面,背離地面的一側總是亮色。
要保證多邊形的各側向垂面的法線總是朝外(保持外側面為亮面),若該多邊形為順時針,則各垂面邊框按從高點起始,先畫水平線到下點,再畫垂線到低點,最后回到高點的方法。反之,若該多邊形為逆時針,則各垂面邊框應從高點開始,先畫垂線到低點,再畫水平線到下點,最后回到高點的方法。
換句話說,假設各垂面都從高點開始畫,如果多邊形是順時針的,則先畫水平線;如果多邊形是逆時針的,則先畫垂直線。歸納為 “順高水,逆高垂”。
?
凸多邊形只有具有一個時針方向,但凹多邊形的凸邊和凹邊時針方向不相同。一個多邊形無論凹凸,判斷每相鄰兩邊的時針方向更有意義。由3點構成的兩邊,計算這3點的卷積(CorssProduct),卷積為正是逆時針,卷積為負是順時針。
卷積=(ΔXi,ΔYi)×(ΔXi+1,ΔYi+1),即 cp=(xi-xi-1)×(yi+1-yi)-(yi-yi-1)×(xi+1-xi), 若cp>0,該點為逆時針點。反之為順時針點。
同時,如果一個多邊形是凸多邊形,那么,它每個頂點的卷積都為正或都為負。凹多邊形的所有頂點的卷積有的為正有的為負。
此外,如果多邊形存在重合的兩點,或連續3點在一條直線上,那么,卷積=0,沒有時針方向,也不區分凹凸。
?
代碼示例1:判斷一個多邊形是順時針還是逆時針
/*
?? Return the clockwise status of a curve, clockwise or counterclockwise
?? n vertices making up curve p
?? return 0 for incomputables eg: colinear points
????????? CLOCKWISE == 1
????????? COUNTERCLOCKWISE == -1
?? It is assumed that
?? - the polygon is closed
?? - the last point is not repeated.
?? - the polygon is simple (does not intersect itself or have holes)
*/
int ClockWise(XY *p,int n)
{
?? int i,j,k;
?? int count = 0;
?? double z;
?
?? if (n < 3)
????? return(0);
?
?? for (i=0;i<n;i++) {
????? j = (i + 1) % n;
????? k = (i + 2) % n;
????? z? = (p[j].x - p[i].x) * (p[k].y - p[j].y);
????? z -= (p[j].y - p[i].y) * (p[k].x - p[j].x);
????? if (z < 0)
???????? count--;
????? else if (z > 0)
???????? count++;
?? }
?? if (count > 0)
????? return(COUNTERCLOCKWISE);
?? else if (count < 0)
????? return(CLOCKWISE);
?? else
????? return(0);
}
?
代碼示例2:判斷一個多邊形是凸多邊形還是凹多邊形
?? Return whether a polygon in 2D is concave or convex
?? return 0 for incomputables eg: colinear points
????????? CONVEX == 1
????????? CONCAVE == -1
?? It is assumed that the polygon is simple
?? (does not intersect itself or have holes)
*/
int Convex(XY *p,int n)
{
?? int i,j,k;
?? int flag = 0;
?? double z;
?
?? if (n < 3)
????? return(0);
?
?? for (i=0;i<n;i++) {
????? j = (i + 1) % n;
????? k = (i + 2) % n;
????? z? = (p[j].x - p[i].x) * (p[k].y - p[j].y);
????? z -= (p[j].y - p[i].y) * (p[k].x - p[j].x);
????? if (z < 0)
???????? flag |= 1;
????? else if (z > 0)
???????? flag |= 2;
????? if (flag == 3)
???????? return(CONCAVE);
?? }
?? if (flag != 0)
????? return(CONVEX);
?? else
????? return(0);
}
?