凸包的定义,直观的来看就是,由平面上n个点组成的集合,其凸包就是包含这些点的最小凸多边形,凸多边形的任何一条边所在的直线把凸多边形全部划在了同一个半平面内。
性质:如果点集中两个点的连线属于凸多边形的边,当且仅当点集中其余的点都在这两个点连线的同一侧。利用这个性质,可以求解凸包问题。若已知由n个点构成集合的凸包是以其中某些点为顶点的凸多边形(这个凸多边形一定是最小凸多边形),且这些点具有凸包的性质,则它们之间的某些连线共同构成了凸包的全部边。
解题思路:利用数学中两点确定一条直线的方程枚举求解。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
struct Point
{
int x,y,flag;
};
struct Point point[100];
void random(int n)
{
srand(time(NULL));
for(int i=0;i<n;i++)
{
point[i].x=1+rand()%10;
point[i].y=1+rand()%10;
}
}
void ConvexHull(int n)
{
int sum=0;
int sign1,sign2;
int a,b,c;
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
{
a=
point[j].y-point[i].y;
b=point[j].x-point[i].x;
c=(point[i].x*point[j].y)-(point[i].y*point[j].x);
sign1=0;
sign2=0;
for(int k=0;k<n;k++)
{
if((k==j)||(k==i))continue;
if((a*point[k].x-b*point[k].y)==c)
{
++sign1;
++sign2;
}
if((a*point[k].x-b*point[k].y)>c)
++sign1;
if((a*point[k].x-b*point[k].y)<c)
++sign2;
}
if(sign1==(n-2)||sign2==(n-2))
{
point[i].flag=1;
point[j].flag=1;
}
}
printf("\n凸包的极点坐标为:\n");
for(int i=0;i<n;i++)
if(point[i].flag==1)
{ sum++;
printf("(%d,%d)\n",point[i].x,point[i].y);
}
printf("\n一共有%d个点为极点.\n",sum);
}
int main()
{
int n;
printf("请输入坐标个数n:\n");
scanf("%d",&n);
random(n);
printf("\n平面的%d个坐标为:\n",n);
for(int i=0;i<n;i++)
{
printf("(%d,%d)\n",point[i].x,point[i].y);
}
ConvexHull(n);
return 0;
}