using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections.Generic;
using System.Windows.Forms;
namespace PascalsTriangleDisplay.UI
{
sealed class PascalsTriangle : PictureBox
{
public PascalsTriangle()
{
DoubleBuffered = true;
Size = new Size(100, 100);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
BackColor = Color.Transparent;
}
public int Base { get; set; }
private int _rad = 2;
public int Rad
{
get { return _rad; }
set { _rad = value; }
}
public Color DefaultBaseColor { get; set; }
public Dictionary<int, Color> BaseColors { get; set; }
private const decimal Sqrt2 = 1.4142135623730950488016887242m;
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
int gridTiles = Width / Rad;
decimal dy = Sqrt2 * Rad;
int[] previousColors = new int[] { };
for (int i = 0; i < gridTiles / 2 - Rad; i++)
{
int[] rowColors = new int[i + 1];
for (int j = 0; j <= i; j++)
{
int colorIndex;
if (j == 0 || j == i)
{
colorIndex = 1;
}
else
{
int leftColor = previousColors[j - 1];
int rightColor = previousColors[j];
colorIndex = (leftColor + rightColor) % Base;
}
Color fillColor = BaseColors.ContainsKey(colorIndex) ? BaseColors[colorIndex] : DefaultBaseColor;
DrawElipse(e.Graphics, fillColor, new Point((Width / 2) + Rad * (2 * j - i), (int)(dy * i * 1.415m)), Rad * 2);
rowColors[j] = colorIndex;
}
previousColors = rowColors;
}
}
private int _prevSize;
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (Height != _prevSize)
{
_prevSize = Width = Height;
}
else
{
_prevSize = Height = Width;
}
Invalidate();
}
private static void DrawElipse(Graphics g, Color fill, Point location, int diameter)
{
Size s = new Size(diameter, diameter);
g.DrawEllipse(Pens.Black, new Rectangle(location, s));
using (SolidBrush sb = new SolidBrush(Color.FromArgb(200, fill)))
g.FillEllipse(sb, new Rectangle(location, s));
}
}
}