程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> C語言求任意四邊形面積和其關聯的三角形面積的關系

C語言求任意四邊形面積和其關聯的三角形面積的關系

編輯:關於C

  定理:對於任意的四邊形ABCD,其對角線AC與BD的中點分別是M,N,AB,CD的延長線交於R.驗證三角形RMN的面積是四邊形ABCD面積的四分之一。

    下面我們就用C語言來驗證一下這個定理的正確性,由於計算機的精確度是有限的,我們采用雙精度double來存儲各個邊長的長度及運算過程中的變量,由於double值會對實際長度進行截取,特別是長度為根號值時,導致與實際長度有出入,所以最後得到的面積只能是近似,也就是答案接近於4就應是正確的答案,原命題也就得到了證明。

 #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[4];
  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)));
   /*求四邊形的面積 */
   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=cos((pow(m1,2)+pow(m2,2)-pow(m3,2))/2*m1*m2);
  sos=m1*m2*sqrt(1-pow(tmp,2));
  printf("the retangle's area is %lf\n",tt);
  printf("the m n r is\n %lf %lf\n%lf %lf\n%lf %lf\n",m.x,m.y,n.x,n.y,r.x,r.y);
  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;
     printf("the point is %lf  %lf\n ",dian[0],dian[1]);
     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 s[])
{
    double t1,a1;
    t1=(s[0]+s[1]+s[2]+s[3])/2.0;
    a1=sqrt((t1-s[0])*(t1-s[1])*(t1-s[2])*(t1-s[3]));
    return a1;
}

 

\

 


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved