Generators of projective transformations:

(x', y') = A(x, y)

where A is a real 2 by 2 matrix.

x' = x + a

The two above generate all of the affine transformations.

Perhaps those two can best be combined as

(x, y) → (ax + by + c, dx + ey + f)

This correctly counts the 6 degrees of affine freedom.

Lets see what happens it we introduce one projective transformation which is not affine. Consider two planes in 3 space:

- Plane 1: (1, x, y)
- Plane 2: (x, 1, y)

Consider the projection thru the origin (0, 0, 0). Consider a different point P in 3 space with integer coordinates (X, Y, Z). The line thru the origin and P pierces plane 1 at (1, Y/X, Z/X) and plane 2 at (X/Y, 1, Z/Y). (1, Y/X, Z/X) → (X/Y, 1, Z/Y).

In local coordinates (Y/X, Z/X) → (X/Y, Z/Y).

Equivalently (x, y) → (1/x, y/x) is the same transformation.

Stirring with (x, y) → (x+a, y) gives

(x, y) → (1/(x+a), y/(x+a))
In the other order we get

(x, y) → (1/x + a, y/x)

adding (x, y) → (y, x) yields

(x, y) → (1/y + a, x/y) and

(x, y) → (y/x, 1/x + a).

I think this converges at

(x, y) → ((dx + ey + f)/(ax + by + c), (gx + hy + i)/(ax + by + c)).

The line ax + by + c = 0 is the inverse image of the line at infinity.
If k is a non zero real then multiplying a, b, c,... i each by k produces the same transformation.
This indicates 8 degrees of freedom in agreement with the projective square.
These transformations map rational points onto rational points when the coefficients are rational.
This indicates that an n-dimensional projection has (n+1)^{2}−1 degrees of freedom.

The following code says that the composition of two of these projections leaves collinear points, collinear.

(define (P a b c d e f g h i) (lambda (p) (apply (lambda (x y) (let* ((D (/ (+ (* a x) (* b y) c)))) (list (* D (+ (* d x) (* e y) f)) (* D (+ (* g x) (* h y) i))))) p))) (define p1 (P 3 2 4 5 3 6 5 4 7)) (define p2 (P 2 -5 4 3 2/3 5 4 4 5)) (define (p3 x) (p1 (p2 x))) (ylppa ((fileVal "Matrix") '() 0 zero? 1 + - * /) (lambda (rm matm matinv ip tr det i? v= m=) (det (map (lambda (p) (cons 1 p)) (list (p3 '(2 3)) (p3 '(3 5)) (p3 '(9/2 8))))))) ; => 0