Discuss and collaborate on GML scripts

You are not logged in.

- Topics: Active | Unanswered

Pages: **1**

**NervaL928****Member**- From: France
- Registered: 2013-11-11
- Posts: 10

Hello everybody :)

I got a problem with something, that I thought solution was on this page : http://www.gmlscripts.com/script/drawing_shapes

I didn't find anything interesting for me...

Since you have LaTeX installed, let me use it :)

What I want to do is basically calling number of monomials a functions has, and then you call for all the monomial values... Like in this :

[tex]f(x) \to ax²+bx+c[/tex]

You have three monomials (this is a polynomial of degree two in fact).

Note : usually, we don't use complicated functions, like [tex]x \to x^{18}[/tex], but others like [tex]e^x[/tex] or [tex]\frac{1}{x}[/tex] are very useful...

So here, I call for every constant values (I have a problem : how can I ask every constant values until there are no more constants ?) :

```
a = get_integer("Enter a :","")
b = get_integer("Enter b :","")
c = get_integer("Enter c :",""
```

Now that I caught all the monomials values, how can I make the *Game* drawing C, the curve for the function the user entered ?

What I thought was using the room grid, but if it's not a first degree function (C is a line), it might be hard, right ?

Thanks for your replies, but if it's not possible don't matter, I'll try by myself, but note that I'm not posting this without having tried...

Offline

**xot****Administrator**- Registered: 2007-08-18
- Posts: 1,202

I'm not sure I totally understand the question but I'll do my best to answer.

If your polynomial is generic, it should be easy to translate to code.

[tex]P(x) = \sum^n_{i=0} p_i x^i[/tex]

The first thing to do is ask what degree the polynomial is.

`n = get_integer("Degree of polynomial?",2);`

Then ask for the coefficients.

```
var i;
for (i=0; i<=n; i+=1)
{
p[n-i] = get_integer("Enter "+chr(97+i)+" :", 0);
}
```

Then draw the curve.

```
draw_set_color(c_gray);
draw_line(320, 0, 320, 480);
draw_line(0, 240, 640, 240);
draw_set_color(c_black);
var i, xx, yy;
for (xx=-3.2; xx<=3.2; xx+=0.01)
{
yy = 0;
for (i=0; i<=n; i+=1)
{
yy = yy + p[i] * power(xx, i);
}
draw_point(100*xx+320, 100*yy+240);
}
```

*Abusing forum power since 1986.*

Offline

**NervaL928****Member**- From: France
- Registered: 2013-11-11
- Posts: 10

This is... AWESOME !

It works perfectly fine, thanks xot I'll credit you for this in my work !

Also, now that I have this, I think it's possible to get functions like [tex]\frac{1}{x}[/tex] or [tex]e^x[/tex] or [tex]\sqrt{x}[/tex] or [tex]ln(x)[/tex], right ?

And then, just a little thing more... Is it possible to have the curve without the points ? Or I mean, all the points ? Like, you don't have space between them ? If not, no matter, that's cool

Thanks again for your time, I looove this

Edit : for linking all the points, I changed "xx+=0,01" into "xx+=0,001" and it works fine :-)

Edit2 : the first monomial sign is glitchy... In fact, we get its opposed...

*Last edited by NervaL928 (2013-11-13 16:41:45)*

Offline

**xot****Administrator**- Registered: 2007-08-18
- Posts: 1,202

`for (xx=-3.2; xx<=3.2; xx+=0.01)`

You could increase the stepping value (`0.01`

) for fewer points. Obviously `xx=-3.2`

and `xx<=3.2`

select the range.

```
yy = 0;
for (i=0; i<=n; i+=1)
{
yy = yy + p[i] * power(xx, i);
}
```

This is the important part. You can get a point for any value of xx you wish.

**edit:** I see your edit now. You wanted a continuous curve. Reducing the stepping value works somewhat. Drawing a line from one point to the next is faster and won't have problems with very steep curves.

NervaL928 wrote:

Also, now that I have this, I think it's possible to get functions like [tex]\frac{1}{x}[/tex] or [tex]e^x[/tex] or [tex]\sqrt{x}[/tex] or [tex]ln(x)[/tex], right ?

As for the other functions, that's no longer a polynomial, so it's not really clear what you asking for. You could replace the second block of code with:

` yy = sqrt(xx);`

... or whatever function of xx you want.

**edit:** Don't know what you mean about the sign being glitchy. If you are expecting the results to match something elsewhere, like a book, remember that the GM screen has an inverted Y-axis, so curves will appear upside down compared to a traditional cartesian graph.

Replace:

`draw_point(100*xx+320, 100*yy+240);`

... with:

`draw_point(320+100*xx, 240-100*yy);`

... to correct that.

*Last edited by xot (2013-11-13 16:59:25)*

*Abusing forum power since 1986.*

Offline

