如何计算平面n个圆相交的公共部分的面积

来源:互联网 发布:java emptyborder 编辑:程序博客网 时间:2024/04/28 14:09

原题参考 mmmcd 超超 在这个帖子当中的讨论
http://community.csdn.net/Expert/topic/4075/4075074.xml?temp=.4154627

N个任意圆相交求公共面积的问题

必须注意到如下
一:凸体和凸体相交依然是凸体,多元相交后也是凸体
二:多元相交结果,必然是由圆弧所组成,
三:最终的相交面积为各个子圆弧的弓形面积 + 内部凸多边形的面积


要解决这个问题,要解决下面几个问题:
第一个:圆弧的表达方法
Arc(圆心位置,半径,开始角度和结束角度,P1, P2)
   p1,p2是两个交点的位置
交点表达:
   P(x, y, c1, c2)  : 必然是两个 圆交出来的

第二个: 建立同圆的圆弧相交算法
只有两个圆弧是同一个圆上的时候,才用此算法
算法运算的结果是生成一组圆弧,他们的圆心,半径相同,其他的参数不同

第三个: 任意两圆相交结果的圆弧表达方法
    任意两个圆做相交判断,结果有三种:
          相  交:得到组成相交结果的两个圆弧
          不相交:得到两个空的圆弧
          包  含:得到一个空圆弧,一个满圆弧

有了这三个算法,n个圆相交的解决方案如下

第一步:
    n个圆两两执行相交计算,把结果用圆弧表示,执行结果是一个N×N的表格
    执行次数是n*(n-1)/2, 每次运算填充表的两个位置
               第一个圆    第二个   第三个   第四个  .....  第n个
    第一个圆      *        arc12    arc13    arc14   .....   arc1n
    第二个圆   arc21        *       arc23    arc24   .....   arc2n
    第三个圆   arc31       arc32    *        arc24   .....   arc2n
    第四个圆   arc41       arc42    arc23    *               arc2n
    ........     ................................................
    第n个圆    arcn1      arcn2     arcn3    arcn4   .....     *
在这个表格当中,每次运算填充的是arcij和arcji两个位置
比如,第3个和第4个圆相交,结果写入arc34和arc43
arc34是相交后的,第三个圆上的圆弧, arc43则是相交后的第四个圆上的圆弧

如果在执行这个运算过程当中
   arcij 和 arcji都是空圆弧,那么证明圆i和圆j不相交,全体的交集必然是空,可以停止算法了
   arcij 和 arcji一个空,一个满。那么空的圆可以抛弃当作不存在,因为他们之间是包含关系
                     
第二步
   对表的每行做同圆的圆弧的相交运算,得到的最终结果依然是多段圆弧
   相交的结果,可能是空,但是依然是有效的答案

第三步,串连所有的圆弧
   从第二步计算得到的结果当中,随意找到一个不空的圆弧,从中找到任意一个圆弧,开始串连
   串连的方法:
    总面积S为0, 串连点队列L为空
    从表当中选择一个圆,这个圆的表内同圆圆弧相交计算后得到的圆弧数组不空,从这个数组当中任意取得一个圆弧,作为当前圆弧
    while(1)
    {
       把当前圆弧的P1点加入串连顶点队列L当中
       计算这个圆弧的弓形面积,加入总面积S当中
       if ( 当前圆弧的P2点是顶点队列L的第一个点) {
          是跳出循环,结束串连
       }
       根据P2(x,y,c1,c2)点,找到它和另外一个圆的交点对应的圆弧,并把该圆弧作为当前的圆弧, 继续循环
    }

第四步, 计算面积
    在执行完成第三步之后, 串连点队列L就是N个圆相交部分的凸多边形的顶点队列,计算它的面积加入到S当中就完成了任务

原创粉丝点击