已知四边形四个点坐标 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判断一次。
思路:知道公式后,直接代入即可,因为没说明n的大小,我直接暴力了,结果过了
#include
#include
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;
}