三、计算几何
1.叉乘法求任意多边形面积
语法:
result=polygonarea(Point *polygon,int N);
参数:
*polygon:多变形顶点数组
N:多边形顶点数目
返回值:
多边形面积
注意:
支持任意多边形,凹、凸皆可
多边形顶点输入时按顺时针顺序排列
源程序:
typedef struct {
double x,y;
} Point;
double polygonarea(Point *polygon,int N)
{
int i,j;
double area = 0;
for (i=0;i<N;i++) {
j = (i + 1) % N;
area += polygon[i].x * polygon[j].y;
area -= polygon[i].y * polygon[j].x;
}
area /= 2;
return(area < 0 ? -area : area);
}
2.求三角形面积
语法:
result=area3(float x1,float y1,float x2,float y2,float x3,float y3);
参数:
x1~3:三角形3个顶点x坐标
y1~3:三角形3个顶点y坐标
返回值:
三角形面积
注意:
需要 math.h
源程序:
float area3(float x1,float y1,float x2,float y2,float x3,float y3)
{
float a,b,c,p,s;
a=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
b=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));
c=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));
p=(a+b+c)/2;
s=sqrt(p*(p-a)*(p-b)*(p-c));
return s;
}
3.两矢量间角度
语法:
result=angle(double x1, double y1, double x2, double y2);
参数:
x/y1~2:两矢量的坐标
返回值:
两的角度矢量
注意:
返回角度为弧度制,并且以逆时针方向为正方向
需要 math.h
源程序:
#define PI 3.1415926
double angle(double x1, double y1, double x2, double y2)
{
double dtheta,theta1,theta2;
theta1 = atan2(y1,x1);
theta2 = atan2(y2,x2);
dtheta = theta2 - theta1;
while (dtheta > PI)
dtheta -= PI*2;
while (dtheta < -PI)
dtheta += PI*2;
return(dtheta);
}
4.两点距离(2D、3D)
语法:
result=distance_2d(float x1,float x2,float y1,float y2);
参数:
x/y/z1~2:各点的x、y、z坐标
返回值:
两点之间的距离
注意:
需要 math.h
源程序:
float distance_2d(float x1,float x2,float y1,float y2)
{
return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
}
float distance_3d(float x1,float x2,float y1,float y2,float z1,float z2)
{
return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)));
}
5.射向法判断点是否在多边形内部
语法:
result=insidepolygon(Point *polygon,int N,Point p);
参数:
*polygon:多边形顶点数组
N:多边形顶点个数
p:被判断点
返回值:
0:点在多边形内部;1:点在多边形外部
注意:
若p点在多边形顶点或者边上,返回值不确定,需另行判断
需要 math.h
源程序:
#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)
typedef struct {
double x,y;
} Point;
int insidepolygon(Point *polygon,int N,Point p)
{
int counter = 0;
int i;
double xinters;
Point p1,p2;
p1 = polygon[0];
for (i=1;i<=N;i++) {
p2 = polygon[i % N];
if (p.y > MIN(p1.y,p2.y)) {
if (p.y <= MAX(p1.y,p2.y)) {
if (p.x <= MAX(p1.x,p2.x)) {
if (p1.y != p2.y) {
xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
if (p1.x == p2.x || p.x <= xinters)
counter++;
}
}
}
}
p1 = p2;
}
if (counter % 2 == 0)
return(OUTSIDE);
else
return(INSIDE);
}