Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2014-09

Fastest way of drawing 2D graphs

7 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Hunter1972

Hello,
I am new in FPC and want to understand the correct(fastest) methods when drawing 2D graphics. The task is simple but extensive: to draw about 200 polylines with 50000-200000 points in each. I have made a test code in OnPaint event:

...
type
  TSingleArray = array of single;
  TIntArray = array of integer;
  TIntArrayArray = array of TIntArray;
procedure TForm1.FormPaint(Sender: TObject);
var
  cb, cb2, iShift: integer;
  Times: TSingleArray;
  FileDetections: TIntArrayArray;
begin
  canvas.Pen.Color:=clBlue;
  for cb := 0 to High(FileDetections) do
  begin
    iShift := round(Self.Height - cb * Self.Height / High(FileDetections));
    canvas.MoveTo(0, iShift);
    for cb2 := 0 to High(FileDetections[cb]) do
      canvas.LineTo(round(Times[cb2] * Width/15), round(FileDetections[cb, cb2]/20) + iShift);
  end;
end;
...

It works fine (png is attached).

Then I'd like to add some actions to the graphics: 1)Scaling around some point (by mouse wheel), actually magnifying 2)Moving this scaled point quickly to another part of graphics( using scroll bars?)

The main question is:
1)How to correctly organize this drawing that it'll take a lot of time only once before the first display? Later actions (scaling and moving) should be as fast as possible provided that points array (Times and FileDetections) are not changed.

Ravil

Reply by email

Martin Schreiber
to Hunter1972
Hello, I am new in FPC and want to understand the correct(fastest) methods when drawing 2D graphics. The task is simple but extensive: to draw about 200 polylines with 50000-200000 points in each.

MSEgui txychartedit supports it. An example is the MSEspice application: http://sourceforge.net/projects/mseuniverse/
Another option is Lazarus TChart.
40'000'000 datapoints probably is too much and needs to be compressed before plotting.

Martin

Reply by email

Michael Schnell
to Hunter1972: I am new in FPC and want to understand the correct(fastest) methods when drawing 2D…
Then I'd like to add some actions to the graphics: 1)Scaling around some point (by mouse wheel), actually magnifying 2)Moving this scaled point quickly to another part of graphics( using scroll bars?)

I once did "zooming and panning" of pixel graphics using SDL. Worked nicely.

For your project supposedly having the graphic card construct the visible part of the polygons in realtime seems more appropriate. I suppose this can be done by SDL, as well.

(SDL is a user friendly layer between the application and either of DirectView or OpenGL.)

-Michael

Reply by email

Marco van de Voort
to Hunter1972: I am new in FPC and want to understand the correct(fastest) methods when drawing 2D…

In our previous episode, Hunter1972 said:

I am new in FPC and want to understand the correct(fastest) methods when drawing 2D graphics. The task is simple but extensive: to draw about 200 polylines with 50000-200000 points in each. I have made a test code in OnPaint event:

OpenGL is an option here. Basically you upload a bunch of vertices and draw them. I do so with the overlay of vision algorithms over the camera image.

Still, even then, the number of points is excessive. Specially when it also must work on integrated graphics. Uploading it to the graphic card of the points alone is costly.

Also programmingwise, this is the most effort, and thus not for the faint of heart.

Show quoted text 5 lines
It works fine (png is attached). Then I'd like to add some actions to the graphics: 1)Scaling around some point (by mouse wheel), actually magnifying 2)Moving this scaled point quickly to another part of graphics( using scroll bars?)

This is cheap in opengl, and was my main motivation to start that non-trivial project. A repaint of already uploaded data is sub-ms and lightning fast.

Only uploading of data takes time (burst rates on external GPU are in the 1-2ms/MB magnitude, less in the integrated case. Basically you can upload a few MB till it stalls)

The main question is: 1)How to correctly organize this drawing that it'll take a lot of time only once before the first display? Later actions (scaling and moving) should be as fast as possible provided that points array (Times and FileDetections) are not changed.

I assume your polylines are basically an array of X,Y coordinates in single precision + color information? If you supply examples of those, I'll see if I can hack something together. (binary only, since it is a work codebase, more to get you an idea of how workable it would be)

What I currently don't have is autoscale, but that can be easily hacked in by calculating min and max of x and y, and dividing all coordinates by max-min.

My guess I can get it to show sub 100ms, with changing viewport (scaling etc) sub ms.

Reply by email

Hunter1972
to Marco van de Voort
Show quoted text 8 lines
...SDL... -Michael ..... MSEgui txychartedit Another option is Lazarus TChart. ..... Martin

