2016-04-04 2 views
0

ポイントのリストを使用して関数グラフィックを描きたい。しかし、非常に多くの点が存在するときは減速しています。だから、私は現在の図面を消去せずに描画することができます私はポイントを格納する必要はないと思う。私はInvalidateが現在の図面を消去することを知っています。どうやってこのトリックをすることができますか? どのように私は現在のグラフィックスオブジェクトをクリアせずに描くことができますか?

は、私は現在、このメソッドを使用して:

CoordinateSystem cos = new CoordinateSystem(); 
    List<PointF> points = new List<PointF>(); 
    float a = -20; 
    void Form1_Tick(object sender, EventArgs e) 
    { 
     panel1.Invalidate(); 
    } 
    void panel1_Paint(object sender, PaintEventArgs e) 
    { 
     e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
     double x = a; 
     double y = Root(x, 3); 
     cos.DrawSystem(e.Graphics); 
     points.Add(cos.RelativePoint(new PointF((float)x, (float)y))); 
     for (int i = 1; i < points.Count - 1; i++) 
     { 
     e.Graphics.DrawLine(Pens.Red,points[i],points[i+1]); 
     } 
     a += 0.05f; 

    } 

UPDATE

あなたは私が再描画するビットマップを使用している示唆したよう。しかし結果の質は私には良くない。また、データが変更された場合にのみInvalidateに電話する方法はありません。ここでは、Invalidateメソッドが呼び出されるとデータが変更されるためです。

コード:

CoordinateSystem cos = new CoordinateSystem(); 
    Bitmap bmp; 
    float a = -20; 
    void Form1_Tick(object sender, EventArgs e) 
    { 
     panel1.Invalidate(); 
    } 

    void panel1_Paint(object sender, PaintEventArgs e) 
    { 
     e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
     double x = a; 
     double y = Root(x, 3); 
     PointF rel = cos.RelativePoint(new PointF((float)x, (float)y)); 
     using (Graphics grp = Graphics.FromImage(bmp)) 
     { 
      grp.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
      cos.DrawSystem(grp); 
      grp.DrawEllipse(Pens.Red, rel.X - 0.5f, rel.Y - 0.5f, 1, 1); 
     } 
     e.Graphics.DrawImage(bmp, 0, 0); 
     a += 0.01f; 
    } 

あなたはその結果でわかるように、数のテキストは良い品質を持っていない:enter image description here

UPDATE 2: [OK]を、私は少し私のコードを変更しました。 Loadの座標系を一度描くだけで、すぐに良い品質が得られます。皆さん、ありがとうございました!

+0

Timer tickから 'Invalidate()'を呼び出すようですか?どうしてそうするか。 Invalidateを呼び出すだけで、データが変更されたときにフォームを再描画する必要があります。 – NineBerry

+3

ビットマップに描画し、次に描画イベントでDrawImageを実行します。あなたのタイマーイベントは不要です。使用しているグラフィック変数をどのように更新しますか? – LarsTech

+0

はい、バッファーイメージに描画し、コントロールに描画します。また、tickイベントハンドラの中にinvalidateを置かないでください。 – ManoDestra

答えて

2

グラフィックは"不明"グラフィックはありません。 Controlを描画する必要がある場合(無効化されている場合)は、すべてを再度描画する必要があります。

コードを少し改善する方法の1つは、ポイントを反復処理する代わりにGraphics.DrawLines()を使用し、別々の行ごとにGraphics.DrawLine()を呼び出すことです。

void panel1_Paint(object sender, PaintEventArgs e) 
{ 
    e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
    double x = a; 
    double y = Root(x, 3); 
    cos.DrawSystem(e.Graphics); 
    points.Add(cos.RelativePoint(new PointF((float)x, (float)y))); 
    e.Graphics.DrawLines(Pens.Red, points.ToArray()); 
} 
1

Paintイベントはe.ClipRectangle性質を持っています。

これは、すべてを再描画する必要は必ずしもないため(フォームの一部がフォーム上に移動され、再度移動するなど)、実際に再描画する必要がある矩形です。

あなたができることの1つは、その矩形内に収まる線だけを描くことです。

しかし、あなたがInvalidateを呼び出す場合、それは全体のものを再描画する必要があることを示しています。

あなたが描いたものを追跡して、新しいものだけを描く方がよいでしょうか?

+1

引数として再描画する必要のある領域を取る 'Invalidate'のオーバーロードがあることに注意してください。 –

関連する問題