Using Qt To Draw the Graph of Sin(x) - qt

I'm experimenting with ways to draw a sinusoidal graph.
My widget is only expecting to get passed in a few arbitrary data points. I have to fit these data points to a sinusoidal line curve:
So far, I've tried a few methods using QPainterPath.
QPainterPath::lineTo - I tried using this function to plot the curve by taking my data points and creating so many points BETWEEN them, that the line actually smooths out a bit. This is a little too computationally intensive though, I feel.
QPainterPath::cubicTo - From what I gathered from RTFM, this is the best way to go. The only problem is that I'm not sure how to plot my control points at spots where it will consistently and programmatically smooth out the curve the way I want it to. I was unable to get the desired result with this function.
After some googling, I came across a few forum posts that were using Qwt for curve plotting. It would be great if I could use Qwt, but it's not an option since I'm restricted to only using Qt.
Does anyone have helpful feedback/suggestions?

I am doing a very similar thing currently with painting the bode sweep of a parametric EQ (a long line with multiple sweeping curves). The way I'm doing it (pseudo style):
qreal yCoords[GRAPH_WIDTH];
...
QPainter Painter(this);
Painter.setRenderHint(QPainter::Antialiasing, true);
//Painter.setRenderHint(QPainter::HighQualityAntialiasing, true); //opengl specific
for(int xCoord = 0; xCoord < GRAPH_WIDTH; x++)
Path.lineTo(QPointF(xCoord, yCoord[xCoord]));
...
Painter.drawPath(Path);
The combination of the calls to setRenderHint and drawing lines with QPointF (i.e. two qreal) rather than QPoint (two int) makes the line very smooth.
We're using this on an SBC running Ubuntu and getting redraw timings (including all of the complex math to get the points in the first place) of ~80ms for a 600x300px graph. Initial tests show that enabling opengl rendering reduces this to ~8ms (clearly the processor intensive task is the painting with antialiasing), so if you can do that, I think this solution will work for you.

QCustomPlot is a free and easy to use class that can be found online. It may be better for what you are looking to do.

Related

Implementing sliding realtime 2D plot in Qt

I am getting streaming measurement data from an ultrasonic device moving inside a pipeline, and I want to make a sliding/realtime plot of these measurements. The Y axis would represent a gradient of the 360 degrees around the pipe, and the X axis would represent the length-wise position in millimeters. In other words, the X axis will update and move at the same rate as the scanner while new data is arriving (approx 40Hz). The value at each (x,y) coordinate represents one measurement, which should be mapped to a color in a colormap.
I am new to graphics (systems&backend guy) and I have been looking at QImage, QWT and QCustomPlot but none of them seem to straight-forward solve the problem without having to manually build a 2D matrix, draw it in a QImage, and update and shift the coordinates of each datapoint and redraw to move/scroll it. QCustomplot does this very nicely for graphs, but I don't see how it can be applied to their colormaps.
Any hints to frameworks or packages that provide primitives (or widgets) for this kind of plot would be much welcomed.
This can be done with Qwt. The trick is creating a wrapper around the series data that triggers a replot every time you add a data point. If you want to get fancy you can add a timer that removes old data from the series and triggers another replot.
See the CPU, oscilloscope, and realtime examples that come with the Qwt source code. They implement this trick.

How many lines can Qt draw on-screen?

I am currently working on a Qt application to draw maps. I am trying to draw 400,000+ lines and it crashes after using ~2GB but I still have memory left on my machine. I am wondering if I am hitting some limit inside of Qt that is causing the problem. Anyone know if there is a limit to the number of things you can draw or if you can change this limit?
If it is helpful, I am coding in C++ with a class that has a member function to draw the lines. The code is roughly as follows
QPointF fromPoint;
QPointF toPoint;
fromPoint = foo( x );
toPoint = foo( y );
m_Painter.drawLine(fromPoint, toPoint );
//m_Painter is a QPainter
Edit: Turns out the problem was somewhere else in the code. It had to do with the custom caching that was being done. Though I am still interested if there is a limit to how many lines Qt can draw. Does anyone know?
QPainter executes its underlying graphics through QPaintEngine, which has several implementations (like qpaintengine_mac.cpp, qpaintengine_x11.cpp, or qpaintengine_preview.cpp).
Some devices are raster...and are likely drawing each line into an image buffer and throwing away the endpoints after that drawing is done. There should be no limit to the number of lines you can draw in that case.
If the target device is OpenGL, or to a printer that is doing some kind of PostScript-like output, then the limitations of that particular paint engine may well be a factor. You'd have to look at the specific one.
For example: if you trace down the X11 implementation of drawLine you'll see it passes through to drawPolygon() down through strokePolygon_dev()...and bottoms out at a call to XDrawLines:
XDrawLines(dpy, hd, gc, pts, numberPoints, CoordModeOrigin);
So there you have another abstraction layer...and so the question becomes whether the XWindows display parameter is guaranteed to be raster. (My guess would be that it is.)
Anyway, so the answer is "unlimited if raster. may depend otherwise--but the limitations (if any) are probably coming from the underlying device for the paint engine, not Qt."

