\

Školení Návrhové vzory, OOP a UML


 Friday, 12 February 2010
Doplnění metod FillPie a DrawPie do objektu Graphics v Compact .Net Frameworku

Nedávno se na fóru vývojáře objevil dotaz, jak nahradit chybějící metodu FillPie v objektu Graphics na Compact .Net Frameworku, protože prý ani tradiční zuřivé googlování žádné výsledky nepřineslo. Zkusil jsem napsat implementaci metody FillPie, a protože se podobných dotazů na internetu dá najít více, dávám kód obohacený nyní i o metodu DrawPie na blog, aby nezůstal utopen jen v diskuzním fóru.

Compact .Net Framework sice nemá metodu FillPie ani DrawPie, ale má obecné metody DrawPolygon a FillPolygon, se kterými nakreslíte, co se vám zlíbí.  Zhýrale jsem kód opět trochu zlinqovatěl, asi začínám být na LINQu a extenzních metodách závislý. Inu, jak říkáme my C# vývojáři, původně odříkané extenzní metody plný zásobník volání. :-)

 

static class GraphicsExtensions
    {

        public static readonly float ANGLE_MULTIPLY = (float) Math.PI / 180;
        
        public static void FillPie(this Graphics g, SolidBrush brush, int x, int y, int width, int height, float startAngle,  float sweepAngle)
        {
            var tempPoints = GetTempPoints(sweepAngle, startAngle, x, y, width, height);

            g.FillPolygon(brush, tempPoints);
        }

        public static void DrawPie(this Graphics g, Pen pen, int x, int y, int width, int height, float startAngle, float sweepAngle)
        {
            var tempPoints = GetTempPoints(sweepAngle, startAngle, x, y, width, height);

            g.DrawPolygon(pen, tempPoints);
        }

        private static Point[] GetTempPoints(float sweepAngle, float startAngle, int x, int y, int width, int height)
        {
            const float HALF_FACTOR = 2f;
            const int TEMP_POINT_FIRST = 0;
            const int TEMP_POINT_LAST= 100;
            const int TOTAL_POINTS = TEMP_POINT_LAST - TEMP_POINT_FIRST;            
            

            float angleInc = (sweepAngle - startAngle) / TOTAL_POINTS;

            float halfWidth = width / HALF_FACTOR;

            float halfHeight= height / HALF_FACTOR;
            
            return (new[] {new Point
                               {
                                   X = x,
                                   Y = y
                               }
                          })
                                   
                .Union(
                               
                          (from i in Enumerable.Range(TEMP_POINT_FIRST, TOTAL_POINTS)
                           let angle = i == TEMP_POINT_LAST - 1? sweepAngle : startAngle + (i * angleInc)
                           select new Point
                                      {
                                          X = (int) (x + (Math.Cos(angle*(ANGLE_MULTIPLY))*(halfWidth))),
                                          Y = (int) (y + (Math.Sin(angle*(ANGLE_MULTIPLY))*(halfHeight)))
                                      })).ToArray();
        }
    }

 

Použití metod:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (var redBrush = new SolidBrush(Color.Red))
            using (var blueBrush = new SolidBrush(Color.Blue))
            using (var greenBrush = new SolidBrush(Color.ForestGreen))
            {
                e.Graphics.FillPie(redBrush, Width / 2, Height / 2, Width / 2, Height / 2, 0, 35f);
                e.Graphics.FillPie(blueBrush, Width / 2, Height / 2, Width / 2, Height / 2, 35f, 80f);
                e.Graphics.FillPie(greenBrush, Width / 2, Height / 2, Width / 2, Height / 2, 80f, 360f);                
            }

            using (var redPen = new Pen(Color.IndianRed))
            {
                e.Graphics.DrawPie(redPen, Width / 5, Height / 5, Width / 5, Height / 5, 0, 60f);
            }
        }
    }

 

A zde je náhled na formulář:

FillPieResult



Friday, 12 February 2010 13:17:54 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Compact .Net Framework | LINQ