• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GML Making mathematical graphs

S

Sosryet

Guest
Hi there, I am using Game Maker 8.0 pro to build an evolution simulator. What I need to do now, is to write a script that could draw a cartesian graph (X-Y) from a table of values that are stored in a grid. It would be like turning the following into a continuous line on the screen:

x y
1 10
2 20
3 30
...

Bare in mind that number of entries in the grid is variable and that it could have from very few x-y pairs up to 2000.

The axis and the scale is not a problem (at least for now...) It's the line that I don't know how to do.

What would be the best aproach for this?
 

roozilla

Member
Broad answer to get you thinking about it: Your room or view you are drawing the graph to would be similar to a piece of graph paper in that it itself has an x and y grid. So youd need to make some conversions of where your point's actual x and y coordinates would be on the graph(room) depending on scaling. Youd draw your line using one of game makers built in line functions. You could also store the points and their converted values(in relation to where you draw your grid) in a list or something
 

chamaeleon

Member
Hi there, I am using Game Maker 8.0 pro to build an evolution simulator. What I need to do now, is to write a script that could draw a cartesian graph (X-Y) from a table of values that are stored in a grid. It would be like turning the following into a continuous line on the screen:

x y
1 10
2 20
3 30
...

Bare in mind that number of entries in the grid is variable and that it could have from very few x-y pairs up to 2000.

The axis and the scale is not a problem (at least for now...) It's the line that I don't know how to do.

What would be the best aproach for this?
Maybe you can start with and adapt
Code:
for (var i = 0; i < ds_grid_width(pts)-1; i++)
{
    x1 = ds_grid_get(pts, i, 0);
    y1 = ds_grid_get(pts, i, 1);
    x2 = ds_grid_get(pts, i+1, 0);
    y2 = ds_grid_get(pts, i+1, 1);
    draw_line_width_color(x1, y1, x2, y2, 4, c_white, c_white);
}
 
Last edited:

NightFrost

Member
Did GM8 have surfaces? If so, and your set is static (values don't change and their amount doesn't change) you could draw_line as suggested above but to a surface, and display that. Saves you the strain of drawing a bunch of lines every step.
 

GMWolf

aka fel666
Did GM8 have surfaces? If so, and your set is static (values don't change and their amount doesn't change) you could draw_line as suggested above but to a surface, and display that. Saves you the strain of drawing a bunch of lines every step.
im not sure this is such a great idea:
although it does mean reducing number of draw calls, a surface means having that many more pixels to read from and write to.
indvidual lines are not only easier to implement, but wont have much impact on performance either.
 
The good thing about putting your graph on a surface with a projection applied to it is that you can control the size of the graph easily without having to use a bunch of gml to convert from one coordinate system to another.
 
S

Sosryet

Guest
Maybe you can start with and adapt
Code:
for (var i = 0; i < ds_grid_width(pts)-1; i++)
{
    x1 = ds_grid_get(pts, i, 0);
    y1 = ds_grid_get(pts, i, 1);
    x2 = ds_grid_get(pts, i+1, 0);
    y2 = ds_grid_get(pts, i+1, 1);
    draw_line_width_color(x1, y1, x2, y2, 4, c_white, c_white);
}

Thanks for all this information.

roozilla: Yes, that was what I was thinking.

chamaeleon: your code is a good place to start, but won't that make the line jagged? Is there a way to make it more smooth?

NightFrost, GMWolf and flyingsaucerinvasion: I will look into that and test what would work best considering the amount of dots requiered.
 
D

dannyjenn

Guest
I notice in your example, all the points fall nicely on a straight line. I'm guessing it won't always be like that?

If you don't mind the line being jagged, it's pretty simple: just loop through all the points and call draw_line()

If you want a flowy curve, it's way more difficult. I myself don't even know how you'd go about doing that. You'd probably need to come up with some sort of algorithm, using the limited data you have available, to interpolate all the y values for every possible x value, and then loop through everything using draw_point()
 

Alexx

Member
One way for a curved line, add the points to path, set it as curved and draw it. Don't know if this would be accurate enough though.
 

chamaeleon

Member
your code is a good place to start, but won't that make the line jagged? Is there a way to make it more smooth?
No, that is impossible. Or perhaps more correct, sure it's possible to make a smooth curve. Just dig in and read up on some math for, say, Bezier curves, or just google for gamemaker and bezier and see what other people have done before you.
 

GMWolf

aka fel666
your code is a good place to start, but won't that make the line jagged? Is there a way to make it more smooth?
a quick cheat is to use GameMaker paths and set them to smooth. then use draw_path (or custom function) to draw it.
however I think GM paths are stange and wont actually go through the points themselves.
as mentioned by @chamaeleon , you coukd write a custom spline rendere that uses bezier curves.
 
Top