I.2 · Mathematical Language
How do two numbers pin down a place?
A coordinate is a signed distance read from an agreed zero. We build the number line, then the plane from two of them, and learn what a point's coordinates, quadrant, displacement and distance each say, and where screens and arrays quietly turn the picture upside down.
A point and its coordinates:
Try a point
A coordinate plane from minus 7 to 7 on both axes. The point P is at minus 3 comma 2, quadrant II (highlighted). Dashed segments run from the point straight to each axis: the vertical one has length |y| and ends on the x-axis, the horizontal one has length |x| and ends on the y-axis. The distance from P to the origin is the square root of 13.
- x-coordinate (signed)
- −3
- y-coordinate (signed)
- 2
- quadrant
- II
- distance to the y-axis
- 3
- distance to the x-axis
- 2
- distance to the origin
- √133.605551…
= exact · ≈ rounded to 6 decimals · the distance to the x-axis is |y|, to the y-axis |x|
(−3, 2) is in quadrant II: x < 0 and y > 0. The distance to the x-axis is |y| = 2 and to the y-axis is |x| = 3: the coordinate you read along one axis is the distance to the OTHER axis.
from −7 to 7, up to 2 decimal places
from −7 to 7, up to 2 decimal places
Try it before reading on. Drag into each of the four corners and watch the signs of and . Then drag it onto an axis, and read what the stage says about its quadrant. Then compare the two distances to the axes with the two coordinates: which coordinate is the distance to which axis? By the end of the chapter you will know how a pair of numbers fixes a place, why a point on an axis is in no quadrant, what the distance between two points is and why Pythagoras supplies it, and why the row of a pixel in an image is not its -coordinate.
Intuition: reading a place from two rulers
Finding a house on a street needs one number: how far along the street. A street is a line, and one signed number fixes a place on a line. Finding a seat in a theatre needs two: which row and which seat in the row. A plane has two independent directions, so a place in a plane needs two numbers, one for each.
A coordinate system is the agreement that makes those numbers mean something: where zero is, which way is positive, and what one step is. Change the agreement and the same place gets different numbers, so the numbers are never the place itself. They are a reading of the place against rulers that somebody chose. Most of the mistakes in this chapter come from forgetting one of the choices, usually which way an axis points.
The quantities of the previous chapter are what the coordinates measure: each coordinate is a signed length, and its unit travels with it. The squares and roots of that chapter return here in one place only, the distance between two points.
Definition: number line, plane and point
Number line. Choose a point on a straight line, a direction to call positive, and a unit of length. The coordinate of a point on the line is the number whose absolute value is the distance from to , with the sign if is on the positive side of and if it is on the other. Each point has exactly one coordinate and each real number is the coordinate of exactly one point. The point has coordinate .
Displacement and distance on the line. For two points with coordinates and , the displacement from to is the signed number
positive when is to the right of , negative when it is to the left, and zero when they are the same point. The distance is its absolute value, . The displacement has a direction and the distance does not: , while .
Cartesian plane. Take two number lines in the plane that cross at their zero points at a right angle. The first, the -axis, is drawn horizontally with positive to the right. The second, the -axis, is drawn vertically with positive upward. The crossing point is the origin . A point has the coordinates when is the coordinate on the -axis of the foot of the perpendicular from to that axis, and is the same for the -axis. The pair is ordered: and are different points.
Quadrants. The axes cut the plane into four open regions, numbered counter-clockwise from the top right:
| Quadrant | Sign of | Sign of |
|---|---|---|
| I | ||
| II | ||
| III | ||
| IV |
The word open matters. A point is in a quadrant only when both coordinates are non-zero and have the signs in the table. A point with or lies on an axis. It is a border between two quadrants and belongs to neither. The origin is on both axes and belongs to no quadrant.
Distance in the plane. The distance between and is
The next sections explain where this comes from. For the origin it reads .
The number line: one number, a direction, a distance
Everything in the plane is built from the line, so begin there. The stage shows two points and on one line. The step from to is drawn below the line as a signed arrow, and the distance is drawn above it as a measurement.
Two points on a line: and
Try a pair (a → b)
A number line from minus 8 to 8. Point a is at minus 3 and point b is at 5. Point a is to the left of point b. The signed step from a to b is 8, and the distance between them is 8.
- point a
- −3
- point b
- 5
- signed step from a to b
- 8
- signed step from b to a
- −8
- distance (no direction)
- 8
- midpoint
- 1
- distance through 0
- 8
b − a has a sign (a direction); |b − a| does not. |a| + |b| is a distance only through 0.
b is to the right of a, so b − a = 8 (the sign says which way) while a − b = −8: the same two points, the opposite direction. The distance |b − a| = 8 has no direction, so it is the same both ways. |a| + |b| = 8 happens to equal the distance, because 0 is between the points (or is one of them).
from −7 to 7, up to 2 decimal places
from −7 to 7, up to 2 decimal places
Swap the two points and watch what changes. The arrow flips direction and the signed step changes sign. The measurement above does not change at all. That is the whole difference between a displacement and a distance, and it is worth saying again in words: a displacement answers “how do I get from here to there?”, and so depends on which is which. A distance answers “how far apart are they?”, and does not.
The stage also shows the midpoint . It is the point exactly half-way, since it is plus half the displacement: . And it shows a tempting wrong answer. If and are on opposite sides of , then is the distance, because the path passes through . If they are on the same side, it is not: , but the points and are apart. The sum of absolute values is a distance via zero, and the stage marks it as such.
The cleanest rule for the distance on a line is the one in the definition, , because it never needs to ask which side of anyone is on.
The plane: two lines at right angles
Now put a second line through , perpendicular to the first. The hero stage is that picture. A point is reached from the origin by walking along the first axis, then in the perpendicular direction. The two dashed legs on the stage are those two walks, read backwards: from straight down (or up) to the -axis, and straight across to the -axis.
Look at what the legs measure. The vertical leg ends on the -axis and has length . The horizontal leg ends on the -axis and has length . So the distance from to the -axis is and the distance to the -axis is . Each distance uses the other coordinate. This is the single most common slip in this topic, and the stage’s verdict line repeats it deliberately.
Quadrants and the axes
The quadrant of a point is decided by the two signs and nothing else. The point has and , so it is in quadrant II. The point is in quadrant II too: the size of a coordinate has no say in the quadrant, only its sign.
An axis point needs separate care, because “not positive” and “negative” are different things. For , is neither positive nor negative. It is zero, the border. The point is on the -axis and is in neither quadrant III nor quadrant IV. A program that writes if x > 0 and y > 0: ... elif ... else: quadrant 4 assigns and even to quadrant IV. The reference code below runs that mistake next to the correct version.
Use the presets on the stage to visit the three kinds of position: a quadrant, a half-axis, and the origin. In each case the verdict line says which, and which quadrants an axis separates.
The distance formula is Pythagoras
Take two points and . Draw a horizontal line through and a vertical line through ; they meet at the corner . Then is horizontal with length , is vertical with length , and the angle at is a right angle, because the axes were chosen perpendicular. In the right triangle the Pythagorean theorem gives
Squares make the absolute values unnecessary, since . Taking the non-negative root, which is what means, gives the distance formula above.
This is a proof only because the theorem is taken as known. In coordinate geometry it is also used as the definition of distance: when a plane is defined as the set of pairs of numbers, distance is declared to be this formula, and the theorem about right triangles becomes a statement that the formula agrees with the geometry. For the hero point and the origin the same triangle has legs and .
The stage below carries the pieces: the displacement , the right-angled corner, the exact squared distance, and the distance itself in its simplest exact form.
Two points: displacement, distance, midpoint
Try a pair (A → B)
A coordinate plane from minus 7 to 7 on both axes. Point A is at minus 3 comma 1 and point B is at 3 comma minus 3. The displacement from A to B is 6 comma minus 4. Dashed legs run horizontally and then vertically between the points and form a right angle at the corner. The distance from A to B is 2 times the square root of 13. The midpoint is 0 comma minus 1.
- point A
- (−3, 1)
- point B
- (3, −3)
- displacement from A to B
- (6, −4)
- displacement from B to A
- (−6, 4)
- distance (no direction)
- 2√137.211103…
- midpoint
- (0, −1)
- taxicab distance
- 10
The displacement B − A has a direction; the distance |AB| does not. Taxicab = |dx| + |dy|.
The displacement from A to B is (6, −4); from B to A it is (−6, 4): reversing the direction flips both signs. The distance 2√13 ≈ 7.211103 is the same either way. The taxicab distance 10 is larger because the path along the axes is not straight (it is equal only when dx or dy is 0).
from −7 to 7, up to 2 decimal places
from −7 to 7, up to 2 decimal places
from −7 to 7, up to 2 decimal places
from −7 to 7, up to 2 decimal places
Four things to try on it.
- Reverse the direction. Swap and (or drag one through the other). The displacement turns into and both components change sign. The distance is unchanged, since each component is squared.
- Make a leg vanish. Put directly above . The segment is vertical, , and the formula collapses to , which is the number-line distance again. A horizontal segment does the same with . The plane distance contains the line distance as the special case.
- Make the points coincide. Then both legs are , the distance is and there is no direction. The stage reports this case in its own words: a zero displacement has no direction.
- Read the exact form. Take and . Then , , and . The exact form is . The decimal is a rounding, and the book writes for it, as in the previous chapter. Only when the squared distance is a perfect square, as in the -- triangle, is the distance a whole number.
Midpoint, and a second kind of distance
The midpoint of the segment averages each coordinate separately:
The second form says: start at and take half of the displacement.
Walking from to along the grid lines (horizontally, then vertically) covers . This is the taxicab distance, after a driver who must keep to the streets. It is never shorter than the straight line, and it is equal to it exactly when the segment is horizontal, vertical, or has zero length. The reason is one line: , and the extra term is zero only if a leg is zero. The stage shows both numbers, and which one is the straight-line distance.
Screen rows are not the -axis
A mathematical plane has growing upward. A picture stored in a computer does not. In an image array, img[row, col], row is the top row and rows are counted downward; screen coordinates in nearly every graphics system do the same. A point in the mathematical picture therefore sits in the array at
where is the number of rows. The pair is swapped (row first), the vertical direction is flipped, and the appears because the first row is numbered and not . The formula undoes itself: .
This stage is limited, on purpose, to integer lattice points: the pixel is the cell whose indices are the integers and , with the point at the bottom left. Other conventions exist (pixel centres at half-integers, the origin at the top left) and change the formula by a constant or a sign. The stage models one convention and states it.
The same pixel, two coordinate systems
Try a pixel
The pixel grid of an image 5 wide and 4 tall drawn as a coordinate plane with y up. The selected pixel is at x = 3, y = 1, which is column 3 and row 2 counted from the top. The bottom row is y = 0.
| row, column | col 0 | col 1 | col 2 | col 3 | col 4 |
|---|---|---|---|---|---|
| row 0 | (0,3) | (1,3) | (2,3) | (3,3) | (4,3) |
| row 1 | (0,2) | (1,2) | (2,2) | (3,2) | (4,2) |
| row 2 | (0,1) | (1,1) | (2,1) | (3,1) | (4,1) |
| row 3 | (0,0) | (1,0) | (2,0) | (3,0) | (4,0) |
- x (column from the left)
- 3
- y (from the bottom)
- 1
- row = H − 1 − y
- 2
- column = x
- 3
- flat index = row · W + col
- 13
- slip: row = H − y
- 3a legal row number, but the wrong pixel (one row too low)
- slip: img[x, y]
- row 3, col 1a legal index, and a different pixel (a silent bug)
row = H − 1 − y · col = x · index = row · W + col · the two slips are what NOT to write
The image is 5 pixels wide and 4 tall. The point (x, y) = (3, 1) is in column 3, and row 2 counted from the TOP, so it is img[2, 3], flat index 2 · 5 + 3 = 13. The slip H − y = 3 would read the pixel one row lower.
from 2 to 10, whole numbers only
from 2 to 10, whole numbers only
from 0 to 4, whole numbers only
from 0 to 3, whole numbers only
The two classic slips are both shown. Using H - y as the row is off by one: for it points at row , which does not exist, and Python raises an IndexError. Writing img[x, y] in place of img[row, col] is worse when the image is square or the indices happen to be in range, because it raises no error and returns a different pixel. A bug that crashes is a gift; a bug that returns the wrong pixel is not.
Worked examples
A distance calculation is five steps, and it pays to see them as steps rather than a trick:
- Subtract each pair of coordinates to get the displacement , in the direction from to .
- Square each component. The sign disappears here.
- Add the two squares. This is the squared distance, and it is exact whenever the coordinates are.
- Root it, using the exact method of the previous chapter: factor out square factors to reach the simplest radical form.
- Check by squaring the answer, and by reversing the direction: the displacement changes sign, the distance does not.
Step through four cases. The first is the -- triangle. The second is the case from above. The third has coordinates with halves, so the arithmetic is on fractions and the root of a fraction is needed. The last starts in quadrant III and ends in quadrant I: the first point has negative coordinates, yet both components of the displacement are positive, because the displacement is a difference.
Worked examples: the distance between two points
Choose a pair of points (A → B)
We want the distance between the two points A and B, a length. It should not matter which point we call first.
Executable reference code
Run the Python examples below to follow the calculations step by step. First the distance work: displacement, squared distance, math.dist, the midpoint, the taxicab distance, and an exact equality that the doubles get wrong.
import math
from fractions import Fraction
def displacement(a, b):
"""The displacement from point a to point b: b - a, component by component."""
return (b[0] - a[0], b[1] - a[1])
def squared_distance(a, b):
dx, dy = displacement(a, b)
return dx * dx + dy * dy
A, B = (1, 2), (4, 6)
step = displacement(A, B) # (3, 4): the direction matters ...
step_back = displacement(B, A) # (-3, -4): ... so reversing it flips both signs
distance = math.hypot(*step) # 5.0: the length of the step
distance_from_points = math.dist(A, B) # 5.0: math.dist takes the two points directly
same_both_ways = math.dist(B, A) == math.dist(A, B) # True: distance has no direction
taxicab = abs(step[0]) + abs(step[1]) # 7: walking along the axes, never shorter than 5.0
midpoint = ((A[0] + B[0]) / 2, (A[1] + B[1]) / 2) # (2.5, 4.0)
# Comparing distances needs no square root: both sides are non-negative, so d1 < d2 exactly when d1**2 < d2**2.
origin = (0, 0)
closer = squared_distance(origin, (3, 4)) < squared_distance(origin, (4, 4)) # 25 < 32: True
# Equal distances, decided exactly. Build Fractions from STRINGS so that no binary rounding enters.
P = (Fraction("0.1"), Fraction("0.7"))
Q = (Fraction("0.5"), Fraction("0.5"))
exact_equal = squared_distance(origin, P) == squared_distance(origin, Q) # True: both are 1/2
float_equal = (0.1**2 + 0.7**2) == (0.5**2 + 0.5**2) # False: 0.49999999999999994 against 0.5
print(step, distance, taxicab, midpoint, exact_equal, float_equal)Then the quadrant decision, with the common mistake and what happens to axis points and to -0.0.
import math
def quadrant(x, y):
"""The quadrant 1..4 of the point (x, y), or None for a point on an axis or the origin: the axes belong to no quadrant."""
if x == 0 or y == 0:
return None
if x > 0:
return 1 if y > 0 else 4
return 2 if y > 0 else 3
def lumpy_quadrant(x, y):
"""The common mistake: the last `else` swallows every point that is not strictly inside quadrants I-III."""
if x > 0 and y > 0:
return 1
elif x < 0 and y > 0:
return 2
elif x < 0 and y < 0:
return 3
else:
return 4
second = quadrant(-3, 2) # 2
fourth = quadrant(3, -2) # 4
on_y_axis = quadrant(0, -4) # None: (0, -4) is on the axis, in no quadrant
at_origin = quadrant(0, 0) # None
wrong_on_axis = lumpy_quadrant(0, -4) # 4: wrong, the point is on an axis
wrong_at_origin = lumpy_quadrant(0, 0) # 4: wrong, the origin is in no quadrant
# -0.0 is a distinct double that compares equal to 0, so == 0 catches it, but a "sign bit" test does not.
negative_zero = quadrant(-0.0, 3) # None: -0.0 == 0
sign_bit_of_negative_zero = math.copysign(1, -0.0) # -1.0: the sign bit says "negative" for a zero
print(second, fourth, on_y_axis, wrong_on_axis, negative_zero)Finally the picture-to-array conversion, with the two slips from the pixel stage run on a real array.
import numpy as np
H, W = 4, 5
img = np.arange(H * W).reshape(H, W) # img[row, col]: row 0 is the TOP row, the cell number counts left to right, then down
def to_row_col(x, y, height=H):
"""Lattice point (x, y) of the math plane (y grows UP) -> array indices (row, col) (row grows DOWN)."""
return height - 1 - y, x
x, y = 2, 0 # the bottom row of the picture
row, col = to_row_col(x, y) # (3, 2): the last row of the array
pixel = img[row, col] # 17
flat_index = row * W + col # 17: the same cell in the flattened array
same_flat = img.ravel()[flat_index] == pixel # True
back_to_y = H - 1 - row # 0: the formula undoes itself, so the round trip returns y
# The math view of the same data: flip the rows once, then img_math[y, x] is the pixel at the point (x, y).
img_math = np.flipud(img)
same_pixel = img_math[y, x] == img[row, col] # True
# Two classic slips.
try:
img[H - y, x] # off by one: row H does not exist
except IndexError:
off_by_one_fails = True
swapped = img[x, y] # 10: in range, no error, and a DIFFERENT pixel (row 2, column 0). A silent bug.
print(row, col, pixel, flat_index, swapped)Two observations about the first file. The comparison closer uses squared distances and never takes a root. This is legitimate because both sides are non-negative and squaring is strictly increasing on non-negative numbers, so exactly when . Comparing without roots is both faster and exact, and nearest-neighbour searches do it all the time. And the last lines build two Fractions from strings. A Fraction made from the float 0.1 would carry the binary rounding along with it.
Explore: change the parameters
These questions have definite answers; check them against the stages.
- On the point stage, find every point with integer coordinates in the range to , both coordinates non-zero, whose distance to the origin is a whole number. (There are exactly eight, all of the -- family.)
- On the point stage, drag along a circle around the origin of radius . Which quantity stays fixed, and which quantities change?
- On the point stage, set and . Which quadrant? What are the distances to the two axes? Is the distance to the origin rational?
- On the line stage, set and , then change to . What happens to the signed step, the distance, and the “via zero” number?
- On the segment stage, put and move along the line . What is the ratio of the taxicab distance to the straight-line distance, and does it depend on where is?
- On the pixel stage, make the image , put the point at the top row, then at the bottom row. Which row index does each have?
Common mistakes
Numerical considerations
The mathematics above is exact. The doubles a program uses are not, and the distance formula meets two problems.
Equality. Whether two points are equally far from the origin is a question about whether two sums of squares are equal, and a test with == on doubles gets it wrong for perfectly ordinary decimals. The points and both have squared distance exactly , because . A double holds and only approximately, so 0.1**2 + 0.7**2 is 0.49999999999999994 while 0.5**2 + 0.5**2 is exactly 0.5. The table shows the exact value next to the double for several points. A row marked “no” is a case where the program’s answer is a different number from the true one.
| point | Python | exact x² + y² | double (what the program holds) | agree? |
|---|---|---|---|---|
| (0.1, 0.7) | 0.1**2 + 0.7**2 | 0.5 | 0.49999999999999994 | ⚠ no |
| (0.5, 0.5) | 0.5**2 + 0.5**2 | 0.5 | 0.5 | yes |
| (0.3, 0.4) | 0.3**2 + 0.4**2 | 0.25 | 0.25 | yes |
| (0.6, 0.8) | 0.6**2 + 0.8**2 | 1 | 1 | yes |
| (0.1, 0.2) | 0.1**2 + 0.2**2 | 0.05 | 0.05000000000000001 | ⚠ no |
| (1.1, 2.2) | 1.1**2 + 2.2**2 | 6.05 | 6.050000000000001 | ⚠ no |
| (2.3, 0.4) | 2.3**2 + 0.4**2 | 5.45 | 5.449999999999999 | ⚠ no |
Overflow and underflow. Squaring is where large and small numbers go wrong. For the point , the true distance is , which a double holds without difficulty. But the naive math.sqrt(x*x + y*y) computes first, which is beyond the largest double, so the intermediate result is inf and so is the answer. For tiny coordinates such as it is the squares that underflow to 0.0, so the naive answer is 0.0 where the true distance is about . Python’s math.hypot and math.dist scale their arguments internally and return the right size for both. Use them in code that may meet extreme values; the formula on paper is unchanged.
Negative zero. The double -0.0 is a separate value from 0.0 that compares equal to it. The test x == 0 therefore catches it, and the quadrant code above treats as an axis point. But anything that reads the sign bit (math.copysign(1, x), or formatting the number) sees -0.0 as negative. A sign test written with < and > is safe; one written with the sign bit is not.
Connections to engineering and machine learning
- Images are arrays. Every digital image is a grid of pixels addressed by row and column, with row on top. Moving between a mathematical picture and an array, between a plotting library and an image library, or between two libraries with different origins is exactly the conversion in this chapter. Mistakes here produce upside-down or mirrored output, silently.
- Bounding boxes. Object detectors describe a rectangle as a corner plus a width and height,
(x, y, w, h), or as two corners,(x1, y1, x2, y2), and libraries differ on whether points down and which corner is the anchor. Check the convention before comparing boxes from two sources. - Distance between feature vectors. A data point with two features is a point in a plane, and its distance to another is the formula above. The nearest-neighbour method picks the data point at the smallest distance, and clustering methods group points by it. The distance is only meaningful if the two axes are comparable: a feature in metres and one in seconds cannot be mixed (see units), and a feature measured in thousands will dominate one measured in tenths.
- Squared distance in practice. The squared Euclidean distance is the cost that least-squares methods and -means minimise. It is differentiable at zero where the distance is not, and it avoids the root altogether.
- Looking ahead. In Vectors the displacement from to becomes an object of its own, , and the point is recovered as . The distance formula returns there as the length of a vector.
Exercises
Answer each question and press Check. A wrong answer tells you which mistake it looks like. After one attempt you may open a worked solution.
Summary and checkpoints
- A coordinate is a signed distance from an agreed zero, along an agreed positive direction. On a line, the displacement from to is , and the distance is .
- A point in the plane is an ordered pair . The distance from the point to the -axis is and to the -axis is .
- The quadrant is decided by the two signs. A point with a zero coordinate is on an axis and in no quadrant; the origin is in none.
- The distance between and is , which is Pythagoras on the right triangle with legs and . The displacement has a direction, the distance does not. The midpoint averages each coordinate.
- Compare distances through their squares, which stay exact. The taxicab distance is never shorter than the straight line.
- In an array, row is the top and row , column . Never assume a library’s origin.
- In code: use
math.distandmath.hypotfor extreme values, compare with a tolerance or exactly, and write every sign test with a case for zero.
Checkpoints. You are ready to move on when you can, without looking:
- Say which quadrant is in, and why is in none.
- Give the distance from to each axis, and say which coordinate each uses.
- Compute the displacement and the distance from to , and say what changes when the points are swapped.
- Write in simplest form and say why the answer is exact.
- Convert the point in a picture rows high into a row and a column of an array.