65.9K
CodeProject 正在变化。 阅读更多。
Home

改进的等高线绘制算法的 C++ 实现

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (11投票s)

2002年1月10日

3分钟阅读

viewsIcon

333126

downloadIcon

12841

此类生成用户定义函数的等值线。 曲线被绘制到OpenGL设备上下文或存储在线条带中。

Sample Image - contour.jpg

引言

本文介绍了一个等值线绘制类。它旨在绘制用户定义的函数 f(x,y) 的等值线。我编写它来将其集成到一个图形库中:Plot Graphic Library

此类基于[1](查看参考文献部分)中提出的算法。它基本上是等值线跟踪算法的改进版本。

理解算法

该算法使用几个调整参数,用户必须选择这些参数才能获得算法的最佳质量/性能比率。

  • x,y 的定义域
        // Setting domain x=[0,1], y=[2,3]
        double pLimits[4]={0,1,2,3,4};
        CContour contour;
        contour.SetLimits(pLimits);
  • 主网格的大小:在其上计算函数f(x,y)的网格。请参阅SetFirGrid, GetColFir, GetRowFir。该参数极大地影响轮廓的质量。
  • 辅助网格的大小:将要评估函数的网格。该网格可以比第一个网格精细得多。请参阅SetSecGrid, GetColSec, GetRowSec

CContour

主等值线类。此类不能直接使用,必须被继承。继承的类必须实现 ExportLine 函数。要生成等值线,请使用

void Generate()

确保在调用此函数之前已设置字段函数(f(x,y))。 该函数将为每个新段调用 ExportLine

CGLContour

使用此类将等值线绘制到 OpenGL 设备上下文中。

CListContour

使用此类生成等值线并将其存储为线条带。 用户可以检索每个等值线并根据自己的意愿使用它。 此函数使用两个子类

  • CLineStrip,一个包含点索引的 list < int >
  • CLineStripList,一个 list <CLineStrip*>

可以通过以下方式访问线条带

CLineStripList* GetList(iPane);

其中 iPane 是轮廓的索引。

如何操作...

设置等值线对象

假设我们已经从 CContour 继承了一个类并覆盖了 ExportLine 函数。

    class CMyContour : CContour
    { 
        void ExportLine(...);
    }

现在,首先设置函数 f(x,y)

    double  myF(double x, double y)
    { [...] return ... };
	
    CMyContour contour;
    // Setting f(x,y)=myF
    contour.SetFieldFcn(myF);

然后设置等值线值,即

    int n;
    CMyContour contour;
    vector<double> vIso(n); 
    for (int i=0;i<n;i++)
    { ... }
    // setting iso-lines
    contour.SetPlanes(vIso);

等值线已准备好使用。

使用 OpenGL 绘制等值线

使用 CGLContour 作为 CContour 的继承函数。

    CGLContour contour;
    // Setting up contour : setting f, domain of x, 
    // isocurve values
    [...]
    // generating contour
    contour.Generate();

在线条带中检索等值线

使用 CListContour 作为 CContour 的继承函数。只有相对于辅助网格的点的索引存储在列表中。您可以使用 GetXi()GetYi() 函数访问它们的实际值。

    CGLContour contour;
    // Setting up contour : setting f, 
    // domain of x, isocurve values
    [...]
    // generating contour
    contour.Generate();
    // Retrieving info
    CLineStripList* pStripList;
    // getting 0-th iso-curve
    pStripList=contour.GetLines(0); 
    ASSERT(pStripList);
    // iterating liststrip vertices
    CLineStrip::iterator pos;
    for (pos=pStripList->begin(); 
        pos != pStripList->end() ; pos++)
    {
        pStrip=(*pos);
        ASSERT(pStrip);
        if (pStrip->empty())
            continue;
        // using info of strip list
        // pStrip contains the successive index of the points
        // See CContourGLDoc.OnDraw for further details
        [...]       
    }

更新

  • 2002 年 8 月 31 日:添加了来自 Chenggang Zhou 的贡献:更好的条带压缩、阈值合并、条带面积、边界检测,以及一些我不记得的较小更改...
  • 2002 年 3 月 4 日:所有代码现在都在使用 STL。 :)

参考文献

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.