Jump to content
  • Advertisement
Sign in to follow this  
Big Muscle

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.

If you intended to correct an error in the post then please contact us.

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:

 surface.png

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 this post


Link to post
Share on other sites
Advertisement

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 smile.png

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites

Weird, I can't sometimes log in to this forum properly...

 

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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!