Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QQuickPaintedItem rotation causing aliasing
Forum Updated to NodeBB v4.3 + New Features

QQuickPaintedItem rotation causing aliasing

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
8 Posts 2 Posters 1.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Offline
    Z Offline
    zhannum
    wrote on last edited by zhannum
    #1

    Hi,

    I'm working on implementing a custom round rectangle using QQuickPaintedItem so that I can change each corner radii independently and I'm running into an issue with rotating the object. Antialiasing seems to be working properly when the object is painted, but when I rotate the object via QML, aliasing appears along the diagonal edges of the rectangle. I can "hack" a fix to this by increasing the item's height and width and draw the rectangle inside the bounds of the item, but this solution requires a lot of hacky code.

    No rotation:
    0_1556128698190_3facc8f2-f09e-45d6-8877-0c64b44cf0c1-image.png

    Rotation with jaggies:
    0_1556128722708_7752b931-b8a9-4f07-9cc7-61919f2a64d7-image.png

    Here's my paint method:

        double buffer = 0; //Used to draw inside the item instead of on the edges
    
        if(tilt())
        {
            buffer += 1;
        }
        //start
        path.moveTo(width() - topRightRadius() - buffer, buffer);
    
        //Top horizontal
        path.lineTo(topLeftRadius() + buffer, buffer);
    
        //Top left radius
        path.arcTo(buffer, buffer, topLeftRadius(), topLeftRadius(), 90, 90);
    
        //Left vertical
        path.lineTo(buffer, height() - bottomLeftRadius() + buffer);
    
        //Bottom left radius
        path.arcTo(buffer, height() - bottomLeftRadius() - buffer, bottomLeftRadius(), bottomLeftRadius(), 180, 90);
    
        //Bottom horizontal
        path.lineTo(width() - bottomRightRadius() - buffer, height() - buffer);
    
        //Bottom right radius
        path.arcTo(width() - bottomRightRadius() - buffer, height() - bottomRightRadius() - buffer, bottomRightRadius(), bottomRightRadius(), 270, 90);
    
        //Right vertical
        path.lineTo(width() - buffer, topRightRadius() + buffer);
    
        //Top right radius
        path.arcTo(width() - topRightRadius() - buffer, buffer, topRightRadius(), topRightRadius(), 0, 90);
    
        setAntialiasing(true);
        QBrush brush(QColor("#53b748"));
    
        painter->setBrush(brush);
        painter->setPen(Qt::NoPen);
        painter->setRenderHint(QPainter::Antialiasing, true);
        painter->drawPath(path);
    

    Is there a fix for this? A better way to implement what I want? I'm open to any and all suggestions.

    raven-worxR 1 Reply Last reply
    0
    • Z zhannum

      Hi,

      I'm working on implementing a custom round rectangle using QQuickPaintedItem so that I can change each corner radii independently and I'm running into an issue with rotating the object. Antialiasing seems to be working properly when the object is painted, but when I rotate the object via QML, aliasing appears along the diagonal edges of the rectangle. I can "hack" a fix to this by increasing the item's height and width and draw the rectangle inside the bounds of the item, but this solution requires a lot of hacky code.

      No rotation:
      0_1556128698190_3facc8f2-f09e-45d6-8877-0c64b44cf0c1-image.png

      Rotation with jaggies:
      0_1556128722708_7752b931-b8a9-4f07-9cc7-61919f2a64d7-image.png

      Here's my paint method:

          double buffer = 0; //Used to draw inside the item instead of on the edges
      
          if(tilt())
          {
              buffer += 1;
          }
          //start
          path.moveTo(width() - topRightRadius() - buffer, buffer);
      
          //Top horizontal
          path.lineTo(topLeftRadius() + buffer, buffer);
      
          //Top left radius
          path.arcTo(buffer, buffer, topLeftRadius(), topLeftRadius(), 90, 90);
      
          //Left vertical
          path.lineTo(buffer, height() - bottomLeftRadius() + buffer);
      
          //Bottom left radius
          path.arcTo(buffer, height() - bottomLeftRadius() - buffer, bottomLeftRadius(), bottomLeftRadius(), 180, 90);
      
          //Bottom horizontal
          path.lineTo(width() - bottomRightRadius() - buffer, height() - buffer);
      
          //Bottom right radius
          path.arcTo(width() - bottomRightRadius() - buffer, height() - bottomRightRadius() - buffer, bottomRightRadius(), bottomRightRadius(), 270, 90);
      
          //Right vertical
          path.lineTo(width() - buffer, topRightRadius() + buffer);
      
          //Top right radius
          path.arcTo(width() - topRightRadius() - buffer, buffer, topRightRadius(), topRightRadius(), 0, 90);
      
          setAntialiasing(true);
          QBrush brush(QColor("#53b748"));
      
          painter->setBrush(brush);
          painter->setPen(Qt::NoPen);
          painter->setRenderHint(QPainter::Antialiasing, true);
          painter->drawPath(path);
      

      Is there a fix for this? A better way to implement what I want? I'm open to any and all suggestions.

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      @zhannum
      how do you rotate via QML? are you sure is in exact 90 degree steps?

      A workaround could be to bind the antialiasing property to rotation % 90.0 !== 0.0

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      Z 1 Reply Last reply
      0
      • raven-worxR raven-worx

        @zhannum
        how do you rotate via QML? are you sure is in exact 90 degree steps?

        A workaround could be to bind the antialiasing property to rotation % 90.0 !== 0.0

        Z Offline
        Z Offline
        zhannum
        wrote on last edited by
        #3

        @raven-worx

        I only want to rotate 5 degrees. I want to rotate when the item is dragged, so I have:

        rotation: Drag.active ? 5 : 0
        
        raven-worxR 1 Reply Last reply
        0
        • Z zhannum

          @raven-worx

          I only want to rotate 5 degrees. I want to rotate when the item is dragged, so I have:

          rotation: Drag.active ? 5 : 0
          
          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @zhannum
          also make sure that you round the x and y coordinates after the drag has finished.
          Ensuring that the pos and size is even on pixels should prevent the need for antialiasing

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • Z Offline
            Z Offline
            zhannum
            wrote on last edited by
            #5

            @raven-worx
            I'm not sure what you mean. Even if I just rotate it in place without dragging it the aliasing still appears:
            0_1556132002084_652b52f8-5f7a-4d80-be4e-aaffdd998863-image.png

            rotation: 5
            
            raven-worxR 2 Replies Last reply
            0
            • Z zhannum

              @raven-worx
              I'm not sure what you mean. Even if I just rotate it in place without dragging it the aliasing still appears:
              0_1556132002084_652b52f8-5f7a-4d80-be4e-aaffdd998863-image.png

              rotation: 5
              
              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by raven-worx
              #6

              @zhannum said in QQuickPaintedItem rotation causing aliasing:

              I'm not sure what you mean.

              i meant when you are finished with dragging, you should ensure that the item's x and y coordinate and its width and height is not any floating value

              Even if I just rotate it in place without dragging it the aliasing still appears

              this doesnt look very antialiased to me?
              your first screenshot does though.

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              Z 1 Reply Last reply
              0
              • raven-worxR raven-worx

                @zhannum said in QQuickPaintedItem rotation causing aliasing:

                I'm not sure what you mean.

                i meant when you are finished with dragging, you should ensure that the item's x and y coordinate and its width and height is not any floating value

                Even if I just rotate it in place without dragging it the aliasing still appears

                this doesnt look very antialiased to me?
                your first screenshot does though.

                Z Offline
                Z Offline
                zhannum
                wrote on last edited by zhannum
                #7

                @raven-worx

                The x and y of the object after a drop event are set in QML, and are always set to integer values.

                this doesnt look very antialiased to me?
                your first screenshot does though.

                I agree. The jagged aliasing is what I'd like to fix. Basically how the diagonal line is made up of small horizontal lines, giving the appearance of steps.
                0_1556136852368_c495ce12-1a2b-4115-aa66-85d5678e9af1-image.png

                With my hacky fix I've implemented, this is what the result looks like, which is what I want:
                0_1556136996928_b9ea979e-d001-4edb-93ab-d259cf8a4e02-image.png

                To better illustrate how I'm "hacking" a solution, i've set the fillColor of the item to white:
                0_1556137075921_13551cd9-3b41-4bfb-9826-fbe72dcf40a0-image.png

                You can see that the edges of the QQuickItem become jagged when rotated.

                1 Reply Last reply
                0
                • Z zhannum

                  @raven-worx
                  I'm not sure what you mean. Even if I just rotate it in place without dragging it the aliasing still appears:
                  0_1556132002084_652b52f8-5f7a-4d80-be4e-aaffdd998863-image.png

                  rotation: 5
                  
                  raven-worxR Offline
                  raven-worxR Offline
                  raven-worx
                  Moderators
                  wrote on last edited by raven-worx
                  #8

                  @zhannum said in QQuickPaintedItem rotation causing aliasing:

                  I agree. The jagged aliasing is what I'd like to fix

                  now i finally got you.
                  You may want to read the following. If you use OpenGL?
                  https://doc.qt.io/qt-5/qtquick-visualcanvas-scenegraph-renderer.html#antialiasing

                  so you might want to try msaa. I assume the software renderer's (QPainter) antialiasing method is closer to to this one.

                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                  If you have a question please use the forum so others can benefit from the solution in the future

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved