## Introduction

This article presents a contour plot class. It is designed to draw iso-contour of a user-defined function f(x,y). I wrote it to integrate it in a graphic library : Plot Graphic Library

The class is based on the algorithm presented in [1] (Check References section). It is basically an improved version of the Level Curve Tracing Algorithm.

## Understanding the algorithm

The algorithm uses several tuning parameter that the user must choose in order to have the best quality/performance ratio of the algorithm :

- Domain of x,y:
double pLimits[4]={0,1,2,3,4};
CContour contour;
contour.SetLimits(pLimits);

- Size of the primary grid : The grid on which evaluate the function f(x,y). See
`SetFirGrid, GetColFir, GetRowFir`

. The parameter influence greatly the quality of the contour.
- Size of the secondary grid : The grid where the function is going to be evaluated. This grid can be much finer that the first grid. See
`SetSecGrid, GetColSec, GetRowSec`

.

## Classes

### CContour

Main contour class. This class cannot be directly but has to be inherited. The inherited class must implement the `ExportLine`

function. To generate contours, use

void Generate()

Make to have set the field function (f(x,y)) before calling this function. The function will call `ExportLine`

for each new segment.

### CGLContour

Use this class to draw contours to an OpenGL device context.

### CListContour

Use this class to generate contour and store them as line strip. The user can retrieve each contour and use it as he wills. This function uses to sub-classes :

`CLineStrip`

, a `list < int > `

containing the index of the points.
`CLineStripList`

, a `list <CLineStrip*>`

.

The line strip can be accessed by

CLineStripList* GetList(iPane);

where `iPane`

is the index of the contour.

## How to...

### Set up a contour object

Suppose that we have inherited a class from `CContour`

and overriden `ExportLine`

function.

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

Now, first set the function f(x,y):

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

Then set the iso-contour values, i.e.

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

The contour is ready to be used.

### Draw contours using OpenGL

Use `CGLContour`

as inherited function of `CContour`

.
CGLContour contour;
[...]
contour.Generate();

### Retrieve contours in line strip

Use `CListContour`

as inherited function of `CContour`

. Only the index of the points with respect to second grid are stored in the list. You can access their real value by using `GetXi()`

and `GetYi()`

functions.

CGLContour contour;
[...]
contour.Generate();
CLineStripList* pStripList;
pStripList=contour.GetLines(0);
ASSERT(pStripList);
CLineStrip::iterator pos;
for (pos=pStripList->begin();
pos != pStripList->end() ; pos++)
{
pStrip=(*pos);
ASSERT(pStrip);
if (pStrip->empty())
continue;
[...]
}

## Updates

- August, 31, 2002 Added contribution from Chenggang Zhou: better strip compression, threshold merging, area of strip, boundary detection, Also some minor changes I don't remember...
- March, 4, 2002 All the code is now using STL.

## References