DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Draw, Plot 2d Line In C# (csharp) - Bresenham's Line Algorithm

04.26.2007
| 1567 views |
  • submit to reddit
        based on wikipedia
    public interface ISetPixel
    {
        void SetPixel(Point point);
    }
    public partial class Algorithms2D
    {
        public delegate void SetPixel(Point point);
        public static void Line<G>(Point p0,Point p1,G plot)
            where G:ISetPixel
        {
            int x0=p0.X;
            int y0=p0.Y;
            int x1=p1.X;
            int y1=p1.Y;
            bool steep=abs(y1-y0)>abs(x1-x0);
            if (steep)
            {
                swap(ref x0,ref y0);
                swap(ref x1,ref y1);
            }
            if (x0>x1)
            {
                swap(ref x0,ref x1);
                swap(ref y0,ref y1);
            }
            int deltax=x1-x0;
            int deltay=abs(y1-y0);
            int error=-deltax/2;
            int ystep;
            int y=y0;
            if (y0<y1) ystep=1; else ystep=-1;
            for (int x=x0;x<x1;x++)
            {
                if (steep) plot.SetPixel(new Point(y,x)); else plot.SetPixel(new Point(x,y));
                error=error+deltay;
                if (error>0)
                {
                    y=y+ystep;
                    error=error-deltax;
                }
            }
        }
        struct CSetPixel:ISetPixel
        {
            public CSetPixel(SetPixel setPixel)
            {
                this.setPixel=setPixel;
            }
            SetPixel setPixel;
            #region ISetPixel Members
            public void SetPixel(Point point)
            {
                setPixel(point);
            }
            #endregion
        }
        public static void Line(Point p0,Point p1,SetPixel plot)
        {
            Line<CSetPixel>(p0,p1,new CSetPixel(plot));
        }
        private static int abs(int p)
        {
            return Math.Abs(p);
        }
        private static void swap<T>(ref T x0,ref T y0)
        {
            T z=x0;
            x0=y0;
            y0=z;
        }
    }

unit tests (c# 3.0):

    [TestFixture]
    public class Line
    {
        [Test]
        public void LineDiagonal()
        {
            List<Point> l = new List<Point>();
            Algorithms2D.Line(new Point(0,0),new Point(3,3),z=>l.Add(z));
            Assert.AreEqual(3, l.Count);
            Assert.AreEqual(new Point(0, 0), l[0]);
            Assert.AreEqual(new Point(1, 1), l[1]);
            Assert.AreEqual(new Point(2, 2), l[2]);
        }
        [Test]
        public void Line45()
        {
            List<Point> l = new List<Point>();
            Algorithms2D.Line(new Point(0, 0),new Point(6, 3), z => l.Add(z));
            Assert.AreEqual(6, l.Count);
            Assert.AreEqual(new Point(0, 0), l[0]);
            Assert.AreEqual(new Point(1, 0), l[1]);
            Assert.AreEqual(new Point(2, 1), l[2]);
            Assert.AreEqual(new Point(3, 1), l[3]);
            Assert.AreEqual(new Point(4, 2), l[4]);
            Assert.AreEqual(new Point(5, 2), l[5]);
        }
    }