Constrained (Delaunay) Triangulation

For a university project I need to implement a computer graphics paper that has been relased a couple of years ago. At one point, I need to triangulate the results I get from my simulation. I guess its easier to explain what I need looking at a picture contained within the paper:
Let's say I already have got all the information it takes to reconstruct the contour lines that you can see in the second thumbnail. Using those I need to do some triangulation using those siluettes as constrains. I have searched the internet for triangulation libraries like CGAL, VTK, Triangle, Triangle++, ... but I always ended up throwing my hands up in horror. I am not a good programmer and it seems impossible to me to get into one of those APIs before the deadline of this project passes.
I would appreciate any kind of help like code snipplets, tips, etc...
I know that the algorithms need segments (pairs of points) as input, so let's say I have got one std::vector containing all pairs of points defining the siluette as well as the left and right side of the rectangle.
Can you somehow give me a code snipplet for i.e. CGAL that I could use for my purpose? First of all I just want to achieve the state of the third thumbnail. Lateron I will have to do some displacement within the "cracks" and finally write the information into a VBO for OpenGL rendering.
I have started working it out with CGAL. One simple problem still drives me crazy:
It is possible to attach informations (like ints) to points before adding them up to the triangulator object. I do this since I need on the one hand an int-flag that I use lateron to define my texture coordinates and on the other hand an index which I use so that I can create a indexed VBO.
http://doc.cgal.org/latest/Triangulation_2/Triangulation_2_2info_insert_with_pair_iterator_2_8cpp-example.html
But instead of points I only want to insert constraint-edges. If I insert both CGAL returns strange results since points have been fed into two times (once as point and once as point of a constrained edge).
http://doc.cgal.org/latest/Triangulation_2/Triangulation_2_2constrained_8cpp-example.html
Is it possible to connect in the same way as with points information to "Constraints" so that I can only use this function cdt.insert_constraint( Point(j,0), Point(j,6)); before I iterate over the resulting faces?
Lateron when I loop over the triangles I need some way to access the int-flags that I defined before. Like this but not on acutal points but the "ends" defined by the constraint edges:
for(CDT::Finite_faces_iterator fit = m_cdt.finite_faces_begin(); fit != m_cdt.finite_faces_end(); ++fit, ++k) {
int j = k*3;
for(int i=0; i < 3; i++) {
indices[j+i] = fit->vertex(i)->info().first;
}
}

How can I transform my canvas in PlayN?

Application screenshot: http://i.imgur.com/0uVKZiL.png
Source file: http://pastie.org/private/rcgm6o7qso8y0vz8nfjn0w
My application draws curves and I would like to be able to zoom in and out. When I apply a scale and translate transformation, the mapCanvasImage.canvas().gfx.transform changes accordingly, but nothing changes on the screen.
I used to have a different render approach (source code) in which the transformation did work, but there I could not get the layer to clear after each paint (results from previous paint iterations were still visible).
Perhaps (or likely) I am doing something fundamentally wrong. :) Any advice?
The Canvas offers nice high-level functions to draw Bézier curves, but is apparently flawed. My current plan is to abandon the Canvas and write my own code to convert Bézier curves to line segments. This is really easy and gives the added benefit of using less CPU power, since the Canvas is not hardware accelerated.

Smoothing a 3 dimensional Euclidean space matrix

I have a general question about what method to use for smoothing a 3D (xyz) grid.
My program has large matrixes of 3D points obtained with a stereovision method. The shape of the result is always something like a semisphere, but it has a rugosity due to stereovision errors I want to eliminate.
The question is, how to do it? Rigth now I have half developed a method for soomthing, but I think there may be a better method.
My actual idea is to use Hermite method. The idea is to:
Take all XY and smooth in two directions ->XYnew and XnewY
Convert the Hermite lines into Bezier lines and find the cross point between XYnew and XnewY, having the new point. (Repeat with all points, normally 2000)
Use hermite XYZ smoothing having XYZnew.
Rigth now I have the hermite surface smoothing and hermite line smoothing inplemented in C++, but the middle part is not as easy as espected.
Anyway, my question is, is this a correct method or is there another one which may be better?
Of course the idea is to elliminate the error generated by the stereovision method, this is not a computer graphics problem, is more a data treatment problem
Appendix:
At first I thougth that with a Z smoothing would be suficient, but clearly it is not, there is also a lot of XY error. In the images below you can see the Z fitting working but still it is really rugous as it can be seen in the 2 image. (The colours are deformations and shoul be quite continous)
Unless you have better priors, it's hard to beat the classic Taubin's algorithm: http://mesh.brown.edu/taubin/pdfs/taubin-iccv95a.pdf

Resources