You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
8.0 KiB
Markdown

2 years ago
# Line
1 year ago
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.
2 years ago
1 year ago
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.).
2 years ago
```
1 year ago
/ | \ .'
/ ________ | \ .'
/ | \ .'
/ | \ .'
2 years ago
```
1 year ago
*some lines, in case you haven't seen one yet*
2 years ago
8 months ago
## Representing Lines With Equations
2 years ago
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.
8 months ago
## Formulas
Here let be formulas for computing various things related to lines and line segments.
Consider two dimensional plane. Let *L* be a line (or line segment) going from point *L1 = [L1x,L1y]* to point *L2 = [L2x,L2y]*. Let *dx = L2x - L1x* and *dy = L2y - L1y*. Let *K* be another line (or line segment). Let *P = [Px,Py]* be a point.
- **line segment [length](length.md)**: Use [Pythagorean theorem](pythagorean_theorem.md): *length(L) = sqrt(dx^2 + dy^2)*. The same goes for a line in 3D.
- **determine which side of line L point P lies on**: A simple way is to use the simple formula for [triangle](triangle.md) winding, i.e. determine if triangle *[L1,L2,P]* goes clockwise or counterclockwise. This can also determine if the point lies exactly on the line (i.e. lies on neither side).
- **shortest distance of point P from line L**: TODO
- **intersection of lines (or line segments) L and K**: Represent the lines with their equations (see above), preferably parametric (allows any angle), put both points equal and solve the system of equations (watch out for the cases with no or many solutions). For line segments you also additionally have to check whether the intersection you find lies within BOTH line segments (with parametric representations this is easily done by checking if both parameters you get as a solution lie in the range 0 to 1).
- **angle between lines L and K**: TODO
- **distance of lines P and L**: TODO
- **project point P orthogonally to line L**: TODO
- TODO: more
TODO: 3D lines
2 years ago
## Line Drawing Algorithms
1 year ago
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.)