# Drawing surface plot in C++ using GDI

This topic is 1839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello,

I need a little help. I have to render 3D surface plot in C++ using GDI. I have approx. 1000 points [x,y,z] and I want to render a plot from them (it could be called height map or something like that.. exactly what Matlab "surf" function does). The speed is not big problem here, because the plot will be rendered once and then stored to image file so using GDI is enough.

I am able to render 2D plot (from bird view) without any problem by just omitting Z coordinate and simply drawing polygons from 4 neighbouring points. I even fill each rectangle by different color by differentiate their heights. I get this result (which is same as rotating Matlab plot to bird view):

[attachment=16122:plot2d.png]

But now I want to rotate it so the Z coordinate is visible - just to get something like this:

I tried to create projection matrix and multiply each point by it but I didn't get anything usable. Could anyone help me with this?

Thank you!

##### Share on other sites

Assuming you have the correct view/projection transformation, and you insist on using GDI:

• Treat your rectangles as pairs of triangles, or a Polygon in GDI's terms. GDI does not have built-in 3D capabilities whatsoever, so you need to manually project any 3D geometry you have before sending it to the system. Rectangles with varying corner point height (as you have here) are not rectangles anymore, if the transformation is anything except an exact overhead (or underneath) projection.
• Sort your polygons from back to front given the distance from the view plane, or prepare for some serious work as you implement z-buffering manually

Or

• Use D3D or WPF (or OpenGL, if so inclined). "Proper" 3D APIs make this very easy if you know the technologies otherwise.
Edited by Nik02

##### Share on other sites

Have you considered using plotting libraries for that?

In particular:

##### Share on other sites

Our goal was to make it as simple as possible. It does not have to be pure GDI but we should be able to achieve by GDI-like functions (i.e. DrawPolygon, FillPolygon etc.). I tried MathGL and it generates nice plot but its license (GPL) does not serve our purpose so it is probably unusable. Current 2D (bird eye) view is generated very simply as:

for(int i = 0; i < x.size() - 1; ++i)
for(int j = 0; j < y.size() - 1; ++j)
{
POINT points[4];
p[0] = x, y[j];
p[1] = x[i+1], y[j];
p[2] = x[i+1], y[j+1];
p[3] = x, y[j+1];

SetFillColorFromPalette(z[j]);
Polygon(points, 4);
}


I was thinking about function Project(x, y, z) which is called for each p0, p1, p2, p3 and just transforms the coordinate to the screen_x and screen_y and Polygon function will draw this transformed points then. But my expectance was probably too simple to make it work this way. Or maybe only the implementation of Project function was incorrect and transformation was wrong? I don't have much experience in this so I just tried what I remember from school - multiplying vector (x,y,z,1) by rotation matrix and scaling "x" and "y" by "z".

##### Share on other sites
At least a simple vector library would help (I always found the lack of functionality with PointF et.al. very inhibiting). Anyway: A hardcoded isometric projection should suffice.

Since you don't have interpenetration of the polygons, you don't even need sophisticated depth logic. The back-to-front Nik mentioned can be "faked" by correctly choosing the order of your loops and in which direction the loop variables run.

##### Share on other sites

Our goal was to make it as simple as possible. It does not have to be pure GDI but we should be able to achieve by GDI-like functions (i.e. DrawPolygon, FillPolygon etc.). I tried MathGL and it generates nice plot but its license (GPL) does not serve our purpose so it is probably unusable.

A note from the page:

About LGPL and GPL licenses. Generally MathGL is GPL library. However, you can use LGPL license for MathGL core if you don’t use wrapper widget classes, SWIG-based interfaces and disable GSL features. This can be done by using lgpl option at build time. According this, I’ve added the LGPL win32 binaries into Download page.

Perhaps LGPL helps?

##### Share on other sites

Does LGPL allow distributing without the source code? If it does not then it is still not suitable...

However, I noticed that there are two important functions in MathGL - rotate and calcScr which seem to be enough to correctly render 3D plot via my own algorithm, i.e. calling calcScr on each of p0,p1,p2,p3 (mentioned above) and it seems to be much faster then using MathGL completely. Both function just do some matrix operations and point scaling.

1. 1
2. 2
3. 3
4. 4
Rutin
18
5. 5

• 14
• 12
• 9
• 12
• 37
• ### Forum Statistics

• Total Topics
631423
• Total Posts
3000005
×