Want to read Slashdot from your mobile device? Point it at m.slashdot.org and keep reading!


Forgot your password?
Check out the new SourceForge HTML5 internet speed test! No Flash necessary and runs on all devices. ×

Writing Code for Surface Plots? 81

MySchizoBuddy asks: "In what ways can you code plots of surface charts using a z(x,y) function or a cloud of points? I'm looking for a tutorial that explains this that doesn't use DirectX or OpenGL libraries (the language I'm using cannot use either framework anyway). How is the 3D mess generated and how can the 2D contour plots be generated as well? I'm assuming once I know that I can also use it to make torus plots as well. Remember, I'm asking for the explanation of the underlying math and an example code that does that. The GNUPlot gallery has some examples that I find helpful, but are there similar examples out there? (Remember, I am writing the plotting code as well)? Can anyone help or point me in the right direction?"
This discussion has been archived. No new comments can be posted.

Writing Code for Surface Plots?

Comments Filter:
  • first plot (Score:2, Funny)

    by McGiraf ( 196030 )
    first plot

    hum ...
  • Graph3 (Score:2, Informative)

    by The MAZZTer ( 911996 )

    http://www.detachedsolutions.com/graph3/ [detachedsolutions.com]

    This is software that does what you need, written for the TI-83 (should work fine on an 84 too). Since it's open source, you can peek at the source code to get an idea of how its 3d rendering works.

    Unfortunately, most TI calculator apps are coded in assembly...

  • Another view (Score:4, Interesting)

    by Knights who say 'INT ( 708612 ) on Monday July 24, 2006 @12:13AM (#15767863) Journal
    You could plot graphics that represent levels as colours. I think I invented a kind of R^2->R function plot that represents a Z value as the degree of grey (0 being black, 255 being white) corresponding to Z mod 255. The result is that the more frequent "cuts" (sudden changes from white to black) are, the highest is the derivative.

    Looky here [navarro.mus.br], here [navarro.mus.br] and here [navarro.mus.br].
  • I generated solutions to partial differential equations in Mathematica that looked similiar to those plots. You can animate them (Bessel Functions, Heat Equation, and harmonic motion). I personally would use Mathematica. If you're a student you can get that application for cheap.
  • by perlionex ( 703104 ) * <joseph&ganfamily,com> on Monday July 24, 2006 @12:30AM (#15767895) Homepage

    I looked at 3D rendering quite a while back (about 15 years ago). Believe me -- you probably don't really want to built this up from scratch.

    It sounds like you just need some sample code that doesn't rely on OpenGL or DirectX. To that end, the following (open-source) projects may be useful:

  • Meshes ? OMG data structures to manage lines. My brain just froze.
    So what is you're API that lets you turn pixels on and off? Its not that hard to go from a cloud of points in openGL to a cloud of points in another api.

    Contour lines can be harder. you need to connect points on the same elevation without drawing a line through higher/lower elevation. I'd say don't bother connecting lines. just draw a lot of points (of certain colors for certain heights) with a fine enough granularity that they bleed into
  • MATLAB (Score:4, Interesting)

    by Bob_Geldof ( 887321 ) on Monday July 24, 2006 @12:44AM (#15767913) Homepage Journal
    just a thought, but why not use MATLAB. You can sometimes use it to make stand-alone programs and maybe even DLLs. then add it to your code. I help develop code for a Cray X1 and all visualization (for my project) is done locally using MATLAB. It's pretty beefy, but it'll make a contour plot.
  • 2D contouring (Score:5, Informative)

    by jmac880n ( 659699 ) on Monday July 24, 2006 @12:47AM (#15767922)

    Good 2D contour plotting is not easy (I know!!!).

    If you are not afraid of coding, then the best reference that I know of is:

    • Computing Contours by Successive Solution of Quintic Polynomial Equations
      by Albrecht Preusser, ACM TOMS V10#4

    The code (in FORTRAN, unfortunately) is also in TOMS as:

    • Algorithm 626 TRICP: A Contour Plot Program Triangular Meshes

    You can get ACM TOMS (Transaction on Mathematical Software) from any reasonable college library.

    This might be a bit of overkill, as it is designed for irregular data sets (versus regular datasets - grids). However, the code can be separated into a separate Delaunay Triangulation step. If you have a grid (or in your case, a function f(x,y)), it is easy to generate fixed triangles.

    If anybody knows of a better algorithm, I'm all ears!!!

  • Why not OpenGL? (Score:3, Interesting)

    by SanityInAnarchy ( 655584 ) <ninja@slaphack.com> on Monday July 24, 2006 @12:54AM (#15767938) Journal
    I know this doesn't help you, but I'm still curious -- under what circumstances can you not use OpenGL for this? Under what circumstances would it be easier to implement it yourself than to find/create a decent GL binding? Or maybe you could just read the software implementation from Mesa?
  • R-project (Score:3, Insightful)

    by Anonymous Coward on Monday July 24, 2006 @01:01AM (#15767951)
    Check out the R-project at www.r-project.org. It is very good for that sort of thing.
    • Re:R-project (Score:3, Informative)

      by infolib ( 618234 )

      I'm out of mod points, but this is insightful. The R programming language [r-project.org] is GPL'ed and works on lin/win/osx (packages for major distros). It is an interpreted language (except for a few internal commands), and so the source code for the several different 3D plotters is included with the program. Some you might have to install yourself, but this can be done by the install.packages command.

      You might want to have a quick look at output from different 3D commands [ucl.ac.be] (persp, scatterplot3d and wireframe).

      The in

  • I wrote a program to do that in 1968, for a UNIVAC 1108 with a pen plotter. Even did hidden surface elimination. We even ran it on a display a few times during really slow periods. But I don't have the ALGOL code any more.

    The algorithm was in JACM around 1967, but you wouldn't do it that way today.

  • Basic Rundown (Score:5, Informative)

    by The boojum ( 70419 ) on Monday July 24, 2006 @01:10AM (#15767970)
    My advice would be to pick up a decent intro book on graphics. The Foley and Van Dam is a classic, but nearly any good book on the topic tends to have a review of the basic math involved in 3d: linear algebra with 3- or 4-value vectors and 3x3 or 4x4 matrices, the perspective divide, etc. Knowing the basics will help you have a lot better idea of what to do. But for anyone curious about the most basic 3d, here's a simple way to do it that should work decently for simple wireframe plots.

    1) Take each 3d point of interest and apply some set of rotations around the X, Y, and Z axis to get the view angle right. You'll probably want to just do one rotation around each axis. e.g.:

    x2 = x * cos( z_angle ) + y * sin( z_angle );
    y2 = x * -sin( z_angle ) + y * cos( z_angle );

    x3 = x2 * cos( y_angle ) + z * sin( y_angle );
    z2 = x2 * -sin( y_angle ) + z * cos( y_angle );

    y3 = y2 * cos( x_angle ) + z2 * sin( x_angle );
    z3 = y2 * -sin( x_angle ) + z2 * cos( x_angle );

    At this point, you'll have rotated your original coordinate (x,y,z) by some angle around some axis to get (x3,y3,z3)

    (To my fellow graphics geeks: yes, yes, I know full well that matrices and quaternions are better -- I'm trying keep this simple.)

    2) Maybe add some distance to the z value, to move ("translate") it away from the "camera" at the origin. You'll need to add enough to make sure that all of your z-values are positive and non-zero before step 3:

    z4 = z3 + z_translate

    3) Do what's called the "perspective divide" to find the two dimensional coordinate of this point. e.g.:

    px = x3 / z4 * scale + center_x;
    py = y3 / z4 * scale + center_y;

    4) Either plot a point at the (px,py) that you just got, or compute steps 1 and 2 twice for the end points of lines and then use your system's graphics primitives to draw lines between (px1,py1) and (px2,py2). If you're not using a language or a library that can do simple 2d graphics, then I'd suggest writing out a file with the lines in SVG format (and then rasterize to bitmap with a program like Batik, Inkscape, Illustrator, etc.) e.g.:

    <?xml version="1.0" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
    <svg width="4cm" height="4cm" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" version="1.1">
        <path d="M px1 py1 L px2 py2" fill="none" stroke="black" stroke-width="1" /> <!-- First line to draw -->
        <path d="M px1 py1 L px2 py2" fill="none" stroke="black" stroke-width="1" /> <!-- Second line to draw -->
        <path d="M px1 py1 L px2 py2" fill="none" stroke="black" stroke-width="1" /> <!-- Third line to draw, etc... -->

    5) If you want more than wireframe, things will be a lot more complicated. At the very least, you'll need to be able to fill polygons and sort back to front by the z-value after the rotation so that everything gets drawn in the correct order. Z-buffers would be even better.

    Well, I hope all that helps. Again, if anyone's really interested, I'd suggest getting a real book on the topic. But I hope this's enough to get the curious started.
    • Re:Basic Rundown (Score:4, Interesting)

      by Profane MuthaFucka ( 574406 ) <busheatskok@gmail.com> on Monday July 24, 2006 @01:27AM (#15767997) Homepage Journal
      Regarding point #2 and #3, if he's just plotting points to make a graph, fancy perspective may not be needed. Just throw away the Z coordinate after rotation, and plot the X and Y in 2D.

      Also, if you're rotating the graph in real-time, don't rotate the points a degree, plot, and rotate another degree and plot, and so on.

      Save the original set of points. Rotate them one degree and plot. Throw those results away, start with the original set and rotate them two degrees and plot. Repeat, rotating only the original set each time. You'll save a lot of trouble from accumulating floating point errors.
    • I take it that 3rd point is the equivalent of projecting 'the 3d' to the 2d plane of the monitor?
  • dim ymax(screenwidth),ymin(screenwidth)
    For xtemp = xlower to xupper step xincr
    for ytemp = ylower to yupper step yincr
    compute z=f(xtemp,ytemp)
    if yymax(x) then plot x,y : ymax(x) = y
    next ytemp, xtemp

    Adjust your viewpoint for your 3D to 2D matrix so it plots from front to back.

    Algorithm comes from an old book on doing 3D on an Apple ][ - it wasn't too hard to convert it to work on a TRS-80 Model I or a CoCo.
  • I just looked at the GNUPlot page, and regardless of what anyone else says, I don't think it should be too difficult to code at all, at least the grid stuff like near the top of that page. The reason - it's all drawn without perspective, which means a little vector math tells you where to put each point. You might be a bit foolish to try to hand-code something substantial with perspective, but orthogonal projections are straightforward.

    Here's what you need to do. First, figure out what a unit in the X
  • Read a book (Score:5, Informative)

    by jlarocco ( 851450 ) on Monday July 24, 2006 @02:42AM (#15768103) Homepage

    Hate to disappoint you, but you're probably not going to find a tutorial and code that conveniently meets your requirements. For starters, eliminating OpenGL and D3D is going to remove a large number of tutorials, simply because it doesn't make sense for most people to roll their own rendering code.

    Your best bet would be to look through "Computer Graphics: Principles and Practice" by Foley, van Dam, Feiner and Hughes. It covers a large number of topics, in enough detail to get a good idea of how to get started and where to look for more information. Also "Real-Time Rendering" by Tomas Möller and Eric Haines. Despite the name, a large portion of the book is applicable to almost all computer graphics, not just real-time. Also, a book on linear algebra would probably be helpful.

  • The actual code for such a plot, pixel cloud or such, is easy. 5-10 lines, nicely covered elsewhere in the comments already. Most difficulty lies in putting the first pixel on the screen, the right way.

    In times of Amiga, it would be like typing "ScreenOpen 320,256,32", then a line defining the palette in equally simple terms, then you can start the drawing stuff. On PCs there are dozens of graphics libraries and each one more difficult to use than another. Microsoft Visual someshit have this pretty
    • > Stay far away from QT, GTK and alikes. They are a true hell to draw arbitrary stuff

      There's a GTK+ add-on called "GTK Extra", which directly supports 2D and 3D plots. It was created as the infrastructure for SciGraphica.
      • But getting any program to run using GTK requires several hours of digging through tutorials. Drawing a 2D/3D plot even if you have access just to a single "put pixel" function, is easy. Getting from opening the C editor to first pixel correctly drawn a'la hello world in your program is the trick - using GTK the first time you do it is pure hell, if changing current drawing color consists of three lines of obscure invocations.
        Drawingarea is horrible. No idea about this GTK Extra but I seriously doubt if it'
  • As part of some final year course thing I wrote a 3D rendering engine in Java based on implicit surface rendering, I did it in two stages. The first was simply an engine that converted the surface equation (f(x) + f(y) + f(z) = whatever) and then plotted it everything into a spacial array then dumpped everything into java's 3d library for scaling and rotation. Then I knocked out the Java 3D API and replaced it with my own so that everything worked all the way back to java 1 with no extra libraries. It was G
  • The idea behind plotting z = f(x,y) is to sample the function on a grid of points (x,y). You then interpolate linearly between adjacent points to get a polygon. For example, if my grid contains (x,y) = {(0,0), (0,1), (1,0), (1,1)} then my polygon in 3-space has corners (0,0,f(0,0)), (0,1,f(0,1)), etc. Project this polygon onto the screen using the standard 3d transformations.

    There are a couple of things to watch out for. First, all polygons should be convex. This is usually not a problem, but you ca
    • Sorry, I forgot to mention how to get contours from your plot. Basically, you intersect planes (z=1, z=2, etc) with each polygon and draw all the resulting lines. To determine if a polygon intersects z=t, subtract t from all the z-values and see if you have both positive and negative signs. If not, then the polygon is entirely on one side of z=t and you don't get a line from it. You can speed this up by sorting the polygons by minimal z-value (among all the vertices), then breaking ties by maximal z-val
  • If its a very small part of a larger program, then look for some good examples and try to trudge through getting it to work. Otherwise, start writing code and examine the visual output of the screen. Look for algorithms and methods for producing the output you want. When you begin to understand them, you can integrate the concepts into your solution.

    Unfortunately, even if you have an API, you still have to understand what it does and how to interact with it. Many people believe that modular programming
  • by Anonymous Coward
    I actually understand your question and the first place to look is a book Statistics and Data Analysis in Geology" by Davis. I used it in graduate school back in the 80's. It has understandable code for generating this output. It starts with line printer plots to get you running, first with trend fitting the data, and then actually machine contouring the data. I used their examples to program my C64 do draw contour maps on the 1526 plotter. I have tried surface plots with Excel off and on and it is fru
  • One thng I can think of is for each Z value chosen, to make lines between adjacent points and test if any point on that line segment crosses that Z. It's pretty iterative but you'll get your point cloud. That's relatively straightforward, provided you have a fairly regular series of points.

    Another way was to use vector math, make a triangle between three terrain points and try to see if it intersects with your Z plane. Maybe ten years ago I made an algorithm that returns a line segment if there was such
  • Marching cubes (Score:2, Informative)

    by Hillman ( 137883 )
    You can use the marching cubes algorithm. You can go from a cloud of points to a 3d object that you can transform like you want. I think they use that in MRI imaging. I used the 2d version (marching squares) to optimize a metablob routine a long time ago.

    see: http://www.exaflop.org/docs/marchcubes/index.html [exaflop.org]
  • Generic Mapping Tool (Score:3, Interesting)

    by budgenator ( 254554 ) on Monday July 24, 2006 @11:09AM (#15769730) Journal
    Generic Mapping Tool, will do everything you want, and a lot you have not even thought of yet. GMT [hawaii.edu] produces postscript and encapsuleated postscript, so if you have a postscript viewer your good to go, runs on unix/linux, is GPL'd so there source code to analyse. There are lots of examples with generating scripts such as time-series collected along a track [hawaii.edu] or a 3D perspective, artificialy illuminated, greyscale image [hawaii.edu]; just reading and understanding the accompanying ducumentation should be good for college credit in cartography.
  • Basically, there are two issues:
    1. the 3d to 2d mapping from a viewpoint
    2. dealing with hidden points

    The 3d to 2d mapping is actually pretty easy, with a little Linear Algebra. If you don't know any, grab a Linear algebra textbook and read up on vectors, dot products, cross products, etc.

    You pick a viewpoint V = (x_v, y_v, z_v) and a direction vector D = (d_x, d_y, d_z) ( D is a unit vector, it's length should be 1). and an "up" vector U (which way is up, also a unit vector, perpendicular to D). Next we

  • The standard way of doing this is to use the Marching Cubes algorithm. Google it --> http://www.exaflop.org/docs/marchcubes/
  • Pardon me if I missed seeing a reference to the PLOT10 library in this discussion. Used to be THE lib for TEKTRONIX terminals (line perinter then color CRT) for graphics anything. Wrote some stuff for plots in C and fortran for data surfaces way back (Z80 CP/M, and later IBM PC), as it was ported as a general purpose lib, to graph on a flat bed pen plotter and CRT (Hercules monochrome graphics adapter). Also, I seem to recall a few geeks simulation Rubik's Cube and Enterprise (Dammit Jim, the Original Ser
    • We had some code here designed for Textronics _vector_ terminals (basically an oscilloscope modified to plot). When they surplused those in the early 80s I wanted to buy one - however the electric bill made it a non-starter.
  • You could look into Octave [gnu.org], which is an OS version of MATLAB released under GPL. You could either use it directly or look into the source for some helpful ideas.

"No, no, I don't mind being called the smartest man in the world. I just wish it wasn't this one." -- Adrian Veidt/Ozymandias, WATCHMEN