2017-02-04 5 views
2

おはようございます、私はウェブ上で同様の質問とそれに関するチュートリアルがあることを知っていますが、コードを確認して修正してください。つまり、私のプロジェクトに何が問題なのかを知りたいのです。 メインパネルに放物線グラフを描く必要があります。 また、「表示」パネルのビュー(と放物線)を縮小したり拡大したりするために、ズームインとズームアウトの2つのボタンを含める必要があります。 尺度varを使用することをお勧めしました。 これは私のコードです:DrawLineを使用して放物線を描くC#

メモ:x0、y0はpanel_main x center、y centerです。
私は、方程式からx、yを決定するために使用されるx、yを持っています。
xpc、ypcはウィンドウスケール(ピクセルも同様)に変換されます。
xmin、xmaxは、一定の縮尺でパネル上に留まる極値です

私はあなたに私にヒントを与えることができたら幸いです!

public void DisegnaParabola() 
{ 
    Graphics gs = panel_main.CreateGraphics(); 
    pen.Color = Color.Black;  

    scale = (x0*2)/zoom;  //Pixels equivalent to 1x or 1y 
    n_punti = (x0*2)/scale;  //Number of x math points that are visible in window 
    xmin = -(n_punti/2);      
    xmax = n_punti/2;       
    precision = 1/scale;   //Increment of x to have 1px 
    if (asse_parabola.SelectedIndex == 0) //if Y axis 
    { 
     for (double i = xmin + precision; i < xmax; i += precision) 
     { 
      rifx = i - precision;      //Old points 
      rifxpc = rifx * scale; 
      rify = (a * Math.Pow(rifx, 2)) + b * rifx + c; 
      rifypc = y0 - (rify * scale);    

      x = i;          //New points 
      y = (a * Math.Pow(x, 2)) + b * x + c; 
      ypc = y0 - (y * scale); 

      gs.DrawLine(pen, (float)rifxpc, (float)rifypc, (float)xpc, (float)ypc); 
     } 
    } 
    else 
    { 
     scale = (y0*2)/zoom;  //Pixels for 1y 
     n_punti = (y0*2)/scale;  //Numbers of y in the window 
     ymin = -(n_punti/2);      
     ymax = n_punti/2; 

     for(double i=ymin+precision; i<ymax; i+=precision) 
     { 
      rify = y - precision; 
      rifypc = (y0*2) - rify * scale; 
      rifx = (a * Math.Pow(rify, 2)) + b * rify + c; 
      rifxpc = x0 + (rifx * scale); 

      y = i; 
      x = (a * Math.Pow(y, 2)) + b * y + c; 
      xpc = x0 + (x * scale); 

      gs.DrawLine(pen, (float)rifypc, (float)rifxpc, (float)ypc, (float)xpc); 
     } 

    } 

    lbl_canc.Visible = true; 


} 
+0

_Graphics gs = panel_main.CreateGraphics(); _これは、結果が非​​永続的であるため、最初の間違いです。それ以外は、e.Graphicsオブジェクト(ここでお勧めします)またはBitmapを使用してPaintイベントを描画します。多くの 'DrawLine'呼び出しを使用する_gs.DrawLine_も、width = 1の不透明なペン以外のペンでは見栄えが悪いので、お勧めしません。ポイントを集めて一つの 'DrawLines'(複数の!)コールを使うのは良いです..私はすべてのタイプを見ることはできませんが、あなたは整数除算トラップを知っていればいいと思っています。 、 そうする! – TaW

答えて

0

あなたの質問は、実際にいくつかのタスクで構成され、いつものようにキーを取り、離れて、それらを破るために..ですデータを取得している

  • 一つの問題は、私はあなたに詳細を残しますが、それを残りの部分からスパースする方法を示します。

  • 次の問題は、データを拡大/縮小することです。この方法を避け、代わりに描画ツールをスケールする方法を説明します。

  • そして、第3のものは、それらを表示面に描画することです。あなたが見るように、これは他の問題が処理されると、これは本当に簡単です。

まず、データの収集から始めましょう。あなたは、同じコードでそれらをすべて作成し、スケーリングして描画しようとします。これは、多くの欠点がある。..

てみましょう最初の適した構造でデータを収集:

List<PointF> points = new List<PointF>(); 

List<T>は選択肢ほとんどの時間のコレクションです。配列よりもはるかに良い!いくつかの方法では、数式から計算されたデータをそのリストに入力する必要があります。ここで

は一例です:第二の重要な部分のために今

List<PointF> getPoints(float start, float end, int count, float ymax) 
{ 
    List<PointF> points = new List<PointF>(); 
    float deltaX = (end - start)/count; 

    for (int i = 0; i < count; i++) 
    { 
     float x = i * deltaX; 
     // insert your own formula(s) here! 
     float y = ymax + (float)Math.Sin(x * somefactor) * ymax; 
     points.Add(new PointF(x, y)); 
    } 
    return points; 
} 

:データをスケーリングする方法は?これは、それらを作成するときに行うこともできます。しかし、再び、2つのタクを分離することは、それらを両方ともより簡単にする。だからここ

ではなく、データをスケーリングする、我々はそれらをプロットするために使用しますGraphicsオブジェクトを拡大縮小、機能である:

void ScaleGraphics(Graphics g, List<PointF> data) 
{ 
    float xmax = data.Select(x => x.X).Max(); 
    float ymax = data.Select(x => x.Y).Max(); 
    float xmin = data.Select(x => x.X).Min(); 
    float ymin = data.Select(x => x.Y).Min(); 

    float width = Math.Abs(xmax - xmin); 
    float height = Math.Abs(ymax - ymin); 

    var vr = g.VisibleClipBounds; 

    g.ScaleTransform(vr.Width/width, vr.Height/height); 
} 

この方法は、私たちのリスト内のすべてのデータを図面に収まることを確認します表面。それらを異なるサイズに制限したい場合は、それを渡してそれに応じてコードを変更することができます。

最後に実際の図面を行う必要があります。私たちはどこでそれをするのですか?それは、私たちの描画面制御のPaintイベントです。:

private void panel1_Paint(object sender, PaintEventArgs e) 
{ 
    if (points.Count < 2) return; // no lines to draw, yet 
    ScaleGraphics(e.Graphics, points); 
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; 

    using (Pen pen = new Pen(Color.Blue) 
      { Width = 1.5f , LineJoin = LineJoin.Round, MiterLimit = 1f}) 
     e.Graphics.DrawLines(pen, points.ToArray()); 
} 
+0

ありがとう!私は、私にこれらの新しいコードを聞いてうれしい、それを試してみます –

+0

あなたの問題を解決しましたか? – TaW

+0

はい、(遅れて申し訳ありません)私は最終的にそれを解決することができました。私はDrawEllipseとonPaintイベントを使って放物線を描画して、アプリケーションの開始時に軸を描画しました。 –

関連する問題