These days I am working on a Paint App in Windows Form. I created my own variation of TaW's code for live painting on picturebox:
enum ArtMode { HandDraw, Erase, Line, Rectangle, Ellipse, Circle, AutoPainter }
class ArtManager
{
Pen pen;
public void Draw(PaintEventArgs G, List<ArtAction> actions)
{
foreach (ArtAction da in actions)
{
pen = new Pen(da.color, da.width);
if (da.points.Count > 1)
{
if (da.artMode == ArtMode.HandDraw)
G.Graphics.DrawCurve(pen, da.points.ToArray());
else if (da.artMode == ArtMode.Erase)
G.Graphics.DrawCurve(new Pen(da.color, da.width), da.points.ToArray());
else if (da.artMode == ArtMode.Line)
G.Graphics.DrawLine(pen, da.points[0], da.points[da.points.Count - 1]);
else if (da.artMode == ArtMode.Rectangle)
G.Graphics.DrawRectangle(pen, Math.Min(da.points[0].X, da.points[da.points.Count - 1].X), Math.Min(da.points[0].Y, da.points[da.points.Count - 1].Y), Math.Abs(da.points[0].X - da.points[da.points.Count - 1].X), Math.Abs(da.points[0].Y - da.points[da.points.Count - 1].Y));
else if (da.artMode == ArtMode.Ellipse)
{
Rectangle rect = new Rectangle((int)Math.Min(da.points[0].X, da.points[da.points.Count - 1].X), (int)Math.Min(da.points[0].Y, da.points[da.points.Count - 1].Y), (int)Math.Abs(da.points[0].X - da.points[da.points.Count - 1].X), (int)Math.Abs(da.points[0].Y - da.points[da.points.Count - 1].Y));
G.Graphics.DrawEllipse(pen, rect);
}
else if (da.artMode == ArtMode.Circle)
{
Rectangle rect = new Rectangle((int)Math.Min(da.points[0].X, da.points[da.points.Count - 1].X), (int)Math.Min(da.points[0].Y, da.points[da.points.Count - 1].Y), (int)Math.Abs(da.points[0].Y - da.points[da.points.Count - 1].Y), (int)Math.Abs(da.points[0].Y - da.points[da.points.Count - 1].Y));
G.Graphics.DrawEllipse(pen, rect);
}
}
}
}
}
class ArtAction
{
public Color color;
public float width;
public ArtMode artMode;
public List<PointF> points;
public ArtAction(Color color, float width ,ArtMode artMode)
{
this.color = color;
this.width = width;
this.artMode = artMode;
points = new List<PointF>();
}
}
Form's code:
Pen pen;
ArtMode artMode;
List<ArtAction> actions = new List<ArtAction>();
ArtManager artManager = new ArtManager();
int i = 0;
private void canvas_MouseDown(object sender, MouseEventArgs e)
{
//Setting pen
pen.Width = float.Parse(BrushSizeCB.SelectedItem.ToString());
pen.Color = HandDraw_ColorIndic.BackColor;
if (artMode == ArtMode.HandDraw)
actions.Add(new ArtAction(pen.Color, pen.Width, ArtMode.HandDraw));
else if (artMode == ArtMode.Erase)
actions.Add(new ArtAction(Color.White, pen.Width, ArtMode.Erase));
else if (artMode == ArtMode.Line)
actions.Add(new ArtAction(pen.Color, pen.Width, ArtMode.Line));
else if (artMode == ArtMode.Rectangle)
actions.Add(new ArtAction(pen.Color, pen.Width, ArtMode.Rectangle));
else if (artMode == ArtMode.Ellipse)
actions.Add(new ArtAction(pen.Color, pen.Width, ArtMode.Ellipse));
else if (artMode == ArtMode.Circle)
actions.Add(new ArtAction(pen.Color, pen.Width, ArtMode.Circle));
}
private void canvas_MouseMove(object sender, MouseEventArgs e)
{
Cordinates_X.Text = "X: " + e.X;
Cordinates_Y.Text = "Y: " + e.Y;
if (e.Button == MouseButtons.Left)
{
actions[i].points.Add(e.Location);
canvas.Invalidate();
}
}
private void canvas_MouseUp(object sender, MouseEventArgs e)
{
i++;
}
private void canvas_Paint(object sender, PaintEventArgs e)
{
artManager.Draw(e, actions);
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
}
The results I get for HandDraw(free-form line) are not what I expected... The curves have thorns. With smaller pen width the problem is smaller but at larger numbers the problem is worse: Image1, Image2 The issue gets even worse when there a lot of stuff on the canvas.
Any suggetions on how to fix this?