C语言求任意四边形面积和其关联的三角形面积的关系
2013-05-18 13:42
651 查看
定理:对于任意的四边形ABCD,其对角线AC与BD的中点分别是M,N,AB,CD的延长线交于R.验证三角形RMN的面积是四边形ABCD面积的四分之一。
下面我们就用C语言来验证一下这个定理的正确性,由于计算机的精确度是有限的,我们采用双精度double来存储各个边长的长度及运算过程中的变量,由于double值会对实际长度进行截取,特别是长度为根号值时,导致与实际长度有出入,所以有时候最后得到的面积只能是近似,也就是答案接近于4就应是正确的答案,原命题也就得到了证明。
我贴出正确的C语言源代码,供大家编译运行。花了我四天时间,脑子真是笨呀!
#include<stdio.h>
#include<math.h>
typedef struct
{
double x;
double y;
} Point;
#define a P[0]
#define b P[1]
#define c P[2]
#define d P[3]
int ok(Point *p ) /*指针可以当数组来使用*/
{ /*检测是否1),2)+pow((a2-a1),2);
平行四边形,若是返回0*/
double a0,b0,a1,b1, a2,b2, a3,b3, k1,k2,k3,k4;
a0=p[0].x;b0=p[0].y;a1=p[1].x;b1=p[1].y;
a2=p[2].x;b2=p[2].y;a3=p[3].x;b3=p[3].y;
k1=pow((b1-b0),2)+pow((a1-a0),2);
k2=pow((b3-b2),2)+pow((a3-a2),2);
k3=pow((b2-b1),2)+pow((a2-a1),2);
k4=pow((b3-b0),2)+pow((a3-a0),2);
if((k1==k2)&&(k3==k4))
{ getch();
return 0;
}
return 1;
}
/*声明各个子函数*/
double si_area(double s[]);
Point joind(Point P[]);
main()
{
Point m,n,r,dian1,P[4],*PP=P;
char *p;
double x,y,tt,sos, var[5];
double m1,m2,m3,tmp ;
static char pname[]="ABCD";
p=pname;
while(*p)
{
printf("input (x,y) of point %c:",*p);
scanf("%lf%lf", &x, &y);
/*scanf("%lf%lf",&PP->x,&PP->y); 这种输入编译能成功,但运行时窗口会关闭*/
PP->x=x;PP->y=y;
p++;PP++;
} /* 至此得到四边形的4个顶点的坐标 */
if(!ok(P))
{
fprintf(stderr,"\ninvalid input...\n");
exit(1); /*异常结束1 */
} /*如果AB//CD则无法相交只好退出*/
/*求三角形的各个顶点*/
m.x=(a.x+c.x)/2.0;m.y=(a.y+c.y)/2.0;
n.x=(b.x+d.x)/2.0;n.y=(b.y+d.y)/2.0;
/*求四条边的边长,不要开根号,以便后面运算*/
var[0]=sqrt( pow((b.y-a.y),2)+pow((b.x-a.x),2) ) ;
var[1]=sqrt( pow((c.y-b.y),2)+pow((c.x-b.x),2) ) ;
var[2]=sqrt( pow((d.y-c.y),2)+pow((d.x-c.x),2) ) ;
var[3]=sqrt( pow((d.y-a.y),2)+pow((d.x-a.x),2) ) ;
/*求其中的一条对角线长*/
var[4]=sqrt( pow((b.y-d.y),2)+pow((b.x-d.x),2));
/*求四边形的面积 */
tt=si_area(var);
dian1=joind(P); /*得出四边形的交点坐标*/
r.x=dian1.x;r.y=dian1.y;
printf("the point is %lf %lf\n ",r.x,r.y);
/*求三角形的面积:采用余弦定理 */
m1= sqrt( pow((m.y-n.y),2 ) + pow((m.x - n.x),2) );
m2= sqrt( pow((r.y-n.y),2 ) + pow((r.x - n.x),2) );
m3= sqrt( pow((r.y-m.y),2 ) + pow((r.x - m.x),2) );
tmp = m1*m2*m3/(pow(((m1+m2+m3)*(m1+m2-m3)*(m2+m3-m1)*(m1+m3-m2)),0.5));
sos=(m1*m2*m3)/(4*tmp);
printf("the retangle's area is %lf\n",tt);
printf("the triangle's area is %lf\n", sos );
printf("the retangle's area is the %lf times as the triangle\n",tt/sos);
getch();
return 0;
}
/*以下是求两直线是否有交点的函数
返回参数:NULL。通过设置全局变量,所以没有返回参数
输入参数:结构体类型的两条线段的四个顶点 */
Point joind(Point P[])
{
double a0,b0,a1,b1, a2,b2, a3,b3, k1,k2;
Point ss;
double dian[2];
a0=P[0].x;b0=P[0].y;a1=P[1].x;b1=P[1].y;
a2=P[2].x;b2=P[2].y;a3=P[3].x;b3=P[3].y;
if((a0-a1)==0&&(b2-b3)==0)
{
dian[0]=a0;
dian[1]=b2;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else if((a0-a1)==0&&(b2-b3)!=0)
{
if((a2-a3)==0) /*所比较的直线平行*/
{
if((a1-a2)==0)
{
dian[0]=a1;
dian[1]=(b3-b0)*(a1-a0)/(a3-a0)+b0;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else if((a3-a0)==0)
{
dian[0]=a0;
dian[1]=(b2-b1)*(a0-a1)/(a2-a1)+b1;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else
{
k1=(b2-b1)/(a2-a1);
k2=(b0-b3)/(a0-a3);
dian[0]=(k2*a3-k1*a2+b2-b3)/(k2-k1);
dian[1]=(dian[0]-a2)*k1+b2;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
else
{
k2=(b2-b3)/(a2-a3);
dian[0]=a0;
dian[1]=(a0-a2)*k2+b2;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
else if((a0-a1)!=0&&(b2-b3)==0)
{
if((b0-b1)==0) /*所比较的直线平行*/
{
if((a1-a2)==0)
{
dian[0]=a1;
dian[1]=(b3-b0)*(a1-a0)/(a3-a0)+b0;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else if((a3-a0)==0)
{
dian[0]=a0;
dian[1]=(b2-b1)*(a0-a1)/(a2-a1)+b1;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else
{
k1=(b2-b1)/(a2-a1);
k2=(b0-b3)/(a0-a3);
dian[0]=(k2*a3-k1*a2+b2-b3)/(k2-k1);
dian[1]=(dian[0]-a2)*k1+b2;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
else
{
k1=(b0-b1)/(a0-a1);
dian[1]=b2;
dian[0]=(b2-b0)/k1+a0;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
else
{
k1=(b0-b1)/(a0-a1);
k2=(b2-b3)/(a2-a3);
if(k1==k2) /*所比较的直线平行*/
{
if((a1-a2)==0)
{
dian[0]=a1;
dian[1]=(b3-b0)*(a1-a0)/(a3-a0)+b0;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else if((a3-a0)==0)
{
dian[0]=a0;
dian[1]=(b2-b1)*(a0-a1)/(a2-a1)+b1;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else
{
k1=(b2-b1)/(a2-a1);
k2=(b0-b3)/(a0-a3);
dian[0]=(k2*a3-k1*a2+b2-b3)/(k2-k1);
dian[1]=(dian[0]-a2)*k1+b2;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
else
{
dian[0]=(k1*a0-k2*a2+b2-b0)/(k1-k2);
dian[1]=b0+(dian[0]-a0)*k1;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
}
/* 求四边形的面积 */
double si_area(double var[])
{
double s1,s2,ss1,ss2,a1;
s1=var[0]*var[3]*var[4]/(pow
(((var[0]+var[3]+var[4])*(var[0]+var[3]-var[4])*(var[3]+var[4]-var[0])*(var[0]+var[4]-var[3])),0.5));
ss1=var[0]*var[3]*var[4]/(4*s1);
s2=var[1]*var[2]*var[4]/(pow
(((var[1]+var[2]+var[4])*(var[1]+var[2]-var[4])*(var[2]+var[4]-var[1])*(var[1]+var[4]-var[2])),0.5));
ss2=var[1]*var[2]*var[4]/(4*s2);
a1=ss1+ss2;
return a1;
}
下面我们就用C语言来验证一下这个定理的正确性,由于计算机的精确度是有限的,我们采用双精度double来存储各个边长的长度及运算过程中的变量,由于double值会对实际长度进行截取,特别是长度为根号值时,导致与实际长度有出入,所以有时候最后得到的面积只能是近似,也就是答案接近于4就应是正确的答案,原命题也就得到了证明。
我贴出正确的C语言源代码,供大家编译运行。花了我四天时间,脑子真是笨呀!
#include<stdio.h>
#include<math.h>
typedef struct
{
double x;
double y;
} Point;
#define a P[0]
#define b P[1]
#define c P[2]
#define d P[3]
int ok(Point *p ) /*指针可以当数组来使用*/
{ /*检测是否1),2)+pow((a2-a1),2);
平行四边形,若是返回0*/
double a0,b0,a1,b1, a2,b2, a3,b3, k1,k2,k3,k4;
a0=p[0].x;b0=p[0].y;a1=p[1].x;b1=p[1].y;
a2=p[2].x;b2=p[2].y;a3=p[3].x;b3=p[3].y;
k1=pow((b1-b0),2)+pow((a1-a0),2);
k2=pow((b3-b2),2)+pow((a3-a2),2);
k3=pow((b2-b1),2)+pow((a2-a1),2);
k4=pow((b3-b0),2)+pow((a3-a0),2);
if((k1==k2)&&(k3==k4))
{ getch();
return 0;
}
return 1;
}
/*声明各个子函数*/
double si_area(double s[]);
Point joind(Point P[]);
main()
{
Point m,n,r,dian1,P[4],*PP=P;
char *p;
double x,y,tt,sos, var[5];
double m1,m2,m3,tmp ;
static char pname[]="ABCD";
p=pname;
while(*p)
{
printf("input (x,y) of point %c:",*p);
scanf("%lf%lf", &x, &y);
/*scanf("%lf%lf",&PP->x,&PP->y); 这种输入编译能成功,但运行时窗口会关闭*/
PP->x=x;PP->y=y;
p++;PP++;
} /* 至此得到四边形的4个顶点的坐标 */
if(!ok(P))
{
fprintf(stderr,"\ninvalid input...\n");
exit(1); /*异常结束1 */
} /*如果AB//CD则无法相交只好退出*/
/*求三角形的各个顶点*/
m.x=(a.x+c.x)/2.0;m.y=(a.y+c.y)/2.0;
n.x=(b.x+d.x)/2.0;n.y=(b.y+d.y)/2.0;
/*求四条边的边长,不要开根号,以便后面运算*/
var[0]=sqrt( pow((b.y-a.y),2)+pow((b.x-a.x),2) ) ;
var[1]=sqrt( pow((c.y-b.y),2)+pow((c.x-b.x),2) ) ;
var[2]=sqrt( pow((d.y-c.y),2)+pow((d.x-c.x),2) ) ;
var[3]=sqrt( pow((d.y-a.y),2)+pow((d.x-a.x),2) ) ;
/*求其中的一条对角线长*/
var[4]=sqrt( pow((b.y-d.y),2)+pow((b.x-d.x),2));
/*求四边形的面积 */
tt=si_area(var);
dian1=joind(P); /*得出四边形的交点坐标*/
r.x=dian1.x;r.y=dian1.y;
printf("the point is %lf %lf\n ",r.x,r.y);
/*求三角形的面积:采用余弦定理 */
m1= sqrt( pow((m.y-n.y),2 ) + pow((m.x - n.x),2) );
m2= sqrt( pow((r.y-n.y),2 ) + pow((r.x - n.x),2) );
m3= sqrt( pow((r.y-m.y),2 ) + pow((r.x - m.x),2) );
tmp = m1*m2*m3/(pow(((m1+m2+m3)*(m1+m2-m3)*(m2+m3-m1)*(m1+m3-m2)),0.5));
sos=(m1*m2*m3)/(4*tmp);
printf("the retangle's area is %lf\n",tt);
printf("the triangle's area is %lf\n", sos );
printf("the retangle's area is the %lf times as the triangle\n",tt/sos);
getch();
return 0;
}
/*以下是求两直线是否有交点的函数
返回参数:NULL。通过设置全局变量,所以没有返回参数
输入参数:结构体类型的两条线段的四个顶点 */
Point joind(Point P[])
{
double a0,b0,a1,b1, a2,b2, a3,b3, k1,k2;
Point ss;
double dian[2];
a0=P[0].x;b0=P[0].y;a1=P[1].x;b1=P[1].y;
a2=P[2].x;b2=P[2].y;a3=P[3].x;b3=P[3].y;
if((a0-a1)==0&&(b2-b3)==0)
{
dian[0]=a0;
dian[1]=b2;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else if((a0-a1)==0&&(b2-b3)!=0)
{
if((a2-a3)==0) /*所比较的直线平行*/
{
if((a1-a2)==0)
{
dian[0]=a1;
dian[1]=(b3-b0)*(a1-a0)/(a3-a0)+b0;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else if((a3-a0)==0)
{
dian[0]=a0;
dian[1]=(b2-b1)*(a0-a1)/(a2-a1)+b1;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else
{
k1=(b2-b1)/(a2-a1);
k2=(b0-b3)/(a0-a3);
dian[0]=(k2*a3-k1*a2+b2-b3)/(k2-k1);
dian[1]=(dian[0]-a2)*k1+b2;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
else
{
k2=(b2-b3)/(a2-a3);
dian[0]=a0;
dian[1]=(a0-a2)*k2+b2;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
else if((a0-a1)!=0&&(b2-b3)==0)
{
if((b0-b1)==0) /*所比较的直线平行*/
{
if((a1-a2)==0)
{
dian[0]=a1;
dian[1]=(b3-b0)*(a1-a0)/(a3-a0)+b0;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else if((a3-a0)==0)
{
dian[0]=a0;
dian[1]=(b2-b1)*(a0-a1)/(a2-a1)+b1;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else
{
k1=(b2-b1)/(a2-a1);
k2=(b0-b3)/(a0-a3);
dian[0]=(k2*a3-k1*a2+b2-b3)/(k2-k1);
dian[1]=(dian[0]-a2)*k1+b2;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
else
{
k1=(b0-b1)/(a0-a1);
dian[1]=b2;
dian[0]=(b2-b0)/k1+a0;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
else
{
k1=(b0-b1)/(a0-a1);
k2=(b2-b3)/(a2-a3);
if(k1==k2) /*所比较的直线平行*/
{
if((a1-a2)==0)
{
dian[0]=a1;
dian[1]=(b3-b0)*(a1-a0)/(a3-a0)+b0;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else if((a3-a0)==0)
{
dian[0]=a0;
dian[1]=(b2-b1)*(a0-a1)/(a2-a1)+b1;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
else
{
k1=(b2-b1)/(a2-a1);
k2=(b0-b3)/(a0-a3);
dian[0]=(k2*a3-k1*a2+b2-b3)/(k2-k1);
dian[1]=(dian[0]-a2)*k1+b2;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
else
{
dian[0]=(k1*a0-k2*a2+b2-b0)/(k1-k2);
dian[1]=b0+(dian[0]-a0)*k1;
ss.x=dian[0];ss.y=dian[1];
return ss;
}
}
}
/* 求四边形的面积 */
double si_area(double var[])
{
double s1,s2,ss1,ss2,a1;
s1=var[0]*var[3]*var[4]/(pow
(((var[0]+var[3]+var[4])*(var[0]+var[3]-var[4])*(var[3]+var[4]-var[0])*(var[0]+var[4]-var[3])),0.5));
ss1=var[0]*var[3]*var[4]/(4*s1);
s2=var[1]*var[2]*var[4]/(pow
(((var[1]+var[2]+var[4])*(var[1]+var[2]-var[4])*(var[2]+var[4]-var[1])*(var[1]+var[4]-var[2])),0.5));
ss2=var[1]*var[2]*var[4]/(4*s2);
a1=ss1+ss2;
return a1;
}
相关文章推荐
- c语言计算三角形面积代码
- C语言初学 计算三角形面积问题
- 用C语言编程求三角形的面积
- 点到直线的距离 点是否在多边形内 计算多边形面积 四边形面积 三角形面积 两边之和减去第三边 C程序
- Linux下的C语言编程——求三角形面积
- 从键盘任意输入三角形的三边长为a,b,c,编程判断a,b,c的值能否构成一个三角形,若能,请算出面积·若不能就输出不能构成三角形。
- 输入任意3个整数 判断是否能组成三角形 它的面积是多少?
- 【c语言】给出三角形的三边长,求三角形面积
- C语言浮点数除法求三角形面积
- 任意输入三条边(a,b,c实型),若能构成三角形,则计算并输出其面积,否则输出标志“No Triangle!”。
- 用带实参的宏名通过“海伦公式”求任意三角形的面积
- 使用C语言打印不同星号图案(矩形 平行四边形 三角形)
- C语言已知三边求三角形的面积
- C语言 输入三角形的三边,判断三角形的类型,并输出它的类型和面积
- c语言求三角形的面积及判断三角形类型
- C语言输入三角形边长判断其类型并输出面积实例代码
- 问题三十四: 任意输入三条边(a,b,c实型),若能构成三角形,则计算并输出其面积,否则输出标志“No Triangle!”。
- python中 自定义向量 计算向量乘积, 平行四边形面积,三角形面积
- hdoj2036 c语言实现(任意多边形的面积
- 计算任意三边三角形的面积的算法