68336016 发表于 2012-7-30 22:49:12

有熟悉图像编程的朋友么,请教个计算曲线面积的问题

本帖最后由 68336016 于 2012-7-31 09:37 编辑

红色是设计曲线,蓝色是实际曲线,目的就是计算超过部分面积(左图绿色区块),不足部分面积(左图红色区块)
方法一:用像素法,我能计算出面积,但是误差比较大。因为实际曲线半径一般都是10米级多,缩小成像素,一个点就相当于实际一本书的面积了,图形边界造成的误差比较大,接近10%了

方法二:我把曲线中的圆弧都分解成多段线段,那么设计面积和实际面积我就能通过三角形面积和算出来,这步实现了,结果跟CAD里面比较误差0.05%,可以说很精确了。
现在为了求绿色,红色部分面积,就得把两曲线交集面积(白色部分)计算出来,但是想不到什么思路。
我现在有的就是曲线点的坐标(不是所有连续点坐标,因为曲线也是N多直线连接成的),用的是VC6.0

xivisi 发表于 2012-7-31 09:06:09

本帖最后由 xivisi 于 2012-7-31 09:09 编辑

楼主你有曲线点的坐标 相当于已经将曲线进行矢量化了,如此计算所有交点,相邻交点之间的曲线就是绿色或红色的区域,判断红色或者绿色就看在红色曲线内或者外,这样基本上就转换为各个独立区域。
对于凸多边形 按你的三角形法即可计算,
对于凹多边形,可以将大于180度的角的边延长与该多边形另一边相交分解为两个凸多边形,再用凸多边形计算即可,以此类推直至计算完毕。

PS:计算中有各种小技巧,即可加快效率,待楼主挖掘。   竞赛应该有很多类似的题目的

68336016 发表于 2012-7-31 09:34:31

本帖最后由 68336016 于 2012-7-31 09:36 编辑

xivisi 发表于 2012-7-31 09:06 static/image/common/back.gif
楼主你有曲线点的坐标 相当于已经将曲线进行矢量化了,如此计算所有交点,相邻交点之间的曲线就是绿色或红 ...

肉眼很直观的问题,转换成程序就很难

我得想想怎么求交点

求出交点后,还得判断哪些点(哪个曲线上的)跟交点组成相交部分图形(也就是内部白色部分面积)

xivisi 发表于 2012-7-31 10:11:14

本帖最后由 xivisi 于 2012-7-31 10:17 编辑

68336016 发表于 2012-7-31 09:34 static/image/common/back.gif
肉眼很直观的问题,转换成程序就很难

我得想想怎么求交点


高中数学里有 判断一个点 与一条直线之间关系的方法

另外,做算法真的费脑子的,可以简单的取红色相邻两点,求线性方程,然后取另一曲线两点(一般取靠近的) 如果在直线方程两边,则必有交点,但未必是取的这条线段上,只有向两边相邻不停地取下去了,直到交点在取的线段上

xivisi 发表于 2012-7-31 10:26:41

楼主做什么?感觉像什么运动的东西 计算误差

68336016 发表于 2012-7-31 10:53:21

本帖最后由 68336016 于 2012-7-31 10:55 编辑

xivisi 发表于 2012-7-31 10:26 static/image/common/back.gif
楼主做什么?感觉像什么运动的东西 计算误差

计算隧道,涵洞之类开挖土方用的,挖太多浪费混凝土,挖少了混凝土太薄也不行,所以要计算面积,得到实际用量

在CAD里面很简单就能解决,把区块填充,查询面积就可以。

但是VC里面一个个点,线都得自己控制

68336016 发表于 2012-7-31 20:01:10

xivisi 发表于 2012-7-31 10:26 static/image/common/back.gif
楼主做什么?感觉像什么运动的东西 计算误差

{:lol:} 网上搜了一天,终于解决了,暂时也是拷贝的,自己没消化
像素法非常慢,现在这个办法很快,而且计算精确,跟CAD对比相差0.03%        CRgn intersectRgn;
        intersectRgn.CreateRectRgn(0,0,0,0);
        int nIntersect = intersectRgn.CombineRgn(&区域1, &区域2 ,RGN_AND);

        //计算相交部分的面积
        Region   intersectRegion((HRGN)intersectRgn);
        Matrix   matrix;
        Rect*   rects   =   NULL;
        int   count   =   0;   
       
        CClientDC   dc(this);
        Graphics   graphics(dc.GetSafeHdc());
        graphics.GetTransform(&matrix);
        count = intersectRegion.GetRegionScansCount(&matrix);
        rects = (Rect*)malloc(count*sizeof(Rect));
        intersectRegion.GetRegionScans(&matrix, rects, &count);
       
        double   dbTotalArea=0;
        for(int j=0; j<count; ++j)
                dbTotalArea +=(rects.GetBottom()-rects.GetTop())* (rects.GetRight()-rects.GetLeft());
       
        free(rects);
        graphics.ReleaseHDC(dc.GetSafeHdc());
        //返回面积值

xivisi 发表于 2012-7-31 23:21:42

不知道 内部实现 是怎样的

68336016 发表于 2012-7-31 23:29:27

xivisi 发表于 2012-7-31 23:21 static/image/common/back.gif
不知道 内部实现 是怎样的

利用这个方法计算,我感觉非常方便
对任何的轮廓,只要能矢量化成多边形,就可以求交集,和,差,
变成纯粹的图像计算,自己想计算方法说不定有些漏洞

canspider 发表于 2012-7-31 23:51:24

按路径积分可以求出精确面积
对于多边形(单连通域),实质是求梯形面积和
对于图中的圆弧可以用弧面积公式

68336016 发表于 2012-8-1 00:05:13

canspider 发表于 2012-7-31 23:51 static/image/common/back.gif
按路径积分可以求出精确面积
对于多边形(单连通域),实质是求梯形面积和
对于图中的圆弧可以用弧面积公式 ...

你说的跟这文章意思差不多,面积越大精度越高

基于 Windows GDI 的几何形状测量
http://www.doc88.com/p-90826581347.html

xivisi 发表于 2012-8-1 12:46:49

canspider 发表于 2012-7-31 23:51 static/image/common/back.gif
按路径积分可以求出精确面积
对于多边形(单连通域),实质是求梯形面积和
对于图中的圆弧可以用弧面积公式 ...

汗,一说路径积分就想起来了 高数教材就有
页: [1]
查看完整版本: 有熟悉图像编程的朋友么,请教个计算曲线面积的问题