Search code examples
cplotparticlesmathgl

Draw point by point 3D scatter plot with MathGL in C


I am building a particle simulation, and I want to display each particle's position as a dot in a 3D scatter plot using MathGL in C (not C++!). I am having trouble with the C interface.

So far I found two interesting examples:

  1. A C++ example that seems to be close to what I want: http://mathgl.sourceforge.net/doc_en/Dots-sample.html (but this is in C++, I have been unable to find the C-equivalent)

  2. This is a piece of C code that constructs a 3D surf plot with dots.

    #include <mgl2/mgl_cf.h>
    int main()
    {
            HMGL gr = mgl_create_graph(600,400);
    
            HMDT a,x,y;
            a = mgl_create_data_size(30,40,1);
            x = mgl_create_data_size(30,1,1);
            y = mgl_create_data_size(40,1,1);
            mgl_data_modify(a,"pi*(1-2*x)*exp(-4*y^2-4*(2*x-1)^2)",0);
            mgl_data_fill(x,-1.,1.,'x');
            mgl_data_fill(y,0.,1.,'x');
            mgl_rotate(gr,40.,60.,0.);
            mgl_set_light(gr,1);
            mgl_box(gr,1);
            mgl_surf_xy(gr,x,y,a,".","");
            mgl_delete_data(a);
            mgl_delete_data(y);
            mgl_delete_data(x);
    
            mgl_write_frame(gr,"test.png","");
            mgl_delete_graph(gr);
            return 0;
    }
    

The example 2 is close to what I want to do, but it is annoying that a is not a linear array of just N particles. It also has to take a function to evaluate the values for a (z-axis) whereas I just want to pass the z-coordinate manually for each dot).

My data is just a 1D array of structs, similar to this:

struct particle {
    double x, y, z, velocity;
};

How do I plot these particles as dots in a 3D (scatter) plot with MathGL in C? I guess I have to use mgl_dots, but how does it read from my array of values? (I could use velocity as color coding, but that is optional)


Solution

  • I was right about using mgl_dots, and the data can be prepared using mgl_create_data_sizeand mgl_data_put_val, e.g.:

    HMDT z,x,y;
    int N = 1000;
    x = mgl_create_data_size(N,1,1);
    z = mgl_create_data_size(N,1,1);
    y = mgl_create_data_size(N,1,1);
    
    for(int i=0; i < N; i++) {
            // Set position of particle[i]
            printf("%lf\n", i/(double) N);
            mgl_data_put_val(x, i/(double) N, i, 0, 0);
            mgl_data_put_val(y, i/(double) N, i, 0, 0);
            mgl_data_put_val(z, i/(double) N, i, 0, 0);
    }