We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I am trying to make visualizations of common sorting algorithms using processing. I would like to be able to call the draw function after every step the algorithm takes, so that you can see everything as it happens. Here is an example of what i am trying to do with Insertion sort:
public void insertionSort()
{
for(int i = 0; i < arr.length; i++)
{
while(j > 0 && arr[j-1] > arr[j])
{
swap(arr, j, j-1);
j--;
draw();
}
j = i;
}
}
public void draw()
{
(draw everything)
}
I know for simpler sorts like selection and insertion sort you could make the sort work within the draw function itself, which i have done, but that wont work for sorts that use recursion like quick sort and merge sort (at least i cant think of how to get them to work). So basically, my question is is there any way to choose when the draw function executes so i can call it and have it update when i want? I have tried the redraw() function but that doesn't seem to be fast enough, and simply calling draw doesn't do anything either. I also tried running the sort in a separate thread, which sort of works but has some bad side effects with the screen glitching out.
Answers
You have to learn how draw works to use it to your advantage. Here is an example below.
https://processing.org/reference/draw_.html
Kf
draw() is also the animation clock for a Processing sketch (frameRate etc.) so what you probably want instead is an object that encapsulates a sort algorithm and its state, eg
BubbleSort bsort
Declare the object, then in draw call
bsort.next()
to advance the state, then draw the updated state to the screen usingbsort.arr
etc.Thanks for the responses guys. I actually figured out that i can in fact run the algorithm perfectly fine in separate thread as long as i delay long enough in between each step for the draw function clear and redraw everything. Don't know why i didn't try that the first time. Thanks for the help though.
Interesting! Willing to share a code example for that approach?
Sure! Here is the full sketch for the insertion sort animation:
@isaac328 -- thank you for sharing this use of
thread()
combined with reading global variables to render the current state of nested loops.I like that your approach can monitor sorting code as-is, from standard examples!
Here is a quick example of an alternate object-based approach which does not use
thread()
orThread
. This makes it easier to incorporate interactive control over changing the running speed, pausing, manually advancing, switching between algorithms etc. etc.A Sorter is a class. An InsertionSorter defines the step method for that class. Each call to
iSort.step()
advances the array to the next Insertion Sort state. You can create multiple sorters and multiple sort displays.Thinking about these approaches a bit more, I think that having multiple algorithms that each perform exactly the same number of steps (rather than being in racing threads) would be particularly useful if trying to do side-by-side comparison animations, as for example on this page:
No offence, but delaying 50 milliseconds for every step of the algorithm is kind of pointless to put it in a seperate thread.
@Lord_of_the_Galaxy -- looking back at this, I think there is one way that the thread approach has a real advantage for this kind of code. If you are using a lot of standard sorting algorithms, you can just "cut-paste" those algorithms into a threaded function that saves its state in global variables, add a delay, and animate from draw() -- no rewriting necessary. That is pretty convenient.
The class-based solution I shared as an alternative has many advantages -- starting / pausing / stopping, speed control, multiple objects, etc.... but it requires you to partly rewrite most algorithms to unwind them into a steps-with-states rather than nested loops.
Perhaps you may be right. But I guess that's just your personal preference.