Results 1 to 11 of 11

Thread: Fill area above baseline and below the curve

  1. #1
    Join Date
    Nov 2010
    Posts
    4
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Fill area above baseline and below the curve

    Hello. Is it possible to fill area above the baseline and below the curve (something like this)?

  2. #2
    Join Date
    Oct 2010
    Location
    Berlin, Germany
    Posts
    358
    Thanks
    18
    Thanked 68 Times in 66 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Fill area above baseline and below the curve

    have you tried QwtPlotCurve::setBrush() ?

  3. #3
    Join Date
    Nov 2010
    Posts
    4
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Fill area above baseline and below the curve

    Yes, but it fills whole area under the curve. Please, look at this image. It is exactly what I'm trying to achieve. This kind of fill is a requirement for seismic profile data visualization.

  4. #4
    Join Date
    Oct 2010
    Location
    Berlin, Germany
    Posts
    358
    Thanks
    18
    Thanked 68 Times in 66 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Fill area above baseline and below the curve

    no, setBrush() fills the area between the curve and the baseline. Have you set the CurveType to Xfy?

  5. #5
    Join Date
    Nov 2010
    Posts
    4
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Fill area above baseline and below the curve

    For example, sin() alternates from positive to negative and back again. Baseline is 0. With the brush set, the whole area between baseline and sin() values (both positive and negative) will be filled. I need only area between positive values and baseline to be filled. My code looks something like:
    Qt Code:
    1. class SimpleData : public QwtData
    2. {
    3. public:
    4. SimpleData(double (*f)(double), size_t size):
    5. d_size(size),
    6. d_f(f)
    7. {
    8. }
    9.  
    10. virtual QwtData *copy() const
    11. {
    12. return new SimpleData(*this);
    13. }
    14.  
    15. virtual size_t size() const
    16. {
    17. return d_size;
    18. }
    19.  
    20. virtual double x(size_t i) const
    21. {
    22. return d_f(y(i));
    23. }
    24.  
    25. virtual double y(size_t i) const
    26. {
    27. return 0.1 * i;
    28. }
    29.  
    30. private:
    31. size_t d_size;
    32. double (*d_f)(double);
    33. };
    34.  
    35. int
    36. main(int argc, char** argv)
    37. {
    38. QApplication application(argc, argv);
    39. QwtPlot plot;
    40.  
    41. plot.show();
    42.  
    43. QwtPlotCurve curve;
    44. SimpleData data(std::sin, 100);
    45.  
    46. curve.attach(&plot);
    47. curve.setBrush(QBrush(Qt::blue, Qt::SolidPattern));
    48. curve.setCurveType(QwtPlotCurve::Xfy);
    49. curve.setData(data);
    50.  
    51. return application.exec();
    52. }
    To copy to clipboard, switch view to plain text mode 
    Is overriding the QwtPlotCurve::drawCurve with extra curve style is the only way?

  6. #6
    Join Date
    Oct 2010
    Location
    Berlin, Germany
    Posts
    358
    Thanks
    18
    Thanked 68 Times in 66 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Fill area above baseline and below the curve

    ok, I understand the problem now. what about this (pseudocode):

    you have curve "c1". create a second curve "c2". set c2.yValues = c1.yValues and c2.xValue[i] = max(c1.xValue[i], baseline) - now you can add the brush to c2 and the area between baseline and higher values will be painted.

    I hope, you understand what I suggest...

  7. #7
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,241
    Thanked 860 Times in 809 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Fill area above baseline and below the curve

    Setting brush and baseline to your curve is almost what you need - beside clipping away the rectangle above your baseline before the curve is filled. But unfortunately QwtPlotCurve::fillCurve() is not virtual.

    So what you try do is something like this:

    Qt Code:
    1. virtual void YourCurve::drawLines(QPainter *painter,
    2. const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    3. int from, int to) const
    4. {
    5. painter->save();
    6.  
    7. painter->setClipRect(...);
    8.  
    9. const QPen pen = this->pen();
    10. setPen(Qt::transparent);
    11.  
    12. QwtPlotCurve::drawLines(painter, xMap, yMap, from, to);
    13.  
    14. setPen(pen);
    15.  
    16. painter->restore();
    17.  
    18. const QBrush brush = this->brush();
    19. setBrush(Qt::NoBrush);
    20.  
    21. QwtPlotCurve::drawLines(painter, xMap, yMap, from, to);
    22.  
    23. setBrush(brush);
    24. }
    To copy to clipboard, switch view to plain text mode 

    Uwe

  8. #8
    Join Date
    Nov 2010
    Posts
    4
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Fill area above baseline and below the curve

    Thanks. I've came to the following code, but it seems that I have to understand QPainter and it's logical coordinates (looks like it clips everything).
    Qt Code:
    1. virtual void
    2. drawCurve(QPainter *painter,
    3. int style,
    4. const QwtScaleMap &xMap,
    5. const QwtScaleMap &yMap,
    6. int from,
    7. int to) const
    8. {
    9. if (style < QwtPlotCurve::UserCurve) {
    10. QwtPlotCurve::drawCurve(painter, style, xMap, yMap, from, to);
    11. return;
    12. }
    13.  
    14. QPoint topLeft;
    15. QPoint bottomRight;
    16.  
    17. switch (curveType()) {
    18. case Xfy :
    19. topLeft.rx() = xMap.transform(baseline());
    20. topLeft.ry() = yMap.transform(y(from));
    21. bottomRight.rx() = xMap.transform(maxXValue());
    22. bottomRight.ry() = yMap.transform(y(to));
    23. break;
    24. case Yfx :
    25. topLeft.rx() = xMap.transform(x(from));
    26. topLeft.ry() = yMap.transform(baseline());
    27. bottomRight.rx() = xMap.transform(x(to));
    28. bottomRight.ry() = yMap.transform(maxYValue());
    29. break;
    30. }
    31.  
    32. painter->save();
    33.  
    34. painter->drawRect(QRect(topLeft, bottomRight)); // Draw clip rectangle
    35. painter->setClipRect(QRect(topLeft, bottomRight));
    36.  
    37. const QPen savedPen = painter->pen();
    38.  
    39. painter->setPen(Qt::transparent);
    40. QwtPlotCurve::drawLines(painter, xMap, yMap, from, to);
    41. painter->setPen(savedPen);
    42.  
    43. const QBrush savedBrush = painter->brush();
    44.  
    45. painter->setBrush(Qt::NoBrush);
    46. QwtPlotCurve::drawLines(painter, xMap, yMap, from, to);
    47. painter->setBrush(savedBrush);
    48.  
    49. painter->restore();
    50. }
    To copy to clipboard, switch view to plain text mode 

  9. #9
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,241
    Thanked 860 Times in 809 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Fill area above baseline and below the curve

    Your clip rectangle can be built from the baseline ( mapped into widget coordinates ) and the contents rect of the canvas - the coordinates of your curve are of no importance.

    As you don't have the canvas rectangle here you could also use any huge coordinate far outside like -100000 ( or 100000, when your y axis is inverted and you want to clip below the baseline ).

    Uwe

  10. #10
    Join Date
    Feb 2012
    Posts
    17
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Fill area above baseline and below the curve

    Hi Uwe,
    I have exactly the same problem as jarno: filling only the positive part of a curve, and leave transparent the negative part.
    You said in a previous reply of this post:
    Quote Originally Posted by Uwe View Post
    Setting brush and baseline to your curve is almost what you need - beside clipping away the rectangle above your baseline before the curve is filled. But unfortunately QwtPlotCurve::fillCurve() is not virtual.
    But I can see now that in qwt-6.0.1 fillCurve is "virtual", probably you made a change in one of the last versions.
    May I ask you to spend some words to explain to me which is the right way to use fillCurve() to achieve what I need?

    Thank you very much
    c


    Added after 22 minutes:


    Sorry, I asked Uwe, but obviously anyone has an answer will be very appreciated.
    c
    Last edited by chinalski; 28th February 2012 at 17:38.

  11. #11
    Join Date
    Feb 2012
    Posts
    17
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Fill area above baseline and below the curve

    Hi all,
    nobody answered to my question, probably because it was a trivial question, in any case I resolved my problem, and I'm writing just to close the thread and to post the solution, if anyone will have the same problem in the future.
    This is the code I used to define the member fillCurve of the virtual class QwtPlotCurve.
    Thank you, bye
    c

    Qt Code:
    1. void QwtPlotCurveAnteo::fillCurve(QPainter *painter,
    2. const QwtScaleMap &xMap,
    3. const QwtScaleMap &yMap,
    4. const QRectF & canvasRect,
    5. QPolygonF & polygon) const
    6. {
    7. painter->save();
    8. painter->setClipRect(xMap.transform(baseline()),0,100,1000,
    9. Qt::ReplaceClip);
    10.  
    11. QwtPlotCurve::fillCurve(painter, xMap, yMap, canvasRect, polygon);
    12.  
    13. painter->setClipRect(xMap.transform(baseline()),0,100,1000,
    14. Qt::NoClip);
    15. painter->restore();
    16.  
    17. return;
    18. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Replies: 5
    Last Post: 17th December 2014, 12:07
  2. Replies: 4
    Last Post: 29th April 2010, 06:11
  3. Replies: 1
    Last Post: 28th January 2010, 12:57
  4. Compute the area under a curve
    By giusepped in forum Qwt
    Replies: 0
    Last Post: 26th December 2008, 06:56
  5. Replies: 6
    Last Post: 18th December 2008, 21:16

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.