/* Diagonal stripe pattern generator. ./stripes > output.pgm Doing this with a transformation matrix would be more straightforward (rotate and scale screen coordinates, then color odd/even rows). This file does it the less obvious way, without using transcendental functions. */ #include #include #include #ifdef _WIN32 #include #include #endif int main(int argc, char **argv) { int width, height, x, y; int a, b, offset, direction, parity; if( argc != 3 || (width = atoi(argv[1])) <= 0 || (height = atoi(argv[2])) <= 0 ) { return printf("%s \n", *argv); } if( width >= 0x8000 || height >= 0x8000 ) return !puts("Output size too large."); #ifdef _WIN32 setmode(STDOUT_FILENO, O_BINARY); #endif srand(time(NULL)); /* Generate stripe slopes. */ a = (int)((double)rand() / RAND_MAX * (width / 10 + 1)) + 5; b = (int)((double)rand() / RAND_MAX * (height / 10 + 1)) + 5; direction = rand() > RAND_MAX / 2; /* Generate shift offset. Since stripe lines extend infinitely, we only need to shift in one direction. */ offset = (int)((double)rand() / RAND_MAX * a * 2); printf("P5\n%d %d\n255\n", width, height); for(y = 0; y < height; y++) { for(x = offset; x < width + offset; x++) { /* Divide screen into rectangles of sizes (a,b), then find points within those rectangles that are below the line of slope b/a. */ if( direction ) parity = x % a * b > (b - 1 - y % b) * a; else parity = x % a * b > y % b * a; /* Previous step would have generated lots of triangles. If we flip half of them, the triangles would align, creating the stripe pattern. */ parity ^= ((x / a) + (y / b)) & 1; fputc(parity * 255, stdout); } } return 0; }