**NervaL928****Member**- From: France
- Registered: 2013-11-11
- Posts: 10

NervaL928 wrote:Also, now that I have this, I think it's possible to get functions like [tex]\frac{1}{x}[/tex] or [tex]e^x[/tex] or [tex]\sqrt{x}[/tex] or [tex]ln(x)[/tex], right ?

As for the other functions, that's no longer a polynomial, so it's not really clear what you asking for. You could replace the second block of code with:

`yy = sqrt(xx);`

... or whatever function of xx you want.

Thanks ! This will do !

About the "glitchy signs", I meant you get this : [tex]ax^n+bx^{n-1}+cx^{n-2}+...+Nx^{n-n} \to -ax^n+bx^{n-1}+cx^{n-2}+...+Nx^{n-n}[/tex]

Edit : the "320+100*xx, 240-100*yy" replacement worked and fixed the problem, so thatnk you again, xot !

*Last edited by NervaL928 (2013-11-14 07:39:44)*

Offline

**xot****Administrator**- Registered: 2007-08-18
- Posts: 1,202

No glitchy signs, that's correct.

n is the degree of the polynomial. If the degree of the polynomial is 2, the three terms are:

[tex]ax^n \to ax^2[/tex]

[tex]bx^{n-1} \to bx^{2-1} \to bx^1 \to bx[/tex]

[tex]cx^{n-2} \to cx^{2-2} \to cx^0 \to c[/tex]

Altogether: [tex]ax^2+bx+c[/tex]

**edit:**

OK, I see what you meant. You said the sign of the first term is wrong, but what you were actually perceiving is the negation of the sum of all the terms. As you found, it was because the y-axis of the screen is reversed (positive is down, not up).

*Abusing forum power since 1986.*

Offline

**NervaL928****Member**- From: France
- Registered: 2013-11-11
- Posts: 10

Again, thank you, xot !

I'm now experimenting some troubles with it... I mean, I'm using it in my final project, but I have a problem with entering the window...

But anyway, my real problem is here : I don't really understand this part of the code :

```
1. var i, xx, yy;
2. for (xx=-3.2; xx<=3.2; xx+=0.001)
3. {
4. yy = 0;
5. for (i=0; i<=n; i+=1)
6. {
7. yy = yy + p[i] * power(xx, i);
8. }
9. draw_point(100*xx+320, 100*yy+240);
10. }
```

I know it's for drawing the points, but the lines 2 and 9 are quite strange for me... Why having xx=-3.2 ? And I don't understand the full command draw_point(100*xx+320, 100*yy+240);...

Offline

**xot****Administrator**- Registered: 2007-08-18
- Posts: 1,202

`for (xx=-3.2; xx<=3.2; xx+=0.001)`

The values are arbitrary. They are the selected range of the x-axis. You could use any portion of the x-axis you wanted.

`draw_point(100*xx+320, 100*yy+240);`

This scales and positions the graph. +320 and +240 position the origin (0,0) in the center of the display (assuming the display is 640 x 480). 100*xx and 100*yy scale the graph to fill the display, ie. 100*-3.2+320 = 0, the left edge of the display; 100*3.2+320 = 640, the right edge of the display. I scaled yy by the same amount as xx (100 times) but you don't have to.

If you are making something like a graphing calculator, ideally, you would want to fit the graph to the display automatically.

For the x-axis, if "x0" was the first point on the graph and "x1" was the last point on the graph, and "width" was the width of the display, you could compute the screen position for any "xx" value with "drawx = width * (xx - x0) / (x1 - x0)".

For the y-axis, it might be more complicated. To make sure the entire curve fits on the screen, you could compute all the points on the curve and save the highest ("y1") and lowest ("y0") values of "yy". You can then use the same basic formula as above to draw the computed points, fitting it to the height of the display with "drawy = height * (yy - y0) / (y1 -y0)". That will draw the graph upside-down like before, so you may want to flip the y-axis. Changing "(yy - y0)" to "(y0 - yy)" is the simplest way to do that.

Those formulas can also aid you in positioning the axes or a grid correctly.

*Abusing forum power since 1986.*

Offline

**NervaL928****Member**- From: France
- Registered: 2013-11-11
- Posts: 10

Thank you again !

Yes, Imma change the room size : I'm using 800x592.

And of course, the noob that I am is gonna ask you : where to put those two lines {drawx = width * (xx - x0) / (x1 - x0); drawy = height * (y0 - yy) / (y1 -y0)} ?

And also, when you mean width and heigth in your formulas, do you mean room_width and room_height ?

Offline

**xot****Administrator**- Registered: 2007-08-18
- Posts: 1,202

Yes, width and height are the display size or room size.

You put those formulas right before the draw code, which should now be `draw_point(drawx,drawy)`

.

*Abusing forum power since 1986.*

Offline

Pages: **1**