2012-02-29 8 views
0

バケツを描き、2つの異なる液体色(黄色と赤色)で塗りつぶす必要があります。複数の液体を入れたバケットを描く

ハードコードされたバージョンではこれまでのところバケットの%を指定する必要があります(例:黄色50%、赤色10%)。

私はC#でグラフィックをやったことがないので、これに関する助けとなります。下の例では、黄色の黒い線の上に黒い線を描くので、バケツの底をよりきれいにする方法も必要です。 Current output of code

private Bitmap drawBucket2() 
    { 
     Bitmap img = new Bitmap(200, 200); 


     using (Graphics g = Graphics.FromImage(img)) 
     { 
      try 
      { 
       Pen penBlack = new Pen(Color.Black, 1);      
       Pen penYellow = new Pen(Color.Yellow, 1); 
       Brush brushYellow = new SolidBrush(Color.Yellow); 
       Brush brushRed = new SolidBrush(Color.Red); 
       Point[] pts = new Point[4]; 
       pts[0] = new Point(11, 115); 
       pts[1] = new Point(170, 115); 
       pts[2] = new Point(162, 180); 
       pts[3] = new Point(21, 180); 

       g.FillEllipse(brushYellow, 11, 90, 160, 50); 
       g.FillPolygon(brushYellow, pts); 

       pts = new Point[3]; 
       pts[0] = new Point(21, 180); 
       pts[1] = new Point(91, 195); 
       pts[2] = new Point(162, 180); 
       g.FillClosedCurve(brushYellow, pts); 

       /*outline */ 
       g.DrawEllipse(penBlack, 2, 10, 180, 50); 
       g.DrawLine(penBlack, 1, 35, 21, 180); 
       g.DrawLine(penBlack, 182, 35, 162, 180); 
       pts = new Point[3]; 
       pts[0] = new Point(21, 180); 
       pts[1] = new Point(91, 195); 
       pts[2] = new Point(162, 180); 
       g.DrawClosedCurve(penBlack, pts); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 

     } 
     return img; 
    } 
+0

宿題ですか? – om471987

+0

'catch'ブロックはまったく無意味です。例外がスローされた場合は、既に*に関するメッセージが表示されます。それをキャッチして自分のメッセージボックスを表示する理由はありません。さらに、何もできない例外を捕まえて飲み込むべきではありません。 –

+0

次の問題は、メソッドが終了する前に作成したGDI +オブジェクト(Pen、Brushなど)を処理していないことです。 **あなたは 'IDisposable' **を実装しているオブジェクトに必ず' Dispose'を呼び出さなければなりません。そうしないと、メモリリークが発生します。 (これらのオブジェクトを処分する習慣に入る必要があります)。これを行う最善の方法は、作成を 'using'ブロックで囲むことです。あるいは、関数の最後に手動で 'Dispose'メソッドを呼び出すこともできます。 –

答えて

1

私はこれを解決するために管理しています、私は答えとしてこれを受け入れる前に誰もがそれを改善することができるかどうかを確認するためにここにコードを投稿しています。

private int[] getPoints(int perc) 
    { 
     int[] pts;// = new int[4]; 
     double x_offset_left = (35 - 21); 
     x_offset_left = x_offset_left/100; 
     double height = 135; 
     double width = 178; 
     double x1, x2, y1, y2; 

     int margin_top = 66;//68 
     int margin_left = 21; 

     y1 = ((height/100) * perc) + margin_top; 
     y2 = y1; 

     x1 = margin_left + (x_offset_left * perc); 
     x2 = width - (x_offset_left * perc); 

     pts = new int[4] { Convert.ToInt32(x1), Convert.ToInt32(y1), Convert.ToInt32(x2), Convert.ToInt32(y2) }; 
     return pts; 
    } 
    private Bitmap drawBucket2(int yellowval, int redval, int overval) 
    { 
     Bitmap img = new Bitmap(200, 221); 
     using (Graphics g = Graphics.FromImage(img)) 
     { 
      Brush bRed = new SolidBrush(Color.FromArgb(50, Color.DarkRed)); 
      Brush bYellow = new SolidBrush(Color.FromArgb(75, Color.Gold)); 
      Brush bBlue = new SolidBrush(Color.FromArgb(50, Color.Blue)); 

      GraphicsPath gp = new GraphicsPath(); 
      Region r; 
      Point[] points_yellow; 
      Point[] points_red; 

      int percentage = 0; 
      int[] pts; 
      int[] pts_full = getPoints(100); 
      int[] pts_min = getPoints(1); 

      #region "Yellow Region" 
      // bottom curve 
      percentage = yellowval; 
      pts = getPoints(100 - percentage); 

      points_yellow = new Point[3]; 
      points_yellow[0] = new Point(pts_full[0], pts_full[3]); 
      points_yellow[1] = new Point(((pts_full[2] - pts_full[0])/2 + pts_full[0]), (pts_full[1] + 15)); 
      points_yellow[2] = new Point(pts_full[2], pts_full[3]); 
      gp.AddCurve(points_yellow, 0.7f); 
      //Console.WriteLine("curve : (" + points_yellow[0].X + ", " + points_yellow[0].Y + "), " + " (" + points_yellow[1].X + ", " + points_yellow[1].Y + "), " + " (" + points_yellow[2].X + ", " + points_yellow[2].Y + ")"); 

      //polygon 
      points_yellow = new Point[4]; 
      points_yellow[0] = new Point(pts[0], pts[1]); 
      points_yellow[1] = new Point(pts[2], pts[1]); 
      points_yellow[2] = new Point(pts_full[2], pts_full[1]); 
      points_yellow[3] = new Point(pts_full[0], pts_full[1]); 
      gp.AddPolygon(points_yellow); 
      //Console.WriteLine("Poly : (" + points_yellow[0].X + ", " + points_yellow[0].Y + "), " + " (" + points_yellow[1].X + ", " + points_yellow[1].Y + "), " + " (" + points_yellow[2].X + ", " + points_yellow[2].Y + "), " + " (" + points_yellow[3].X + ", " + points_yellow[3].Y + ")"); 

      // top curve 
      points_yellow = new Point[3]; 
      points_yellow[0] = new Point(pts[0], pts[1]); 
      points_yellow[1] = new Point(((pts[2] - pts[0])/2 + pts[0]), (pts[1] + 15)); 
      points_yellow[2] = new Point(pts[2], pts[1]); 
      gp.AddCurve(points_yellow, 0.7f); 
      //Console.WriteLine("curve : (" + points_yellow[0].X + ", " + points_yellow[0].Y + "), " + " (" + points_yellow[1].X + ", " + points_yellow[1].Y + "), " + " (" + points_yellow[2].X + ", " + points_yellow[2].Y + ")"); 

      r = new Region(gp); 
      g.FillRegion(bYellow, r); 
      #endregion  

      #region "Red Region" 
      gp = new GraphicsPath(); 
      percentage = yellowval + redval; 

      // Bottom Curve 
      gp.AddCurve(points_yellow, 0.7f); 
      //Console.WriteLine("curve : (" + points_yellow[0].X + ", " + points_yellow[0].Y + "), " + " (" + points_yellow[1].X + ", " + points_yellow[1].Y + "), " + " (" + points_yellow[2].X + ", " + points_yellow[2].Y + ")"); 

      // polygon 
      int[] pts_yel = new int[3]{pts[0], pts[1], pts[2]}; 
      pts = getPoints(100 - percentage); 
      points_red = new Point[4]; 
      points_red[0] = new Point(pts[0], pts[1]); 
      points_red[1] = new Point(pts[2], pts[1]); 
      points_red[2] = new Point(pts_yel[2], pts_yel[1]); 
      points_red[3] = new Point(pts_yel[0], pts_yel[1]); 
      gp.AddPolygon(points_red); 

      // Top Curve 
      points_red = new Point[3]; 
      points_red[0] = new Point(pts[0], pts[1]); 
      points_red[1] = new Point(((pts[2] - pts[0])/2 + pts[0]), (pts[1] + 12)); 
      points_red[2] = new Point(pts[2], pts[1]); 
      gp.AddCurve(points_red, 0.7f); 

      r = new Region(gp); 
      g.FillRegion(bRed, r); 
      #endregion 

      #region "Overflow" 
      if (overval > 0) 
      { 
       gp = new GraphicsPath(); 
       gp.AddEllipse(16, 10, 165, 32); 
       r = new Region(gp); 
       g.FillRegion(bBlue, r); 
      } 
      #endregion 
      r.Dispose(); 
      gp.Dispose(); 
      bRed.Dispose(); 
      bYellow.Dispose(); 
      bBlue.Dispose();    
     } 
     return img; 
    } 

    private void fillBucket(int Yellowperc, int Redperc, int Overperc) 
    { 
     pictureBox1.Image = null; 
     pictureBox1.Image = drawBucket2(Yellowperc, Redperc, Overperc); 
    } 
1

「液体は」そう、あなたが計算する必要があるすべては、液体の量に応じて高さや左右の位置で、下から上に描画し、充填の間にスペースを持つ2つの省略記号です(黄色、赤色)

// Upper Elipse and top Points for the filled center 
y = HeightOfBottom + (FullHeight * (StartAmountFloat + AmountFloat)) 
x1 = Middle - (DiffenceOfDiameter * (StartAmountFloat + AmountFloat)) 
x2 = Middle + (DiffenceOfDiameter * (StartAmountFloat + AmountFloat)) 

// Lower Elipse and bottom Points for the filled center 
y = HeightOfBottom + (FullHeight * StartAmountFloat) 
x1 = Middle - (DiffenceOfDiameter * StartAmountFloat) 
x2 = Middle + (DiffenceOfDiameter * StartAmountFloat) 

ボトムもエリプスの下半分にする必要があります。

+0

Stephanありがとう、私はこれを実装するにはどうすればC#のGDに全く新しいですか? – Neo

1

あなたのためのコードはありませんが、これを達成するためのおおよそのワークフローを提供できます。基本的には後ろから前に、あなたのオブジェクトを描画したいので、私はこの順

  1. 同じサイズのellpiseとして液体の底に描く楕円
  2. としてバケツの底に描きで描画されます1ピクセル高い値
  3. ここで、希望の%に達するまで、各Yピクセルに楕円を描画します。ここで、ピクセルの終了数は(バケットの最下部)+((バケットの最上部) - (バケツの底面)*(パーセンテージ/ 100))。特定のポイントで楕円を広げる必要があります。これでエイリアスエフェクトが作成されますが、心配する必要はありません。次に引き出す予定です
  4. 最後に、バケットと上部の両側を描画します。適切な線の太さを選択すると、誇らしげにあなたの方法をハッキングしたという事実をはっきりと隠すことができます:)

最後に、私は多くの試行錯誤をお勧めします。これを行うほど、より簡単になります!幸運

+0

多くの人が頭の上にありがとう、その奇妙なあなたが実際の生活の中で常にトップダウンを描画するように私は注文を再配置することを忘れないだろう。 – Neo

関連する問題