贴上我的想法,不知到是不是正确。。。
#include <stdio.h>
#include <math.h>
#include <conio.h>
#define EPSILON 1e-24
typedef unsigned char BOOL;
/* 三角形区域结构 */
typedef struct triArea
{
/* 向量AB */
double vAB[2];
/* 向量AC */
double vAC[2];
/* 向量BC */
double vBC[2];
/* 向量AB和向量AC的夹角 */
double angleAB_AC;
/* 向量AB和向量BC的夹角 */
double angleAB_BC;
/* 向量BC和向量AC的夹角 */
double angleBC_AC;
};
/* 取两数中最大值 */
double max(double,double);
/* 趋近比较 */
BOOL approx_equal(double,double);
/* 通过平面两座标计算向量坐标 */
void convert(double [],double [],double []);
/* 计算两向量的点积 */
double valmuti(double [],double []);
/* 计算一个向量的模 */
double mod(double []);
/* 计算两向量夹角的cos值 */
double vector_cos(double [],double []);
int main()
{
/* 定义一个测试点 */
double posD[2];
/* 定义构成三角形平面的三个顶点 */
double posA[2]={1,4},posB[2]={2,5},posC[2]={3,6};
/* 定义测试点与三角区域个顶点的夹角和与顶点的连线向量 */
double vAD[2],vBD[2],vCD[2];
double angleAD_AB,angleAD_AC,angleBD_AB,angleBD_BC,angleCD_AC,angleCD_BC;
/* 定义一个三角形区域 */
triArea region;
/* 计算三角形区域的边界向量 */
convert(posA,posB,region.vAB);
convert(posA,posC,region.vAC);
convert(posB,posC,region.vBC);
/* 计算三角形区域的三个顶角的度数 */
region.angleAB_AC=acos(vector_cos(region.vAB,region.vAC));
region.angleAB_BC=acos(vector_cos(region.vAB,region.vBC));
region.angleBC_AC=acos(vector_cos(region.vBC,region.vAC));
double triAB,triAC,triBC;
printf("Input a position (x,y)=");
scanf("%lf,%lf",&posD[0],&posD[1]);
/* 计算测试点与三角形区域三个顶点构成的向量 */
convert(posA,posD,vAD);
convert(posB,posD,vBD);
convert(posC,posD,vCD);
/* 计算测试点与各个顶点的夹角 */
angleAD_AB=acos(vector_cos(region.vAB,vAD));
angleAD_AC=acos(vector_cos(region.vAC,vAD));
angleBD_AB=acos(vector_cos(region.vAB,vBD));
angleBD_BC=acos(vector_cos(region.vBC,vBD));
angleCD_AC=acos(vector_cos(region.vAC,vCD));
angleCD_BC=acos(vector_cos(region.vBC,vCD));
/* 趋近比较 */
if(approx_equal(angleAD_AB+angleAD_AC,region.angleAB_AC)&&
approx_equal(angleBD_AB+angleBD_BC,region.angleAB_BC)&&
approx_equal(angleCD_AC+angleCD_BC,region.angleBC_AC))
{
printf("Position (%lf,%lf) is in the triangle region!\n",posD[0],posD[1]);
}
else
{
printf("Position (%lf,%lf) is not in the triangle region!\n",posD[0],posD[1]);
}
getch();
return 1;
}
double max(double a,double b)
{
return a>b?a:b;
}
BOOL approx_equal(double a,double b)
{
if(!a&&b) return fabs(b)<=EPSILON;
if(a&&!b) return fabs(a)<=EPSILON;
return (fabs(a-b)/max(fabs(a),fabs(b)))<=EPSILON;
}
void convert(double bpos[],double epos[],double v[])
{
register int i;
for(i=0;i<2;v[i]=epos[i]-bpos[i],i++);
}
double valmuti(double v1[],double v2[])
{
register int i;
double result=0;
for(i=0;i<2;result+=v1[i]*v2[i],i++);
}
double mod(double v[])
{
register int i;
double result=0;
for(i=0;i<2;result+=pow(v[i++],2));
return sqrt(result);
}
double vector_cos(double v1[],double v2[])
{
return valmuti(v1,v2)/(mod(v1)*mod(v2));
}