叉积运用-判断凸多边形

Shape of HDU

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4643    Accepted Submission(s): 2080


Problem Description
话说上回讲到海东集团推选老总的事情,最终的结果是XHD以微弱优势当选,从此以后,“徐队”的称呼逐渐被“徐总”所取代,海东集团(HDU)也算是名副其实了。
创业是需要地盘的,HDU向钱江肉丝高新技术开发区申请一块用地,很快得到了批复,据说这是因为他们公司研发的“海东牌”老鼠药科技含量很高,预期将占全球一半以上的市场。政府划拨的这块用地是一个多边形,为了描述它,我们用逆时针方向的顶点序列来表示,我们很想了解这块地的基本情况,现在请你编程判断HDU的用地是凸多边形还是凹多边形呢?
 

 

Input
输入包含多组测试数据,每组数据占2行,首先一行是一个整数n,表示多边形顶点的个数,然后一行是2×n个整数,表示逆时针顺序的n个顶点的坐标(xi,yi),n为0的时候结束输入。
 

 

Output
对于每个测试实例,如果地块的形状为凸多边形,请输出“convex”,否则输出”concave”,每个实例的输出占一行。
 

 

Sample Input
4 0 0 1 0 1 1 0 1 0
 

 

Sample Output
convex

 

题意很简单,就是判断是凸多边形还是凹多边形。

这里用到了向量的叉积,这一块的内容基本还给老师的。。。。

再次复习下:

向量的数量积(内积,点积)
               
       
向量的向量积(外积,叉积) ,符合右手规则。
       

向量积是一个伪向量,定义其方向垂直于进行叉积的两个向量且满足右手规则。

向量叉积的几何意义
  计算矢量叉积是与直线和线段相关算法的核心部分。
1.向量的叉积的模表示这两个向量围成的平行四边形的面积。
    设矢量P = ( x1, y1 ),Q = ( x2, y2 ),

  则矢量叉积定义为由(0,0)、p1、p2和p1+p2所组成的平行四边形的带符号的面积,即:P×Q = x1*y2 – x2*y1,其结果是一个伪矢量。
  

  显然有性质 P × Q = – ( Q × P ) 和 P × ( – Q ) = – ( P × Q )。
2.叉积的一个非常重要性质是可以通过它的符号判断两矢量相互之间的顺逆时针关系:


    若 P × Q > 0 , 则P在Q的顺时针方向

  若 P × Q < 0 , 则P在Q的逆时针方向

  若  P × Q = 0 , 则P与Q共线,但可能同向也可能反向


   叉积的方向与进行叉积的两个向量都垂直,所以叉积向量即为这两个向量构成平面的法向量。
3.如果向量叉积为零向量,那么这两个向量是平行关系。
4.因为向量叉积是这两个向量平面的法向量,如果两个向量平行无法形成一个平面,其对应也没有平面法向量。所以,两个向量平行时,其向量叉积为零。

 

AC代码(摘自CSDN)

 1 #include<stdio.h>  
 2 #include<stdlib.h>  
 3   
 4 struct xy  
 5 {  
 6     int x;  
 7     int y;  
 8 }d[1000];  
 9   
10 int g(int a,int b,int c)  
11 {  
12     int t;  
13     //公式:s=(x1-x3)*(y2-y3)-(x2-x3)*(y1-y3)  
14     //当s>0时,p1,p2,p3三个点呈逆时针  
15     //当s<0时,p1,p2,p3三个点呈顺时针  
16     t=(d[a].x-d[c].x)*(d[b].y-d[c].y)-(d[b].x-d[c].x)*(d[a].y-d[c].y);  
17     return t;  
18 }  
19   
20 int main()  
21 {  
22     int i,t,n;  
23     while(scanf("%d",&n),n)  
24     {  
25         for(i=0;i<n;i++)  
26         {  
27             scanf("%d %d",&d[i].x,&d[i].y);  
28         }  
29         for(i=0;i<n;i++)  
30         {  
31             //模n是因为当i=n-1的时候n+1,n+2会超出数据范围,所以从头开始为最后一个点和第一二个点判断直线的走向  
32             t=g(i%n,(i+1)%n,(i+2)%n);  
33             if(t<0)break;  
34         }  
35             if(t>=0)  
36                 printf("convex\n");  
37             else  
38                 printf("concave\n");  
39     }  
40     return 0;  
41 } 

 

 

posted @ 2013-12-05 00:31  Jeremy Wu  阅读(4457)  评论(0编辑  收藏  举报