Question

I'm seeing strange behaviour when drawing a line with a scale transform (Graphics.ScaleTransform() - see MSDN) in my OnPaint() method.

When using a large y-scale factor for the ScaleTransform method, then if the x-scale is set above 1x, the line suddenly becomes much larger.

Setting the width of pen with which the line is drawn to -1 seems to get round the problem, but I do not want to draw a very thin line (the line must be printed later, 1px is too thin).

Here's some sample code to demonstrate the problem:

public class GraphicsTestForm : Form
{
    private readonly float _lineLength = 300;
    private readonly Pen _whitePen;

    private Label _debugLabel;

    public GraphicsTestForm()
    {
        ClientSize = new Size(300, 300);

        Text = @"GraphicsTest";
        SetStyle(ControlStyles.ResizeRedraw, true);

        _debugLabel = new Label
        {
            ForeColor = Color.Yellow,
            BackColor = Color.Transparent
        };
        Controls.Add(_debugLabel);

        _lineLength = ClientSize.Width;
        _whitePen = new Pen(Color.White, 1f); // can change pen width to -1
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        float scaleX = ClientSize.Width / _lineLength;
        const int ScaleY = 100;

        e.Graphics.Clear(Color.Black);

        _debugLabel.Text = @"x-scale: " + scaleX;

        // scale the X-axis so the line exactly fits the graphics area
        // scale the Y-axis by scale factor
        e.Graphics.ScaleTransform(scaleX, ScaleY);

        float y = ClientSize.Height / (ScaleY * 2f);
        e.Graphics.DrawLine(_whitePen, 0, y, _lineLength, y);

        e.Graphics.ResetTransform();
    }
}

I would like the line/pen to scale gracefully, without jumping in size so dramatically.

(Additionally, I noticed that when the line is very large, it is not drawn continuously across multiple monitors. Perhaps this is related?)

Was it helpful?

Solution

Try to change the pen width according to the scale:

 _whitePen = new Pen(Color.White, 1f / ScaleY); 
 e.Graphics.DrawLine(_whitePen, 0, y, _lineLength, y); 

OTHER TIPS

I just compensated for the overall scaling in the pens line geometry;-

m_Pen->SetWidth(1.0f);
m_Pen->ScaleTransform(1.0f / ZoomX, 1.0f / ZoomY);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top