如何判断凸边形或者凹变形

已知四边形四个点坐标 p1 = (x,y), p2 = (x,y), p3 = (x,y), p4 = (x,y) 
判断凹凸性及凹点位置 
  
t1 = (p4.x-p1.x)(p2.y-p1.y)-(p4.y-p1.y)(p2.x-p1.x) 
t2 = (p1.x-p2.x)(p3.y-p2.y)-(p1.y-p2.y)(p3.x-p2.x) 
t3 = (p2.x-p3.x)(p4.y-p3.y)-(p2.y-p3.y)(p4.x-p3.x) 
t4 = (p3.x-p4.x)(p1.y-p4.y)-(p3.y-p4.y)(p1.x-p4.x) 
 if t1*t2*t3*t4 < 0: 
 return Concavequadrilateral(凹四边形) 
 if t1*t2*t3*t4 > 0: 
 return Convexquadrilateral(凸四边形)

 if t1*t2 < 0 and t1*t4 < 0: 
 return t1 
 if t1*t2 < 0 and t2*t3 < 0: 
 return t2 
 if t2*t3 < 0 and t3*t4 < 0: 
 return t3 
 if t3*t4 < 0 and t4*t1 < 0: 
 return t4 
数学原理: 
按照输入顺序依次将点连接起来 
对于连续的三个点p0,p1,p2,另向量a=p1-p0,b=p2-p1 
若是凸多边形,那么b相对于a一定是向逆时针方向旋转的 
判断两向量的旋转方向,可以使用向量的叉积 a×b = x1×y2 - x2×y1 
a×b > 0 b在a的逆时针方向 
a×b = 0 b平行于a(共线) 
a×b < 0 b在a的顺时针方向 
要注意的是,对于最后一个点pn,还要和起始的两个点p0,p1判断一次。


Shape of HDU

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


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

思路:知道公式后,直接代入即可,因为没说明n的大小,我直接暴力了,结果过了

#include<stdio.h>  
#include<string.h>  
struct m{
	int x;
	int y;
}p[100]; 
bool solve(m p1,m p2,m p3, m p4) {
	int t1,t2,t3,t4;
	t1 = (p4.x-p1.x)*(p2.y-p1.y)-(p4.y-p1.y)*(p2.x-p1.x); 
	t2 = (p1.x-p2.x)*(p3.y-p2.y)-(p1.y-p2.y)*(p3.x-p2.x); 
	t3 = (p2.x-p3.x)*(p4.y-p3.y)-(p2.y-p3.y)*(p4.x-p3.x); 
	t4 = (p3.x-p4.x)*(p1.y-p4.y)-(p3.y-p4.y)*(p1.x-p4.x);
	if (t1*t2*t3*t4 > 0) {
		return true;	
	}else {
		return false;
	} 
	 
}
int main(){  
    int n,sum;  
	//freopen("main.txt", "r", stdin);
    while(~scanf("%d",&n), n != 0){ 
	   bool check = false; 
     	for(int i = 0; i < n; i++) {
     		scanf("%d%d", &p[i].x, &p[i].y);
		 }
		 for(int i = 0; i < n; i++) {
		 	for(int j = i+1; j < n; j++) {
		 		for(int k = j+1; k < n; k++) {
		 			for(int f = k+1; f < n; f++) {
		 				if(!solve(p[i],p[j],p[k],p[f])) {
		 					check = true;
		 					break;
						 }
					 }
					 if(check) {
					 	break;
					 }
				 }
				 if(check) {
				 	break;
				 }
			 }
			 if(check) {
			 	break;
			 }
		 }
		 
		 if(check) {
		 		printf("concave\n");
		 }else {
		 
		 	printf("convex\n");
		 }
    }  
    return 0;  
}  






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值