Contour algorithm

i m developing a terrain viewing application.
i want display terrain in contour mode (one which has curves depending upon height intervals). i know that i need interpolation and some curve like b-spline or something. can any body has this type of algo. for generating contours from height data ?

Do you need to do anything with the curves other than display them? If not, it would be easy to use a 1D texture map and automatic texture coordinate generation or a fragment program for getting the lines on your terrain.

Actually, I have the same question. I have a sphere and some values (temperatue) measured in some points on the sphere. I need to draw contour lines on this sphere (isothermes). Could someone elaborate as to how to use 1-D texture mapping to draw contour lines on the triangles that make up my sphere?

Texture mapping in 1D is simple. Just project all your vertices on to a vector in some direction.

For example, for a terrain heightmap in the xy plane, you could map your vertices on to the z axis. This is trivial, it’s simply the height at (x,y), the height is your texture coord. You may want to scale this value, but that’s completely arbitrary.

For a sphere, pick any direction from the center of the sphere, and project the sphere’s points onto this vector. The projected length along this vector is your texture coord.

You can use gl’s texture coordinate generation to do all this for you by supplying the appropriate planes. Here’s an example for the terrain:


glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );

// supply an arbitrary scale and direction
float scale = 0.12345;
float s[4] = { 0,0,scale,0 };
glTexGenfv( GL_S, GL_OBJECT_PLANE, s );

glEnable( GL_TEXTURE_GEN_S );

// now draw the terrain…

This is not exactly what I had in mind… See, in terrain mapping the contours depend only on distance from a reference plane, or from a reference sphere (if we want to do contours on a planet, for example). What I was thinking about was to plot isovalues of something, not necessarily height, on a geometrical shape. Think of air pressure isocontours on an airplane’s wing, for instance…

At the moment, I have scalar values (temperature) and corresponding color triples (R,G,B) at the vertices of the triangles by which I divided my unit sphere (so the normals at vertices coincide with the vertices themselves). OpenGL performs automatic (Gouraud?) shading inside each triangle. Now I need an algorithm for plotting contour lines across each triangle.

For that I will probably consider each of the 3 sides of every triangle, find (by interpolation), the coordinate at which the value crosses the edge. This will be the point where the contour line will pass.

What to do next is a mistery to me. I was thinking about plotting a 3-D point (GL_POINTS) or do a line-loop… But I have a feeling that it could be done with texture mapping. But I don’t know how :frowning:

Well, for automatic texture gen you have these basic choices:

  1. object linear
  2. eye linear
  3. sphere map
  4. cube map
  5. reflection map
  6. normal map
  7. others…

It sounds like you will need to roll your own, as it were, since there is as yet no “contour map”. You could calculate texture coodinates on the CPU, and assign them per-vertex manually. Or, you could do the same thing in a vertex program. Additionally, you can modify/create texture coordinates in a fragment program from vertex and/or texture data. You have quite a bit to work with.

The 1D texture map approach is certainly fastest but somtimes you need the actual lines.

To generate actual lines it’s fairly straight forward if your data is triangulated. Say you have a triangle defined by vertices P0, P1 and P2. At each vertex you have a scalar value V0, V1 and V2. You then have some threshold X.

For each triangle:

Step 1: Trivial reject. All values V0, V1 and V2 are either above or below X. Do nothing.

Step 2: There will only be 2 line segments that the contour passes through. For example if V0 is above X and V1 and V2 are below the contour passes through line segments P0 P1 and P0 P2. Along each of these line segments you need to find the position of the contour line that passes through them. Find the parameter distance ‘t’ between each set of points. You determine t from the data values. So for line segment P0 P1

X = V0 + t * ( V1 - V0 )
t = ( X - V0 ) / ( V1 - V0 )

Step 3: Compute the positions of the contour line. Call the positions of the contour line C0 and C1. To compute these positions just plug ‘t’ into the parameterized line equation.

C0 = P0 + t * ( P1 - P0 )

Then do the same for the second line segment.

This is the basic way of doing it. Some comments: This just generates individual line segments. You can write the code so that it ‘follows’ the contour to create a more efficient polyline. Beware devide by zero. This can happen when your threshold value is the same as multiple data values. However a single data value that is the same as your threshold value will just generate a line that is a point.

From 2D regular gridded data you have to break the squares of data into triangles. I have found that often data from numerical simulations is symmetric. In the process of triangulating the squares you can lose this symmetry. So the data is symmetric but your contour lines arent. In this instance you will have to initially process the square first to determine how it should be triangulated.

A way to triangularise quads so that they are still symetric is to add a new vertice at the center of each quad, at the average z of the 4 neighbours. Then you create 4 triangles, from this center to each edge.

The drawback is that you end up with twice more triangles.