0 votes

So my program draws beautiful geometrical structures that depend on many variables.
At the moment you can choose the value of those variables in the menu and enjoy the sight of one of those structures each time.

But I would like to add a new feature. A button that makes the use able to see how that structure changes over time by increasing the value of a variable each time it gets drawn For this I need to re-draw everything with the new variables.
What I mean is, I need to start with some values and draw the beautiful thing, then I need it to be undrawn and then to be able to draw another one again but with the value increased a little bit, so you can see how you can go from one figure to another.

I'll show you pictures to illustrate you:

enter image description here

For example, from the top one, to the bottom one. The first one has a value of 2/100 and the second one has a value of 17.6/100

enter image description here

Or from:

enter image description here

(25/100)

To:

enter image description here

(45/150)

So if you increase the first number bit by bit, you will be able to see the image transform from one to another.

I would need a way to undraw-redraw with changed values, to choose the rate of change and the speed that it changes, and a way to change the colors bit by bit like a rainbow.

Is there a way of doing any of these things?

asked 6 days ago in Engine by C:\\Flavius (45 points)

What's your method of drawing?

I just use drawpolyline and drawline
If that's not what you're asking, then idk what you mean by method

1 Answer

+1 vote

You know you could store the commands and parameter in an array.
For example: ['poly_line', [Vect...], Color.., 'draw_line', Vec.., Vec.., Color..]
That's drawpolyline with a Vector2 array and color, and then a regular line with three parameter after.

In the draw function you can then read this array using a match statement within a while loop.

var i = 0
while i < commands.size():
    match commands[i]:
        'poly_line':
            draw_poly_line(commands[i+1], commands[i+2])
            i += 3
        'draw_line':
            draw_line(commands[i+1], commands[i+2], commands[i+3])
            i += 4
         _: printer('Sry.. Unknown command at ' + str(i) + ' :(')

And you can add more to it.
So how does this help? Well now you can easily call a specified number of these commands. Simply by replacing commands.size() in the while loop with min('your_var', commands.size().
Any questions?

answered 5 days ago by SIsilicon (937 points)

That's a very interesting way of doing it. I think I wouldn't be able to come up with that by myself, at least not at this level of experience (this is my first public programme).
Have you come up with that or have you learnt it? If you learned it, can I know the book/person you learned it from?

And also, let me understand;

First of all, is match the same or similar to the switch command in C++?

Next, what is the min function and what does it do?

Also, the "_" at the end gets executed when i is not between 0 and commands.size()?

Even one more question, if commands[1] is an array, you could access the different values of that array by typing commands[1][x], or [1,x]?

I just really found this way of doing this very interesting and want to know everything about it.

So, with this code, I could go from the 0.1 figure to the .2 figure, to .3, and so on.
Wouldn't this draw the new shape over the old one, which would make it not look so good?
And how could I make this be able to change the speed at which it draws the new figure. For example make it either 30 fps, or 10 fps or so.

Thank you very much for you reply, have a great day!

Ok. exhales heavily
Here we go.

Have you come up with that or have you learnt it?

Came up with it right on the spot. Which also means it's prone to error so I'll be testing it as well.

First of all, is match the same or similar to the switch command in C++?

Indeed it is. With only a few differences.

Next, what is the min function and what does it do?

It does as its name implies. Returns the minimum of two of its parameters. In this case, your variable, and the size of the command array. Eg: min(1, 2) = 1; min(9, 7) = 7;

Also, the "_" at the end gets executed when i is not between 0 and commands.size()?

Nope. It is the equivalent of default in switch-case. Meaning that it is the only one that will match if none of the others match. So in this case, if the command does not match neither 'polyline' nor 'drawline' then it will match with _. And thus in our case again, print an error.

Even one more question, if commands[ 1] is an array, you could access the different values of that array by typing commands[ 1][x], or [1,x]?

The first one. [ 1][x]

Wouldn't this draw the new shape over the old one, which would make it not look so good?

Nope. All of this is inside the canvas item's override able _draw() function. It gets cleared every time it gets called(which is automatic so please don't call it yourself). However to get to draw something different, you not only change the variable; but you must also call update() every time the draw function changes in anyway. That includes the variables it uses.

And how could I make this be able to change the speed at which it draws the new figure. For example make it either 30 fps, or 10 fps or so.

By changing how much you increment 'your variable' by. Like increment it by 0.016 * 20 every frame.

Unfortunately though, my current code does not interpolate lines. Instead it does each command in its entirety. Going to have to use more brain power to figure that out ..

Thanks a lot for all this help!

One more question, why does it have to be multiplied by 20?

I'm playing with this right now, it seems it will work wonder.
So, correct me if I am wrong but the way this will work is that if, for example I choose my variable to be 0, and the increment to be 0.016 * 20, it will begin by drawing a simple circle (cause the first variable is 0) and then, the cardioid will slowly emerge. Right?
And if I want to stop it, can I just hit the "Return" button (one button I placed that gets you back to the main menu) or it will mess with the program?

Edit: I put all the variables and commands in an array, and used that code. Replaced commands.size() with min(0, commands.size());
So this way the first thing it draws is an empty circle, but it doesnt drawy anything.

Lol just realised before hitting Save Changes. i is not less then 0 so it doesn't draw anything. I don't know how to increment the variable, but I will figure it out. Omg I'm so noob

Edit2: changed the 0 to other number. It freezes, it doesn't get any error, it's just like it's in an infinite recursion.

Edit3:

This is what I did

var increment = 0.32

var i = 0
while i < commands.size():
    match commands[i]:
        'draw_circle':
            draw_circly(commands)
            i += 5
        'draw_epic':
            draw_epicicles(commands);
            commands[6] = commands[6] + increment;
            i += 5
        'restart':
            update();
            i = 0;
        _: print('Sry.. Unknown command at ' + str(i) + ' :(')

So in my mind, this should draw a circle, then draw the epicycloid (the figures shown in the screenshots), then increase the variable (number of epicycles, or NbOfEpicycles) with 0.32 (0.016 * 20) and then restart i so that it draws everything again.

But it freezes, you know, as if it was doing an infinite loop, which now that I think of it, it's doing so.
I just deleted the restart part, and it still freezes.

Where do I put the update thing?

Edit4: I've put the update() in many places, so yeah, I completely don't know where to place it without the program freezing

Update() shouldn't be called inside the draw function. Here's what you could do. Call it every time you change a variable used by the draw function.

Also I don't recommend passing the whole command array. Instead pass the parameters that come after the command. Which is why i is incremented by a certain amount depending on the command's number of parameters. So like if I had a command that had two parameters, then it would have two variables following the command in the array.

#Example
commands = ['my_func', 0.7, 6.8]
#my_func has two parameters. So it has two variables following it.
var i = 0
while i < commands.size():
    match commands[i]:
        'my_func':
                          #first parameter  second parameter
            my_func(commands[i+1], commands[i+2])
            i is incremented by number of parameters + 1
            i += 3

Also maybe you should allow to help me with your project more directly.
Like host it on github or somewhere. I could help more.

And I believe this is the only way I can help with that infinite freeze.

That would be great, but how do I host the project in github? I think I need the files of the project, but where can I find them?

Also, I will try again, doing what you told me.

Edit: I changed the whole 'commands' variable to just the parameters I will use.

Well, now it is 10 PM here so I'm gonna go eat something, and then I may go to sleep.

I will host my project on GitHub tomorrow, thank you very much for all this help!
Have a nice day

Goodnight. Its 3:30 PM here

...
Sooooo..
Did you get your project on github yet?

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.