I will check what these libraries can do and how fast.

> I assume your polylines are basically an array of X,Y coordinates in single precision + color information? If you supply examples of those, I'll see if I can hack something together. (binary only, since it is a work codebase, more to get you an idea of how workable it would be)

Ok, I will describe the task in details (test code with sample data file is here: https://yadi.sk/d/ET9fp8AobSfXy). Sample file is CSV(Excel) where the first line is data field names, the first column is time, the other are detection values. Time (X coord) is float in seconds but actual time step is always 250 microseconds (0,00025 sec) precisely. Detections (Y coord) are always integers.
There are 4-26 antennas, with 26 detectors each working on 4000 Hz, so one second at maximum can give 26*26*4000=~2,7 millions points. The detections can be of 1 minute length, 2,7 * 60(secs) = around 150 millions points. Each line represents detections from one detector. I need to show them schematically but with enough precision that you are able to see where the detections amplitude is above average. Then you should have the possibility:
1)To select the interesting time interval and program should show the data of this interval. If the scaling was not enough you can narrow the interval again and again. Scaling can go up to show distinct points (e.g. 10 ms interval). 2)To select the second time interval (independent from the first one) with the same scale of the previous one and visually compare data on both intervals.

Actually there are several waves launched in different times, with different initial amplitudes, so you should be able to estimate approximately how they dissipate, change their fronts and phases. The task can be widened later, for example, to show two files simultaneously (one is actual data points, the second - splined approximation) to understand how good the approximation was done. Color can be applied to detection areas where the lines have the same phase.

I know it's not en easy task but at first my program should be able to: 1)Show the whole file data
2)Show the data of some interval
3)Move this interval to another part

Ravil

Reply by email

Graeme Geldenhuys
to Hunter1972
I will check what these libraries can do and how fast.

You can also take a is a very good 2D vector graphics engine and loads of example apps that show scaling and panning. A copy can be found in the fpGUI or Lazarus code repository. The one included with fpGUI has a bit more bug fixes though.

Ok, I will describe the task in details (test code with sample data ...snip... maximum can give 26*26*4000=~2,7 millions points. The detections can be of 1 minute length, 2,7 * 60(secs) = around 150 millions points.

The way I would program that is to not use ALL data points on the "zoomed out" / overview graph. Instead divide it into equal sample points that still gives you reasonable accuracy. When you select a range and zoom in, use that range of data points (from the origin 150 mil), but again divide the range equally in sample points and pick sample data. The further you zoom in, the more data points you will use - thus keeping accuracy.

I hope I explained that so you understand.

Regards,
Graeme

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Marco van de Voort
to Hunter1972: I will check what these libraries can do and how fast. Ok, I will describe the task in…

In our previous episode, Hunter1972 said:

Show quoted text 8 lines
> > I assume your polylines are basically an array of X,Y coordinates in single > precision + color information? If you supply examples of those, I'll see if > I can hack something together. (binary only, since it is a work codebase, > more to get you an idea of how workable it would be) Ok, I will describe the task in details (test code with sample data file is here: https://yadi.sk/d/ET9fp8AobSfXy). Sample file is CSV(Excel) where the first line is data field names, the first column is time, the other are detection values. Time (X coord) is float in seconds but actual time step is always 250 microseconds (0,00025 sec) precisely. Detections (Y coord) are always integers.

http://www.stack.nl/~marcov/viewlotsofdata.zip

This is a Delphi (XE3) binary, but older versions of this codebase ran fine under Lazarus. The opengl code was originally done by Ales Kantona for our company.

It requires opengl3 and nonpower2 textures, and the upload will be slower on integrated gfx, but if those are new enough (anything i3/i5/i7 and HD4500+ should work)

I hope it works, I had some problem with the CSV loading code that wasn't aware of decimal separators. Press "load" to load, then draw to draw.

Then clicking in the picture centers, and the top slider (or + and - buttons) zoom. ( from -64 to +64 magnification).
My zoom system is a bit specialized, so I hacked this in quickly. Not very elegant, but this is just a demo.

I map the whole shebang on a 4096*4096 coordinate system, but this is floating point.

On my I7-3770 I had the following timings:

load took 945.9 ms (the CSV loading with your routines in Unicode delphi, probably slower than lazarus)
canvas prepare took 222.8 ms ( the new draw routine) upload to card took 334.8 ms (uploading to the GPU)

drawing/panning/zooming is not timed, but probably negible.

Total time +/- 45min.

Reply by email