# HPQ Images

HPQ images are mathematical images. I discovered them around 2019.

## Software

- hpq-fb - display HPQ images on the Linux framebuffer device
- hpq-png - write an HPQ image to a PNG file
- hpq-seq - write some HPQ q-sequences
- hpq.h - library for HPQ images

These programs and libraries are part of Misk. I use hpq-fb to explore the images and hpq-png to save them.

## Definition

In an HPQ image, a function p#(q, (x, y)) is applied to every pixel. The #, q, x, y, and output of the function are nonnegative integers. The function is called a painter. The # is called the identifier (ID). The q is called the q-argument. The x and y are the horizontal and vertical coordinates of a pixel, respectively. Pixel (x, y) is white if p#(q, (x, y)) = 0, otherwise it is black.

For pixel (x, y), the pixel to its right is at (x + 1, y), and the pixel below it is at (x, y + 1).
The top-left pixel is at (x_{0}, y_{0}), where x_{0} and y_{0}
are nonnegative integers called x-offset and y-offset, respectively. Pixel (0, 0) is called the origin.

There are 50 defined painters, 0 through 49, divided into 10 classes, 0 through 9.
They are defined in such a way that p#(q, (x, y)) = p#(q, (y, x)).
Painters in odd classes divide by q, so q = 0 is undefined for them.
The following is a list of all painters, where **&** denotes bitwise AND, **|** denotes bitwise inclusive OR,
**^** denotes bitwise exclusive OR, ***** denotes multiplication, which has the highest precedence, and **%** denotes modulo:

- Class 0
- p0 = (x & y) & q
- p1 = (x | y) & q
- p2 = (x ^ y) & q
- p3 = (x + y) & q
- p4 = (x * y) & q

- Class 1
- p5 = (x & y) % q
- p6 = (x | y) % q
- p7 = (x ^ y) % q
- p8 = (x + y) % q
- p9 = (x * y) % q

- Class 2
- p10 = (x * x & y * y) & q
- p11 = (x * x | y * y) & q
- p12 = (x * x ^ y * y) & q
- p13 = (x * x + y * y) & q
- p14 = (x * x * y * y) & q

- Class 3
- p15 = (x * x & y * y) % q
- p16 = (x * x | y * y) % q
- p17 = (x * x ^ y * y) % q
- p18 = (x * x + y * y) % q
- p19 = (x * x * y * y) % q

- Class 4
- p20 = (q * x & q * y) & q
- p21 = (q * x | q * y) & q
- p22 = (q * x ^ q * y) & q
- p23 = (q * x + q * y) & q
- p24 = (q * x * q * y) & q

- Class 5
- p25 = (q * x & q * y) % q
- p26 = (q * x | q * y) % q
- p27 = (q * x ^ q * y) % q
- p28 = (q * x + q * y) % q
- p29 = (q * x * q * y) % q

- Class 6
- p30 = ((q & x) * x & (q & y) * y) & q
- p31 = ((q | x) * x & (q | y) * y) & q
- p32 = ((q ^ x) * x & (q ^ y) * y) & q
- p33 = ((q + x) * x & (q + y) * y) & q
- p34 = ((q * x) * x & (q * y) * y) & q

- Class 7
- p35 = ((q & x) * x & (q & y) * y) % q
- p36 = ((q | x) * x & (q | y) * y) % q
- p37 = ((q ^ x) * x & (q ^ y) * y) % q
- p38 = ((q + x) * x & (q + y) * y) % q
- p39 = ((q * x) * x & (q * y) * y) % q

- Class 8
- p40 = ((q & x) * x + (q & y) * y) & q
- p41 = ((q | x) * x + (q | y) * y) & q
- p42 = ((q ^ x) * x + (q ^ y) * y) & q
- p43 = ((q + x) * x + (q + y) * y) & q
- p44 = ((q * x) * x + (q * y) * y) & q

- Class 9
- p45 = ((q & x) * x + (q & y) * y) % q
- p46 = ((q | x) * x + (q | y) * y) % q
- p47 = ((q ^ x) * x + (q ^ y) * y) % q
- p48 = ((q + x) * x + (q + y) * y) % q
- p49 = ((q * x) * x + (q * y) * y) % q

## Example

For an HPQ image with width 3, height 2, x-offset x_{0} = 1, and y-offset y_{0} = 2,
the pixels have the following coordinates:

(1, 2) | (2, 2) | (3, 2) |

(1, 3) | (2, 3) | (3, 3) |

Painter 8 with q-argument 4 is applied to every pixel as follows:

- p8(4, (1, 2)) = (1 + 2) % 4 = 3
- p8(4, (2, 2)) = (2 + 2) % 4 = 0
- p8(4, (3, 2)) = (3 + 2) % 4 = 1
- p8(4, (1, 3)) = (1 + 3) % 4 = 0
- p8(4, (2, 3)) = (2 + 3) % 4 = 1
- p8(4, (3, 3)) = (3 + 3) % 4 = 2

The pixels are colored as follows:

Black | White | Black |

White | Black | Black |

Pixel (2, 2) is white because p8(4, (2, 2)) = 0. Pixel (1, 2) is black because p8(4, (1, 2)) ≠ 0.

## Observations

- HPQ images are symmetric around the line y = x.
- The Sierpinski sieve or variations of it seem to occur in painters 0, 5, 6, 20, 30, 31, 32, 35, and 36.
- Cantor dust or variations of it seem to occur in painters 1, 40, 45, and 46.
- The box fractal or variations of it seem to occur in painters 25, 26, 27, and 35.
- Painter 9 visualizes the factors of its q-argument.

## Demo

Here is an interactive demo of HPQ images. It has options that let you select a painter and input its q-argument to paint a canvas. Note that the options are limited in comparison with those of the main program hpq-png.

Program | Painter | Q-argument | Offset | Length |
---|---|---|---|---|

Demo | 8 or 25 | 1 to 4294967295 | 0 | 256 |

Main | 0 to 49 | 0 to 4294967295 | 0 to 4294967295 | 1 to 32768 |

## Gallery

Here are some images written using hpq-png. They are 256 pixels in width and height. Their captions show the painter and q-argument used.