locked
Strange behavior using ScaleTransform RRS feed

  • Question

  • 'PUT CODE IN A FORM AND TRY TO CHANGE  X_ScaleFactor = 66  -> You will get a weird behavior!     

            Dim X_ScaleFactor = 65

            g= Me.CreateGraphics

            g.ScaleTransform(X_ScaleFactor, 1)

            g.DrawLine(Pens.Red, 1, 0, 1, 10)

            g.Dispose()

           ' Does anyone understand what is happening? 

    Wednesday, February 10, 2016 12:21 PM

Answers

  • If you want to draw a thin unscaled (1-pixel) line, then try this workaround:

    g.DrawLine(New Pen(Color.Red, 0), 1, 0, 1, 10)


    Wednesday, February 10, 2016 1:26 PM

All replies

  • First off you know about the "jaggies" you get when you draw square pixels along a (diagonal) line?

    Then you realize when you scaletransform you not only scale the coordinates you scale the drawing pen.

    So try this:

          g.DrawLine(New Pen(Color.Red, 1 / X_ScaleFactor), 1, 0, 1, 10)

    See how its dividing the pen width by the scalefactor? Then you get a thin pen all the time. Your sample is scaling the pen width to, then from 65 to 66 you get "jagged". Like this:


    Wednesday, February 10, 2016 1:17 PM
  • If you want to draw a thin unscaled (1-pixel) line, then try this workaround:

    g.DrawLine(New Pen(Color.Red, 0), 1, 0, 1, 10)


    Wednesday, February 10, 2016 1:26 PM
  • Hi,

    indeed, this is an interresting output when scalfactor is larger as 65...

    I'll inspect this and if I find something I come back and tell what I found...

    Regards,

      Thorsten

    Thursday, February 11, 2016 1:04 AM
  • Hi,

    this seems to be a known problem:

    [Btw I'd expected the line with a scalefactor of less than 66 drawn larger as just that thin one, so I see that problem "the other way round..." --->

    so this is what I'd rather would expect:

    Note the setting for the width of the pen:

        Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
            Dim X_ScaleFactor = 65.0F
    
            e.Graphics.ScaleTransform(X_ScaleFactor, 1)
    
            Using p As New Pen(Color.Red, 1.000001F)
                'p.Alignment = Drawing2D.PenAlignment.Center
                e.Graphics.DrawLine(p, 1, 0, 1, 10)
            End Using
        End Sub

    Maybe related to:

    http://stackoverflow.com/questions/13400742/precision-of-multiplication-by-1-0-and-int-to-float-conversion

    but     

        MessageBox.Show((1 > CSng(1)).ToString()) returns false, since 1^1 is 1.    :-)

    ]

    [I just dont know why it "jumps" at 65<->66. I'd rather expected a value larger than 64 would cause this (256 / 4) or (256 - 256 / 4)as a "quasi limit"]

    http://stackoverflow.com/questions/10482032/incorrect-scaling-of-pen-when-using-graphics-scaletransform

    You can use Viorel_'s solution or scale the pen:

        Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
            Dim X_ScaleFactor = 66.0F
            'e.Graphics.PixelOffsetMode = Drawing2D.PixelOffsetMode.Half
            'e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.NearestNeighbor
    
            e.Graphics.ScaleTransform(X_ScaleFactor, 1)
    
            Using p As New Pen(Color.Red, 1.0F / X_ScaleFactor)
                e.Graphics.DrawLine(p, 1, 0, 1, 10)
            End Using
        End Sub

    Regards,

      Thorsten

    Thursday, February 11, 2016 1:12 AM