Skip to content

Line Creation

Chris Ridley edited this page Oct 21, 2018 · 14 revisions

GoRogue offers a few different line generation algorithms designed to help create "closest-fit" lines between two points on a grid. These include the (popular) Bresenham's line algorithm, a DDA (Digital Differential Analyzer) line generation algorithm, and an orthogonal line generation algorithm.

These algorithms are included in the Lines static class. This static class contains static Get functions, which take two points and an enum value denoting which algorithm to use, and produce an ordered IEnumerable<Coord> of all points considered on a line between those two points, according to the specified algorithm.

Table of Contents

Code Examples

The code examples in this sections use the simple console display library RLNET to help visualize the lines created. The process of creating a project with RLNET installed is fairly straightforward, and is detailed on the RLNET Project Setup page of GoRogue's wiki.

In addition, the code examples on this wiki page assume you have the following "using" statements at the top of your code file:

using GoRogue;
using RLNET;
using System.Collections.Generic;
using System.Linq;

Bresenham's Line Algorithm

This algorithm is by many accounts the most popular in roguelike development. It produces accurate lines quickly in most circumstances. We can simply call the aforementioned Get function, specifying Lines.Algorithm.BRESENHAM as the algorithm, to retrieve a line as determined by this algorithm. The line produced by this algorithm will either be in order from starting point to ending point, or in order from ending point to starting point.

Bresenham's Ordered Line Algorithm

This algorithm is exactly like Bresenham's above, but guarantees that the order of the returned points will be from starting point to ending point, at the cost of potentially being slightly slower. Similar to Bresenham's above, we may call the Get function, specifying Lines.Algorithm.BRESENHAM_ORDERED as the algorithm, to retrieve a line as determined by this algorithm.

Digital Differential Analyzer (DDA)

This algorithm is very similar to Bresenham's line algorithm in the result it yields. The result may vary from Bresenham's result in some cases, but DDA may also prove significantly faster in many cases. The points are also guaranteed to be in order from starting point to ending point. Similar to Bresenham's, we may call the Get function, specifying Lines.Algorithm.DDA as the algorithm, to retrieve a line as determined by this algorithm.

Orthogonal Line Generation Algorithm

This algorithm produces a line that only takes orthogonal steps -- that is, each step of the line will be within one cardinal direction of the last. This may be useful in cases where MANHATTAN distance is involved. Like DDA, this algorithm guarantees the order of the returned points will be from starting point to ending point. Similar to the previous three algorithms, we may call the Get function, specifying Lines.Algorithm.ORTHO as the algorithm, to retrieve a line as determined by this algorithm.

Code Example

The following code produces and displays lines between two points, as generated by any of the above algorithms. There are 4 calls to Lines.Get, one for each line type. The proper line can simply be uncommented to show the line as generated by that algorithm.

        // Initialize "root console" -- the main window of the game.
        public static RLRootConsole RootConsole = new RLRootConsole("terminal8x8.png", 15, 15, 8, 8, 1f, "GoRogue Demo");
        
        private static readonly int windowSize = 15;
        private static Coord start = Coord.Get(1, 2);
        private static Coord end = Coord.Get(9, 13);

        private static List<Coord> line;

        static void Main(string[] args)
        {
            line = Lines.Get(start, end, Lines.Algorithm.BRESENHAM).ToList();
            // line = Lines.Get(start, end, Lines.Algorithm.BRESENHAM_ORDERED).ToList();
            // line = Lines.Get(start, end, Lines.Algorithm.DDA).ToList();
            // line = Lines.Get(start, end, Lines.Algorithm.ORTHO).ToList();

            // The root console's Update event is triggered once per frame,
            // followed by the root console's Render event.  Here, we add the
            // functions we would like to run upon each of those events happening.
            RootConsole.Update += rootConsole_Update;
            RootConsole.Render += rootConsole_Render;

            // Start the main window.
            RootConsole.Run();
        }

        static void rootConsole_Update(object sender, UpdateEventArgs e)
        {
            //Update Logic Here
        }

        static void rootConsole_Render(object sender, UpdateEventArgs e)
        {
            RootConsole.Clear();

            // Render line generated in Main, by first filling the screen
            // with "." symbols, then filling the line in.
            for (int x = 0; x < windowSize; x++)
                for (int y = 0; y < windowSize; y++)
                    RootConsole.Print(x, y, ".", RLColor.White);

            foreach (var point in line)
                RootConsole.Print(point.X, point.Y, "x", RLColor.Yellow);

            RootConsole.Draw();
        }

Output

The following images show the output of the above code using each of the generation algorithms:

Bresenham's Line Algorithm

Bresenham's Ordered Line Algorithm

Digital Differential Analyzer (DDA)

Orthogonal Line Generation Algorithm