Line is one of the most basic geometric shapes, it is straight, continuous, infinitely long and infinitely thin. A finite continuous part of a line is called **line segment**, though in practice we sometimes call line segments also just *lines*. In flat, non-curved geometries shortest path between any two points always lies on a line.
Line is a one [dimensional](dimension.md) shape, i.e. any of its points can be directly identified by a single number -- the signed distance from a certain point on the line. But of course a line itself may exist in more than one dimensional spaces (just as a two dimensional sheet of paper can exist in our three dimensional space etc.).
Mathematically lines can be defined by equations with space coordinates (see [analytic geometry](analytic_geometry.md)) -- this is pretty important for example for [programming](programming.md) as many times we need to compute intersections with lines; for example [ray casting](ray_casting.md) is a method of 3D rendering that "shoots lines from camera" and looks at which objects the lines intersect. Line equations can have different "formats", the two most important are:
- **point-slope**: This equation only works in 2D space (in 3D this kind of equation will not describe a line but rather a [plane](plane.md)) and only for lines that aren't completely vertical (lines close to vertical may also pose problems in computers with limited precision numbers). The advantage is that we have a single, pretty simple equation. The equation is of form *y = k * x + q* where *x* and *y* are space coordinates, *k* is the [slope](slope.md) of the line and *q* is an offset. See examples below for more details.
- **parametric**: This is a system of *N* equations, where *N* is the number of dimensions of the space the line is in. This way can describe any line in any dimensional space -- obviously the advantage here is that we can can use this form in any situation. The equations are of form *Xn = Pn + t * Dn* where *Xn* is *n*th coordinate (*x*, *y*, *z*, ...), *Pn* is *n*th coordinate of some point *P* that lies on the line, *Dn* is *n*th coordinate of the line's direction [vector](vector.md) and *t* is a variable parameter (plugging in different numbers for *t* will yield different points that lie on the line). DON'T PANIC if you don't understand this, see the examples below :)
As an equation for line segment we simply limit the equation for an infinite line, for example with the parametric equations we limit the possible values of *t* by an interval that corresponds to the two boundary points.
**Example**: let's try to find equations of a line in 2D that goes through points *A = [1,2]* and *B = [4,3]*.
Point-slope equation is of form *y = k * x + q*. We want to find numbers *k* (slope) and *q* (offset). Slope says the line's direction (as dy/dx, just as in [derivative](derivative.md) of a function) and can be computed from points *A* and *B* as *k = (By - Ay) / (Bx - Ax) = (3 - 2) / (4 - 1) = 1/3* (notice that this won't work for a vertical line as we'd be dividing by zero). Number *q* is an "offset" (different values will give a line with same direction but shifted differently), we can simply compute it by plugging in known values into the equation and working out *q*. We already know *k* and for *x* and *y* we can substitute coordinates of one of the points that lie on the line, for example *A*, i.e. *q = y - k * x = Ay - k * Ax = 2 - 1/3 * 1 = 5/3*. Now we can write the final equation of the line:
*y = 1/3 * x + 5/3*
This equation lets us compute any point on the line, for example if we plug in *x = 3*, we get *y = 1/3 * 3 + 5/3 = 8/3*, i.e. point *[3,8/3]* that lies on the line. We can verify that plugging in *x = 1* and *x = 4* gives us *[1,2]* (*A*) and *[4,3]* (*B*).
Now let's derive the parametric equations of the line. It will be of form:
*x = Px + t * Dx*
*y = Py + t * Dy*
Here *P* is a point that lies on the line, i.e. we may again use e.g. the point *A*, so *Px = Ax = 1* and *Py = Ay = 2*. *D* is the direction [vector](vector.md) of the line, we can compute it as *B - A*, i.e. *Dx = Bx - Ax = 3* and *Dy = By - Ay = 1*. So the final parametric equations are:
*x = 1 + t * 3*
*y = 2 + t * 1*
Now for whatever *t* we plug into these equations we get the *[x,y]* coordinates of a point that lies on the line; for example for *t = 0* we get *x = 1 + 0 * 3 = 1* and *y = 2 + 0 * 1 = 2*, i.e. the point *A* itself. As an exercise you may try substituting other values of *t*, plotting the points and verifying they lie on a line.
Drawing lines with computers is a subject of [computer graphics](graphics.md). On specific devices such as [vector monitors](vector_monitor.md) this may be a trivial task, however as most display devices nowadays work with [raster graphics](raster_graphics.md), let's from now on focus only on such devices.
There are many [algorithms](algorithm.md) for line [rasterization](rasterization.md). They differ in attributes such as:
- complexity of implementation
- speed/efficiency (some algorithms avoid the use of [floating point](float.md) which requires special [hardware](hardware.md))
- support of [antialiasing](antialiasing.md) ("smooth" vs "pixelated" lines)
- [subpixel](subpixel.md) precision (whether start and end point of the line has to lie exactly on integer pixel coordinates; subpixel precision makes for smoother animation)
- support for different width lines (and additionally e.g. the shape of line segment ends etc.)
- ...
```
.
XXX XX .aXa
XX XX lXa.
XX XX .lXl
XXX XXX .aal
XX XX lXa.
XX XXX .aXl
XX XX a.
pixel subpixel subpixel accuracy
accuracy accuracy + anti-aliasing
```
One of the most basic line rasterization algorithms is the [DDA](dda.md) (Digital differential analyzer), however it is usually better to use at least the [Bresenham's line algorithm](bresenham.md) which is still simple and considerably improves on DDA.
TODO: more algorithms, code example, general form (dealing with different direction etc.)