Question

J'ai besoin de dessiner un seau et de le remplir de deux couleurs liquides différentes (jaune et rouge).

Je suis arrivé si loin dans une version codée en dur, mais je dois être en mesure de spécifier le% du seau rempli, donc par exemple 50% jaune puis 10% rouge.

Je n'ai jamais fait de graphiques en C #, donc toute aide à ce sujet est appréciée. J'ai également besoin d'une façon plus propre de faire le bas du seau car il trace une ligne noire sur le jaune dans l'exemple ci-dessous.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;
    }
Était-ce utile?

La solution 3

J'ai réussi à résoudre celui-ci, je publie le code ici pour voir si quelqu'un peut encore l'améliorer avant d'accepter cela comme réponse.

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

Autres conseils

Les "liquides" sont deux elipses avec l'espace entre les deux remplies, donc tout ce dont vous avez besoin pour calculer est les hauteurs et les positions gauche et droite en fonction de la quantité de liquide et dessiner du bas en haut (c'est-à-dire jaune puis rouge)

// 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)

Le fond doit également être la moitié inférieure d'une élipse.

OK, je n'ai pas de code pour vous, mais je peux vous donner un flux de travail approximatif pour y parvenir. Fondamentalement, vous voulez retirer vos objets à l'avant, donc je dessinerais dans cet ordre

  1. Dessinez le bas du seau comme une ellipse
  2. Dessinez le bas du liquide comme un ellpise de la même taille, mais un pixel plus haut
  3. Dessinez maintenant des ellipses à chaque pixel Y ci-dessus jusqu'à ce que le% souhaité soit atteint, où le nombre d'extrémité de pixels est calculé par le (bas du seau) + ((haut du seau) - (en bas du seau) * ( pourcentage / 100)). Vous devrez élargir l'ellipse à certains points. Cela créera un effet aliasé mais ne vous inquiétez pas, nous allons le dessiner ensuite
  4. Dessinez enfin les côtés du seau et du haut. Si vous choisissez une épaisseur de ligne appropriée, vous pouvez masquer les faits effectivement le fait que vous avez piraté votre chemin vers la gloire :)

Dernière chose, je suggérerais beaucoup d'essais et d'erreurs. Plus vous faites cela, plus cela deviendra facile! Bonne chance

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top