分享

求两圆的公共部分的面积-转载

 玉诗 2015-03-29
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define PI 3.1415926

typedef struct
{
 float x;
 float y;
 float r;
}circle;

typedef struct
{
 float x;
 float y;
}intersect;

float p1x;
float p1y;
float p2x;
float p2y;

/*计算圆心之间的长度*/
float betweenR(circle c1,circle c2);

void prn(circle c1,circle c2);

/*计算三角形的面积*/
float areaTriangle(intersect p1,intersect p2,circle c);

/*计算交点并把值传递给p1x p1y p2x p2y*/
bool countIntersect(circle c1,circle c2,intersect p1,intersect p2);

/*计算交点和圆心所构成的扇形的面积*/
float countSector(circle c,intersect p1,intersect p2);

int main()
{
 /*function variables*/
 circle c1;/*声明圆c1*/
 circle c2;/*声明圆c2*/

 intersect p1;/*交点p1*/
 intersect p2;/*交点p2*/

 float br;/*圆心之间的距离*/

 float maxR;/*大圆半径*/
 float minR;/*小圆半径*/
 float totalR;/*半径和*/

 float ts1;/*圆c1和交点所构成的三角形的面积*/
 float ts2;/*圆c2和交点所构成的三角形的面积*/
 float ss1;/*圆c1和交点所构成的扇形的面积*/
 float ss2;/*圆c2和交点所构成的扇形的面积*/
 float g1;/*圆c1和交点所构成的弓形的面积*/
 float g2;/*圆c2和交点所构成的弓形的面积*/

 float sValue;/*两圆公共部分的面积*/

 /*end of function variables*/

 printf("Please Input two circles: (such as:X1,Y1,R1,X2,Y2,R2 contidion:(R1,R2>0))\n");
 scanf("%f,%f,%f,%f,%f,%f",&c1.x,&c1.y,&c1.r,&c2.x,&c2.y,&c2.r);

 /*initialize p1&p2*/
 p1.x=0;
 p1.y=0;
 p2.x=0;
 p2.y=0;

 prn(c1,c2);
 br=betweenR(c1,c2);/*计算圆心之间的距离*/
 printf("Between the circles the length is:%.3f\n",br);
 maxR=(c1.r>c2.r?c1.r:c2.r);/*大圆半径*/
 minR=(c1.r<c2.r?c1.r:c2.r);/*小圆半径*/
 totalR=c1.r+c2.r;/*两圆半径和*/
 printf("the maxR is:%f,the minR is:%f,totalR is:%f\n",maxR,minR,totalR);

 if((br+minR)<=maxR)/*圆心之间的距离与小圆半径之和小于大圆半径时,小圆在大圆内,没有公共部分,有或没有交点*/
 {
  printf("Small circle is in big circle,there is no intersect points!\n");
  exit(0);
 }
 else if(br>totalR)/*圆心之间的距离大于两圆半径之和,两圆分离,没有交点*/
 {
  printf("There is no intersect points!\n");
  exit(0);
 }
 else if(br==totalR)/*圆心之间的距离等于两圆半径之和,两圆有一个交点,但无公共部分*/
 {
  printf("Two circle have one intersect point,there is no intersect area!\n");
  exit(0);
 }
 else if(br<totalR)/*圆心之间的距离小于半径之和,两圆有两个交点,计算公共区域的面积*/
 {
  countIntersect(c1,c2,p1,p2);/*计算两圆的交点的坐标*/
  
  /*将计算的结果传递给p1.x p1.y p2.x p2.y*/
  p1.x=p1x;
  p1.y=p1y;
  p2.x=p2x;
  p2.y=p2y;

  ts1=areaTriangle(p1,p2,c1);/*计算交点和圆c1所构成的三角形的面积*/
  ts2=areaTriangle(p1,p2,c2);/*计算交点和圆c2所构成的三角形的面积*/

  ss1=countSector(c1,p1,p2);/*计算交点和圆c1所构成的扇形的面积*/
  ss2=countSector(c2,p1,p2);/*计算交点和圆c2所构成的扇形的面积*/

  g1=ss1-ts1;/*计算交点和圆c1所构成的弓形的面积*/
  g2=ss2-ts2;/*计算焦点和圆c2所构成的弓形的面积*/

//////////////////////////////////////////////////////////////////////////////////////////////////////
   if((br*br+minR*minR)<=maxR*maxR)/*圆心之间的距离与小圆半径的平方之和若小于或等于大圆半径的平方*/
   {/*小圆部分为大扇形或半圆,面积为小圆面积-小圆弓形形面积+大圆弓形面积*/
    if(c1.r>c2.r)
    {
     sValue=(float)(PI*c2.r*c2.r-g2+g1);
     printf("Intersect area is:%.3f\n",sValue);
    }
    else if(c1.r<=c2.r)
    {
     sValue=(float)(PI*c1.r*c1.r-g1+g2);
     printf("Intersect area is:%.3f\n",sValue);
    }
   }
   else /*圆心之间的距离与小圆半径的平方之和若大于大圆半径的平方,则过两圆相交小圆为小扇形*/
   {
    printf("Intersect area is:%.3f\n",g1+g2);
   }
//////////////////////////////////////////////////////////////////////////////////////////////////////
  printf("\n");
 } 
}

