2012-05-07 33 views
0

OnPaint()メソッドで縮尺変換(Graphics.ScaleTransform() - MSDNを参照)を使用して線を描画すると、奇妙な動作が発生します。Graphics.ScaleTransformを使用しているときにPenのスケーリングが正しくない

ScaleTransformメソッドに大きなyスケールファクタを使用する場合、xスケールが1xを超えると、突然大きなラインになります。

線を描くペンの幅を-1に設定すると、問題は丸くなりますが、非常に細い線を描きたくはありません(後で線を印刷する必要があります.1pxが薄すぎます)。ここで

は、問題を示すためにいくつかのサンプルコードです:

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(); 
    } 
} 

私はそう劇的サイズにジャンプせずに、優雅にスケールする行/ペンをしたいと思います。

(また、私はおそらく、これが関連しているラインが非常に大きい場合、それは、複数のモニタにまたがって連続して描かれていないことに気づいた。?)

+1

珍しい事をするGDI +を尋ねるが、問題ではないことはありません。珍しいここでは、角度によって異なる厚さで描くことを意味する。より良い結果を得るには、XとYのスケーリング係数を同じに保ちます。 –

+0

@HansPassantヒントをありがとう!私は実際には、X軸上に100点の正弦曲線を描画する必要がありますが、Y軸は-1と1の間にしかありません。したがって、XとYのスケールファクタの違い。描画する前にポイントを別々にスケールするだけで、グラフィックス変換について忘れるべきですか? –

答えて

2

規模に応じてペン幅を変更してください:

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

ペンオブジェクトの作成に問題はありますか? –

+0

しかし、このような仕組みはありますが、ラインはスムーズに拡大縮小されません。たとえば、私が使用した太い線(10f/ScaleY)が必要な場合など、問題が戻ってきます。 –

+0

コンティニュアの作成に関しては、それらを処分すると便利です。 [この前の質問](http://stackoverflow.com/questions/1819096/is-it-important-to-dispose-solidbrush-and-pen)を見てください。しかし、不必要なパフォーマンス低下を避けるために、前のペンが今必要なペンと同じであるかどうかを確認します(最後の縮尺を保存します)。 –

1

私はちょうどペンライン構造の全体的なスケーリングのための補償; -

m_Pen->SetWidth(1.0f); 
m_Pen->ScaleTransform(1.0f/ZoomX, 1.0f/ZoomY); 
関連する問題