Firstly I describe my C# program.
I have kept the description as brief as possible, but have hopefully provided sufficient context for my questions.
My questions appear the the bottom of my post.
I define a struct called ColourPoint:
public struct ColourPoint
public Point point;
public Color colour;
public ColourPoint(Point point, Color colour)
this.point = point; this.colour = colour;
I define a List of ColourPoints:
An integer is defined that is the max number of iterations in the loop described in the next paragraph:
I have a background worker process containing a loop that calculates the points, and adds them to the ColourPoint list. The loop iterates roughly 300000 times and it adds one ColourPoint to the list per iteration. The loop takes about 30 seconds to complete. Once the loop is completed no further calculations of points are made and no extra points are added to the list, unless there is specific user input.
At any point in time, the user can press a button that allows them to enter in new arguments for the calculation of points. If the user does this, then the background worker process is cancelled, the ColourPoint list is re-initialised to an empty list, and then the background worker process is restarted to start the calculations with the new arguments.
The animation of the ColourPoint list can be described as follows:
1) The start frame of the animation is a blank graph.
2) The last frame of the animation is all of the points plotted on the graph.
3) Each step of the animation should plot the next point (or group of points) from the list on to the graph.
By group of points I mean for example, plotting 1000 points per animation step.
I use the following to implement the animation:
int TRACKBAR_PIXEL_COUNT_DIVISOR = 1000;
They are initialised as follows:
trackBarAnimation.Minimum = 0;
trackBarAnimation.Maximum = maxPixels / TRACKBAR_PIXEL_COUNT_DIVISOR;
playing = false;
timerAnimation.Interval = 500;
timerAnimation.Enabled = true;
The button changes the value of the playing boolean.
The timer ticks every 500ms and executes the following:
It disables itself, it checks if playing is set to true and if it is it triggers the opengl control's paint event by calling its Refresh() method. The timer is re-enabled at the bottom of the paint event.
To illustrate what I do within the paint event I have pasted the code here:
private void openGlPlotWindow_Paint(object sender, PaintEventArgs e)
int startPixel = (int)(trackBarPixels.Value * TRACKBAR_PIXEL_COUNT_DIVISOR);
int endPixel = (int)((trackBarPixels.Value + 1) * TRACKBAR_PIXEL_COUNT_DIVISOR);
if (Playing && endPixel < colourPointList.Count)
for (int i = startPixel; i < endPixel; i++)
Color colour = colourPointList[i].colour;
Point point = colourPointList[i].point;
Gl.glColor3f((float)colour.R / 255f, (float)colour.G / 255f, (float)colour.B / 255f);
trackBarPixels.Value += 1;
timerAnimation.Enabled = true;
My implementation works, but I am unsure how to implement the following:
If the user moves the track bar then the graph should be painted appropriately.
For example, if the animation has currently plotted 100000 points and then the user moves the track bar slide and the slide points to the value representing 50000 points, then the graph should change to a plot of the first 50000 points.
In other words the user should be able to scroll to any point of the animation, provided that that part of the animation has been calculated of course.
I am also quite sure that the current way I have implemented the animation / painting of the graph is not best practice and is definitely not very efficient and would love for someone to point out to me how it should be done.
Additionally I would like the user to be able to zoom in on the image. I sort of know how to do this, but am pretty sure that it wouldnt work with my current paint event due to the fact that I am not clearing the window.
Please ask if you would like me to provide any more information.