/*finish the print function*/
void prn(circle c1,circle c2)
{
 printf("c1:%f,%f,%f\n",c1.x,c1.y,c1.r);
 printf("c2:%f,%f,%f\n",c2.x,c2.y,c2.r);
}

/*betweenR return the length of the circles' center*/
float betweenR(circle c1,circle c2)
{/*求圆心之间的距离*/
 float length;
 length=(float)sqrt((c1.x-c2.x)*(c1.x-c2.x)+(c1.y-c2.y)*(c1.y-c2.y));
 return length;
}

/*count the area of Triangle*/
float areaTriangle(intersect p1,intersect p2,circle c)
{/*求三角形的面积,海伦公式*/
 float a;/*length p1 to p2*/
 float b;/*length p1 to d*/
 float d;/*length p2 to d*/
 float p;/*p=(a+b+c)/2*/
 float s;/*sqare*/

 a=(float)sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
 b=(float)sqrt((p1.x-c.x)*(p1.x-c.x)+(p1.y-c.y)*(p1.y-c.y));
 d=(float)sqrt((p2.x-c.x)*(p2.x-c.x)+(p2.y-c.y)*(p2.y-c.y));

 p=(a+b+d)/2;

 s=(float)sqrt(p*(p-a)*(p-b)*(p-d));

 return s;
}

/*count intersect point*/
bool countIntersect(circle c1,circle c2,intersect p1,intersect p2)
{/*求两圆相交的交点坐标*/
 float a=0;
 float b=0;
 float c=0;
 float k=0;
 float t=0;
 float m=0;
 float n=0;
 float st;

 k=(c1.r*c1.r+c2.x*c2.x+c2.y*c2.y-c1.x*c1.x-c1.y*c1.y-c2.r*c2.r);
 a=4*((c1.y-c2.y)*(c1.y-c2.y)+(c2.x-c1.x)*(c2.x-c1.x));
 b=4*k*(c1.y-c2.y)-8*c1.y*(c2.x-c1.x)*(c2.x-c1.x)+2*c1.x*(c1.x-c2.x)*(c1.y-c2.y);
 c=k*k+4*c1.y*c1.y*(c2.x-c1.x)*(c2.x-c1.x)-k*c1.x*(c2.x-c1.x)-4*c1.r*c1.r*(c2.x-c1.x)*(c2.x-c1.x);
 printf("%f,%f,%f\n",a,b,c);

 t=b*b-4*a*c;
 st=(float)sqrt(t);
 printf("%f;%f\n",t,st);

 if(t<0)
 {
  printf("No intersect point!\n");
  return false;
 }
 else if(t=0)
 {
  printf("Two circles only have one intersect point!\n");
  return false;
 }
 else 
 {
  printf("Two circles have two intersect points!\n");
  p1.y=((-1)*b+st)/(2*a);
  p2.y=((-1)*b-st)/(2*a);

  printf("p1.y:%f\n",p1.y);
  printf("p2.y:%f\n",p2.y);
  
  p1.x=(k+2*p1.y*(c1.y-c2.y))/(2*(c2.x-c1.x));
  p2.x=(k+2*p2.y*(c1.y-c2.y))/(2*(c2.x-c1.x));
  printf("p1.x:%f\n",p1.x);
  printf("p2.x:%f\n",p2.x);

  p1x=p1.x;
  p1y=p1.y;
  p2x=p2.x;
  p2y=p2.y;

  return true;
 }
}

/*count the circles' sector area*/
float countSector(circle c,intersect p1,intersect p2)
{/*求扇形的面积*/
 float a;/*length p1 to p2*/
 float b;/*length p1 to d*/
 float d;/*length p2 to d*/
 float tmp;

 b=(float)sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
 a=(float)sqrt((p1.x-c.x)*(p1.x-c.x)+(p1.y-c.y)*(p1.y-c.y));
 d=(float)sqrt((p2.x-c.x)*(p2.x-c.x)+(p2.y-c.y)*(p2.y-c.y));
 
 tmp=(a*a+d*d-b*b)/(2*a*d);

 tmp=(float)acos(tmp);

 return (tmp*c.r*c.r/2);

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多