You are on page 1of 466

2D Computer Graphics in modern c++ and

standard library
Håkan Blomqvist
This book is for sale at http://leanpub.com/2dcomputergraphicsinmoderncandstandardlibrary

This version was published on 2023-05-14

This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing
process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and
many iterations to get reader feedback, pivot until you have the right book and build traction once
you do.

© 2023 Håkan Blomqvist


Contents

1 2D Drawing Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1 History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Standard Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Compile Code Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 Prerequisite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Draw Pixels with Standard Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

3 Texture Generation with Standard Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

4 Time to draw some lines with Standard Library . . . . . . . . . . . . . . . . . . . . . . . . . . 11

5 There are no straight curves, only curved lines . . . . . . . . . . . . . . . . . . . . . . . . . . 19

6 Rectangles with Standard Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

7 Circles with Standard Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

8 Triangles with Standard Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

9 Animation with Standard Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

10 Drawing Charts and a Font . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

11 Presentation, Collaboration, and Investigation . . . . . . . . . . . . . . . . . . . . . . . . . . 36


11.1 Presentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
11.2 Draw a bar chart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
11.3 Draw a pie chart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
11.4 Draw a donut chart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
11.5 Draw a table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
11.6 Draw a more advanced chart 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
11.7 Draw a more advanced chart 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
11.8 Collaboration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
11.9 Investigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

12 PPM++ header-only library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58


CONTENTS

13 In the Rearview Mirror . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

14 Appendix A: Source Code Listings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60


1 2D Drawing Basics
We have all been there when you just want to present som data in a nice and graphical way. You
start by implementing a GUI library so that you can set up a canvas to draw on… but then what?
Or you download and build a library that can handle reading and writing PNG images, as you need
lossless images. Or you do the same just to find out a files entropy. Or you’re coding on a game
and want to test the look of animation sprites in a parallax setting. What ever the reason is… it’s
too complicated to do and takes more time than you would consider doing. So no presentation, no
collaboration, and no investigation using graphics.
It should just be easy to create graphics in standard C++. And this book is all about that. How do
we draw a pixel, a line, or a circle? That is questions we going to answer.

1.1 History
2D Drawings with computers started out in, as most things computer related, in academia. It was
first created as a visualization tool for scientists and engineers in US government and US corporate
research centers such as Bell Labs and Boeing in the 1950s. Later the tools would be developed at
Universities in the 60s and 70s at places such as Ohio State University, MIT, University of Utah,
Cornell, North Carolina and the New York Institute of Technology. The early breakthroughs that
took place in academic centers continued at research centers such as the famous Xerox PARC in the
1970s. These efforts broke first into broadcast video graphics and then major motion pictures in the
late 70¹s and early 1980s. Computer graphic research continues today around the world, now joined
by the research and development departments of entertainment and production companies.
Since 1974 ACM SIGGRAPH has evolved to become an international community of researchers,
artists, developers, filmmakers, scientists, and business professionals who share an interest in
computer graphics and interactive techniques. Each year the latest and greatest with this research
gets presented.

1.2 Standard Library


There are no support for drawing in the Standard Library. There are no media support what so ever
in the Standard Library. And there are no need to. With the tools available to us, we will be able to
draw pixels, lines and circles.
1 2D Drawing Basics 3

1.3 Compile Code Examples


All code is compiled using clang++, but of course works fine with g++. Everything is C++17 except
std::lerp, as its part of C++20 (a C++17 solution will be presented).

1.4 Prerequisite
You’ll need to already know how to program in C++. This book is about how to draw and and not
about how to program.
2 Draw Pixels with Standard Library
We’re using RGB elements to draw a pixel in C++. To handle RGB elements as one unit for
convenience there is something called std::tuple.
Reference: https://en.cppreference.com/w/cpp/utility/tuple e.g. a function that takes three integers
as input and returns it as a tuple
01_tuples.cpp demonstrates the usage of ‘std::tuple’ in C++17. It uses a tuple to store and
manipulate RGB color elements as a single entity. The code includes the ‘’ headers and defines
a function ‘get_rgb_elements_as_a_tuple’ that takes three integers (r, g, and b) and returns a tuple
containing these integers.
The ‘main’ function initializes three sets of RGB values (r1, g1, b1, r2, g2, b2, and r3, g3, b3). Initially,
only the first set (r1, g1, b1) is given values, while the other two sets are initialized to 0.
The code then prints the initial RGB values of all three sets. Next, it calls ‘get_rgb_elements_as_-
a_tuple’ with the first set of RGB values (r1, g1, b1) and assigns the returned tuple to ‘rgb’.
Two different methods are then used to “unroll” the ’ ’ tuple into the other two sets of RGB values:

1. “unroll #1”: Using ‘std::get’ to access individual elements of the tuple by index and assigning
them to r2, g2, and b2.
2. “unroll #2”: Using ‘std::tie’ to unpack the tuple into r3, g3, and b3.

After each unroll, the RGB values of all three sets are printed to verify that the tuple has been
correctly unpacked into the second and third sets of RGB values.
take a look in Appendix A: 01_tuples.cpp
Now that we know how to store and unroll a tuple of rgb elements. Let’s talk about adding rgb
tuples to an image — to set a pixel where we want it to be in the image.
But, before that we need to talk about the way computers memory (1D) is physically represented
and the representation of an image (2D). To know where to store the tuple we need to translate (2D)
into (1D). To store the pixel at a certain x and y in the image, but in memory.

index = x + width ∗ y
2 Draw Pixels with Standard Library 5

X + width * Y = 2 + 10 * 3 = 32 Index = 32
Let’s create a function that handles the index-calculations for us. A function that takes X and Y as
input and returns the index.
Or, take a look in Appendix A: 02_index.cpp
Besides calculating index we need to know how many tuples with we need to store in a std::vector
for a beforehand defined width and height of an image. For instance, an image that has a width of
640 and a height of 360 is 640 * 360 (230400) in size for a std::vector with those dimensions.
Reference: https://en.cppreference.com/w/cpp/container/vector As always we need to include the
header: #include
To set the vector container size we calculate it by multiplying the image width times the height.
We use the Resize function in std::vector to set the size of the vector. Then we can use the vectors
operator[] and operator= for index and assigns.
Also, why not assign the color black to all the pixels while we are at it, as a clear image function.
For the source code, take a look in Appendix A: 03_calcsize.cpp
Note that this code example uses float for the rgb elements. We do that as it’s preferred later when
we work with colors and that red, green and blue are a float number between 0.0 - 1.0 and not an
integer.Enough with the calculations of metadata about the image. It’s time to draw some pixels
and save it into a textile. Yes, there are a few image formats that are text based. In this book we’re
going to use PPM file format. This graphics format comes from the open source Netpbm project that
is several graphics programs and a programming library — used mainly in the Unix world. PPM
stands for Portable PixMap format and is portable due to its written as ASCII (Type: P3). A PPM
2 Draw Pixels with Standard Library 6

file consists of two parts: a header and the image data. Don’t worry about the it being ASCII, PPM
can be converted to PNG, JPG or any other format. Here’s how the PPM format looks like as ASCII:

1 P3 # "P3" means this is a RGB color image in ASCII


2 3 2 # "3 2" is the width and height of the image in pixels
3 255 # "255" is the maximum value for each color
4 # The part above is the header
5 # The part below is the image data: RGB triplets
6 255 0 0 # red
7 0 255 0 # green
8 0 0 255 # blue
9 255 255 0 # yellow
10 255 255 255 # white
11 0 0 0 # black

The header starts with the ”P3” indicator. Second line contains the width and height of the image
separated with a whitespace. Third line has the number 255 stated, this is going to be used for all
examples in this book. The 255 is about the max value for each rgb element. And as we see below
the header, each pixel is represented as three integer values between 0 - 255 for rgb.
Include header: #include Reference: https://en.cppreference.com/w/cpp/io/basic_fstream
For the source code, take a look in Appendix A: 04_helloworld.cpp

04_helloworld_square.ppm

04_helloworld.ppm

That’s great, but even more awesome if we also could read a PPM image too.
For the source code, take a look in Appendix A: 05_randomwalker.cpp
2 Draw Pixels with Standard Library 7

05_randomwalker.ppm

Now, we have a lot of code to go through in the 05 example. There are one new header and few new
functions that needs some explanation.
Example 05 was not only about reading a PPM file. We implemented a random walker. Let go
through the code function by function.
Reference: https://en.cppreference.com/w/cpp/header/random
Add random header to the file: #include
Following functions are new:

• walker
• update_x_and_y
• read_image
• get_color
• get_width_and_height
• startsWithCaseInsensitive

We start by reading 04_helloworld.ppm into image1 and at the same time set width and height from
the PPM file using get_width_and_height. read_image uses the helper function startsWithCaseIn-
sensitive to sort through the PPM data. get_color is used to read the rgb color.
We use the walker function to implement a random walker algorithm. Walker uses random function
to randomize the walker. For each walker generation we use the update_x_and_y function to move
the walker in a random direction.
3 Texture Generation with Standard
Library
Neat, now we can draw pixels. Let’s play around with that a bit and generate different types of
textures that can be useful to have.
Let’s generate textures by using boolean XOR (Exclusive-OR) AND and OR.
The code generates and saves three different textures based on bitwise operations: XOR, AND, and
OR. To achieve this, it defines several functions to create, manipulate, and save the images. The
‘get_index’ function is responsible for converting 2D grid coordinates (x, y) into a 1D array index,
while the ‘calc_size’ function calculates the total number of elements in a 2D grid. The ‘clear_-
image’ function sets all the pixels of an image to a given color, effectively clearing the image.
The code also provides three functions to create different textures: ‘draw_xor’, ‘draw_and’, and
‘draw_or’. Each function iterates through the image’s pixels and calculates the corresponding
bitwise operation (XOR, AND, or OR) on the x and y coordinates of each pixel. The resulting value
is then used as the color intensity for that pixel.
In the ‘main’ function, the program starts by initializing the image vector and color tuple, followed
by resizing the image vector based on the calculated size. The image is then cleared using a dark
blue color. After that, the XOR texture is generated and saved to the “06_xor_texture.ppm” file.
Subsequently, the AND texture is generated and saved to the “06_and_texture.ppm” file. Finally,
the OR texture is generated and saved to the “06_or_texture.ppm” file.
For the source code, take a look in Appendix A: 06_xor_and_or_texture.cpp

06_xor_texture.ppm
3 Texture Generation with Standard Library 9

06_and_texture.ppm

06_or_texture.ppm

XOR, AND and OR type of textures are the simplest ones. It’s just x XOR y, x AND y, or x OR y.
These textures are nice to have if you just want to do an example. Excellent for prototyping use.
Procedural texture generation is another way to create textures. With random noise we can generate
textures like clouds, marble, and wood.
Reference: https://en.cppreference.com/w/cpp/numeric/math/fabs
This code generates and saves three different textures: Clouds, Marble, and Wood. It includes several
functions to create, manipulate, and save images. The ‘get_index’, ‘calc_size’, ‘clear_image’, and
‘save_image’ functions were explained in the previous response, and they serve the same purpose
here. Additionally, a new function ‘generate_noise’ is introduced, which fills a noise vector with
random values in the range of 0.0 to 1.0.
The ‘smooth_noise’, ‘turbulence’, and texture generation functions (‘generate_cloud’, ‘generate_-
marble’, and ‘generate_wood’) are the core of this code. The ‘smooth_noise’ function calculates a
bilinear interpolation of the noise values at a given position, while the ‘turbulence’ function sums
up the smooth noise values at different scales to generate more complex patterns.
The ‘generate_cloud’ function uses the ‘turbulence’ function to create a cloud-like texture. In
contrast, the ‘generate_marble’ function calculates a sine pattern that is distorted by turbulence to
mimic the appearance of marble. Finally, the ‘generate_wood’ function creates a wood-like texture
by calculating the distance from the center of the image and applying a sine pattern combined with
turbulence.
In the ‘main’ function, the program initializes the noise and image vectors and resizes them based on
3 Texture Generation with Standard Library 10

the calculated size. The image is then cleared using a dark blue color. The noise vector is generated,
and the Cloud texture is created and saved to the “07_cloud_texture.ppm” file. Subsequently, the
Marble texture is generated and saved to the “07_marble_texture.ppm” file. Finally, the Wood texture
is generated and saved to the “07_wood_texture.ppm” file.
For the source code, take a look in Appendix A: 07_clouds_marble_wood_texture.cpp

07_cloud_texture.ppm

07_marble_texture.ppm

07_wood_texture.ppm

Uses bilinear interpolation to smooth the noise. Turbulence is added for marble and wood.
Procedural generation in itself is an interesting topic.
4 Time to draw some lines with
Standard Library
Well, not yet, first we go through some theory about light and color that is good to know.
A C++ program designed to manipulate images in the PPM format, specifically the P3 (ASCII) format.
It includes various functions to perform image manipulation tasks such as creating a negative image,
adjusting brightness and darkness, converting to grayscale, swapping color channels, and blending
two images. The program uses the Standard Library and has a main function to perform user-
specified manipulations on an input image file and save the result to an output file.
The code begins by importing necessary headers and declaring several utility functions like
‘startsWithCaseInsensitive’, ‘get_index’, ‘calc_size’, ‘get_width_and_height’, and ‘get_color’.
These functions help with string manipulation, getting an index in a 1D array representing a 2D
image, calculating the size of an image, and extracting image dimensions and color values from
strings.
The ‘read_image’ function reads an image from a file and stores it as a vector of tuples with float
values representing the red, green, and blue (RGB) components of each pixel. The function reads
the file line by line, determining the file format, dimensions, and maximum color value, and then
populates the image vector with the pixel data.
Several functions perform image manipulations like ‘negative_image’, ‘double_as_dark’,
‘onefive_as_dark’, ‘twice_as_bright’, ‘add_for_brighter’, ‘sub_for_darker’, ‘greyscale_image’,
‘zero_gb_image’, ‘r_zero_b_image’, ‘rg_zero_image’, ‘grb_image’, ‘bgr_image’, ‘rrb_image’,
and ‘blended_two_images’. These functions take an image (vector of tuples) and its dimensions
as input and modify the image in place. Some functions also take additional parameters like the
blending factor ‘alpha’ for ‘blended_two_images’.
The main function of the program reads an input image file, performs the user-specified image
manipulations using the functions mentioned above, and writes the modified image to an output
file. The main function also takes care of validating the user input and making sure the provided
parameters are valid.
For the source code, take a look in Appendix A: 08_light_and_color.cpp
For every image generated, 04_helloworld.ppm get’s reread.
4 Time to draw some lines with Standard Library 12

08_negative_image.ppm

Subtraction Eg. original color rgb(203, 37, 101) as negative: rgb(255-203, 255-37, 255-101) which is
the same as: rgb(52, 218, 154).

08_double_as_dark.ppm

Division Eg. rgb(203, 37, 101) as double as dark: rgb(203/2, 37/2, 101/2) which is the same as: rgb(101,
18, 50).

08_onefive_as_dark.ppm

Division Eg. rgb(203, 37, 101) as 1.5 as dark: rgb(203/1.5, 37/1.5, 101/1.5) which is the same as:
rgb(135, 25, 67).

08_twice_as_bright.ppm

Multiplication Eg. rgb(203, 37, 101) as twice as bright: rgb(203x2, 37x2, 101x2) which is the same
as: rgb(255, 74, 202).
4 Time to draw some lines with Standard Library 13

08_add_for_brighter.ppm

Addition Eg. rgb(203, 37, 101) add for brighter: rgb(203+30, 37+30, 101+30) which is nthe same as:
Eg. rgb(233, 67, 131)

08_sub_for_darker.ppm

Subtraction Eg. rgb(203, 37, 101) sub for darker: rgb(203-30, 37-30, 101-30) which is nthe same as:
Eg. rgb(173, 7, 71)

08_greyscale_image.ppm

Greyscale = (0.2126R) + (0.7152G) + (0.0722*B);

08_zero_gb_image.ppm

R = 0;

08_r_zero_b_image.ppm

G = 0;
4 Time to draw some lines with Standard Library 14

08_rg_zero_image.ppm

B = 0;

08_grb_image.ppm

RGB => GRB

08_bgr_image.ppm

RGB => BGR

08_rrb_image.ppm

RGB => RRB

08_blended_two_images.ppm
4 Time to draw some lines with Standard Library 15

Or blend two images together as above (based on bg: 06_xor_texture.ppm and fg: 04_helloworld_-
square.ppm). Or as below, with bg: 05_randomwalker.ppm and fg: 04_helloworld.ppm.

08_blended_two_images(2).ppm

But, now, let’s draw some lines.


This program is designed to generate two images: one with random lines and another with a damped
sine wave. The program includes various utility functions that handle operations like line drawing,
color conversion, line clipping, and saving images.
The ‘main’ function initializes the image as a vector of tuples, each representing a pixel color in
the form of RGB values. It first generates random lines by picking random points and colors, then
checks if the line is within the image’s dimensions using line clipping. If the line passes the clipping
check, it is drawn on the image. The resulting image, containing 15,000 random lines, is saved as
“09_random_lines.ppm”.
Next, the program creates an image of a damped sine wave. The image is initialized with a clear
background and a red line in the middle. The sine wave is drawn with a black color, and its damping
factor is represented with a grey color. The damped sine wave image is saved as “09_damped_-
sine.ppm”.
To achieve these functionalities, the program utilizes functions like ‘get_index’ and ‘calc_size’ to
handle image indexing and size calculations, ‘clear_image’ to set the image background to white,
and ‘h_to_rgb’ to convert hue values to RGB. Additionally, the program uses ‘draw_line’ to draw
lines on the image, ‘find_region’ and ‘clip_line’ to handle line clipping, and ‘save_image’ to save
the generated images to a file in PPM format.
Bresenham’s line algorithm, used in the ‘draw_line’ function, is an efficient and widely-used
technique for drawing lines on a raster grid, such as a computer screen or a digital image. Developed
by Jack E. Bresenham in 1962, the algorithm is notable for its simplicity, speed, and ability to produce
accurate line drawings using only integer arithmetic. It works by plotting a series of points between
two given endpoints, taking into account the discrete nature of raster grids and minimizing the error
between the ideal line and the plotted points.
The algorithm begins by calculating the differences in the x and y coordinates of the two endpoints,
and then determining the absolute values of these differences to establish the overall slope of the
line. Based on the slope, the algorithm chooses whether to increment the x or y coordinate at each
step, depending on which produces the least error. It does so by maintaining an error variable that
accumulates the difference between the ideal line and the plotted points. This error variable is used
to decide when to increment the other coordinate to keep the line as close to the ideal line as possible.
Bresenham’s line algorithm is particularly well-suited for computer graphics because it avoids the
4 Time to draw some lines with Standard Library 16

use of floating-point arithmetic and division, which can be computationally expensive. Instead, it
relies on integer operations, which are generally faster and more efficient. This makes the algorithm
ideal for use in low-level graphics systems, such as early computer displays and video game consoles,
where computational resources are limited.
The ‘find_region’ and ‘clip_line’ functions uses the Cohen-Sutherland line clipping algorithm. This
algorithm is used to determine the parts of a line segment that lie within a rectangular viewport or
window. The main goal of the algorithm is to reduce the amount of line drawing computation
required for lines that are partially or entirely outside the viewport.
The Cohen-Sutherland algorithm assigns a 4-bit region code to each endpoint of a line segment
based on its position relative to the viewport. The bits correspond to the top, bottom, right, and
left regions outside the viewport. The ‘find_region’ function computes this region code for a given
point. If both endpoints have a region code of 0, the line segment is entirely inside the viewport, and
no clipping is required. If the bitwise AND of the two region codes is non-zero, the line segment is
entirely outside the viewport and can be discarded.
When a line segment straddles the viewport boundary, the ‘clip_line’ function comes into play.
This function iteratively clips the line segment against each edge of the viewport by calculating the
intersection point between the line and the edge. It then replaces the endpoint that lies outside the
viewport with the intersection point and updates its region code. This process is repeated until the
line segment is either fully inside the viewport or determined to be outside the viewport.
For the source code, take a look in Appendix A: 09_lines.cpp

09_random_lines.ppm

In this example we use HSV (Hue, Saturation, and Value) as a color model and converts it back to
RGB afterwords. A random Hue gets produced and with the h_to_rgb(float h) function we get a
RGB value back.
We also use clip_line function together with find_region function for clipping every line that is
clipped between the visible and non-visible screen.
‘std::mt19937’ is a C++ standard library implementation of the Mersenne Twister pseudorandom
number generator (PRNG) algorithm. The name “mt19937” is derived from the fact that the
Mersenne Twister uses a Mersenne prime number, 2^19937 - 1, as the basis for its internal state.
This PRNG is widely used for its high-quality random number generation, large period, and efficient
performance. Mersenne Twister is a popular choice for various applications, including simulations,
statistical modeling, and computer games, where high-quality random numbers are needed.
The ‘std::mt19937’ generator is part of the C++11 ‘’’ library is designed to offer a more versatile and
flexible approach to random number generation compared to older C++ functions like ‘rand()’ and
4 Time to draw some lines with Standard Library 17

‘srand()’.
To use ‘std::mt19937’, you first need to create an instance of the generator and seed it with an initial
value. The quality of the random numbers generated depends on the seed value, which is typically
derived from a high-resolution clock or other sources of entropy. Once the generator is seeded, you
can use it to generate random numbers within a specified range or to generate random numbers
according to a probability distribution using distribution classes provided by the ‘’’ header.

09_damped_sine.ppm

Here we use the previous X and Y to draw a continous line that gets shaped into the demped sine
as calculated.
A damped sine wave is a sinusoidal function that gradually decreases in amplitude over time due to
the presence of a damping factor. In mathematical terms, a damped sine wave can be represented
as A(t) = A₀ * sin(ωt + φ) * e^(-αt), where A₀ is the initial amplitude, ω is the angular frequency, φ
is the phase, α is the damping factor, and t represents time. The damping factor, α, determines the
rate at which the amplitude decreases; a larger damping factor results in a more rapid decrease in
amplitude, while a smaller damping factor causes the amplitude to decay more slowly.
Damped sine waves can be effectively used in animations to create natural-looking motion or to
simulate physical processes that involve oscillatory behavior. For example, they can be employed to
animate the movement of a pendulum, the bouncing of a ball, or the oscillation of a spring. In these
cases, the damped sine wave helps to model the gradual loss of energy due to friction, air resistance,
or other dissipative forces that are present in real-world systems. By incorporating damped sine
waves into animations, designers can create more realistic and visually appealing motion that closely
mimics the behavior observed in nature, making the animation more immersive and engaging for
the audience.
Also, we can draw a line with starting x and y point, length and degrees.

09_angle_lines.ppm

The code is designed to create an image with lines drawn at different angles. The code begins
with several include statements, bringing in necessary libraries, followed by a series of function
definitions.
The ‘get_index’, ‘calc_size’, and ‘clear_image’ functions are utility functions for image manipula-
tion. ‘get_index’ calculates a one-dimensional index from two-dimensional coordinates, ‘calc_size’
4 Time to draw some lines with Standard Library 18

calculates the total size of the image given its width and height, and ‘clear_image’ sets all pixels in
the image to white.
‘draw_line’ is a function that draws a line between two points in the image with a specified color.
The ‘find_region’, ‘clip_line’, and ‘get_angle_line’ functions are used for line clipping and angle
calculations. ‘find_region’ determines which region of the image a point lies in, ‘clip_line’ clips a
line to the image boundaries, and ‘get_angle_line’ calculates the endpoint of a line given a starting
point, angle, and length.
Finally, ‘save_image’ is a function that writes the image data to a file in PPM format.
The ‘main’ function initializes the image and sets its dimensions. It then draws lines at various
angles (0, 45, 90, 135, 180, 225, 270, and 315 degrees) around the center of the image with a fixed
length. The clip_line function is used to ensure that lines are only drawn within the boundaries of
the image. After drawing all the lines, the image is saved to a file named “09_angle_lines.ppm”.
5 There are no straight curves, only
curved lines
Bézier curve is a parametric curve. There are three types of Bézier curves:

• Linear Bézier curves


• Quadratic Bézier curves
• Cubic Bézier curves

Linear Interpolation, is a mathematical function that returns a value between two others at a point
on a linear scale. Most commonly it’s used for moving or changing values over a period of time.
With std::lerp (Linear Interpolation) function in C++20 we can draw curves using Linear, Quadratic
and Cubic Bézier curves (using a std::lerp inception; As they build on each other).
Reference: https://en.cppreference.com/w/cpp/numeric/lerp
C++17 version: https://github.com/emsr/cxx_linear
Use the lerp and midpoint code above if you’re only allowed to use C++17.
The C++ code demonstrates how to draw linear, quadratic, and cubic Bezier curves using dots on
an image. It creates an image with various types of Bezier curves and saves the result as a PPM
file. The code starts by including the necessary header files and then defines several functions to
compute the points on the Bezier curves, manipulate the image, and render the curves on the image.
The linear, quadratic, and cubic Bezier curve functions take the coordinates of the start, control, and
end points, along with the number of splits as input, and compute the points on the curves. Utility
functions are defined to help with image manipulation and rendering, such as getting an index in
the image vector, calculating the size of the image, clearing the image, and drawing lines.
In addition to the Bezier curve functions, the code also has functions to draw the Bezier curve points
and markers on the image, which are used for better visualization. Another function, save_image,
is defined to save the image as a PPM file.
In the main function, the program initializes the width and height of the image, creates a vector
for storing the image data, and then clears the image. Next, it draws linear, quadratic, and cubic
Bezier curves by using the previously defined functions. The program also draws the control lines
and markers for better visualization. Finally, it saves the resulting image as a PPM file named
“10_curved_dots.ppm”.
For the source code, take a look in Appendix A: 10_curved_dots.cpp
5 There are no straight curves, only curved lines 20

10_curved_dots.ppm

This is what std::lerp does… it’s these points that then can use a line function and dra the curve. The
curve is controlled with the two control points.
This C++ code is designed to create an image of curved lines using linear, quadratic, and cubic Bezier
curves. It first includes the necessary libraries and then defines several functions to calculate Bezier
curves, draw lines and dots, and save the image.
The ‘linear_bezier_curves’, ‘quadratic_bezier_curves’, and ‘cubic_bezier_curves’ functions are
used to generate the points for linear, quadratic, and cubic Bezier curves, respectively. The ‘draw_-
line’ function draws a straight line between two points. The ‘draw_xy_line’ function draws a line
using the points generated from Bezier curves, while the ‘draw_xy_dots’ function draws dots at
the points generated by the Bezier curves.
The ‘draw_marker’ function creates a small marker at a specified point, and the ‘save_image’
function saves the image to a file in PPM format.
In the ‘main’ function, the code sets up an image of specified width and height and fills it with a
white background. Then, it proceeds to draw lines using the Bezier curves functions, along with
markers and dots at various points. Finally, it saves the created image to a file.
The code demonstrates the use of linear, quadratic, and cubic Bezier curves to create smooth curves
between points in an image, as well as drawing markers and dots at specific points along the curve.
For the source code, take a look in Appendix A: 10_curved_lines.cpp

10_curved_lines.ppm

Here we have the curves drawn with the line function and the points is marked as well as also the
control points.
6 Rectangles with Standard Library
A rectangle is a closed 2D shape, having 4 sides, 4 corners, and 4 right angles (90°).The opposite
sides of a rectangle are equal and parallel. Since, a rectangle is a 2D shape, it is characterized by
two dimensions, width, and height. To draw a rectangle you’ll need X and Y together with the
rectangles width and height.
The C++ code generates an image containing two rectangles, one outlined and one filled, saved as a
PPM file. The code consists of several functions, each serving a specific purpose in order to create
and manipulate the image.
The first few functions in the code are used for basic image handling. The ‘get_index’ function
calculates the index of a pixel in a 1D vector representation of a 2D image given its (x, y) coordinates
and the image width. The ‘calc_size’ function calculates the size of the image given its width and
height, while the ‘clear_image’ function fills the image vector with white pixels (R=1.0, G=1.0,
B=1.0).
Next, there are functions for drawing shapes on the image. The ‘draw_line’ function draws a line
between two points in the image using Bresenham’s line algorithm, an efficient method for drawing
lines on a raster grid. The ‘draw_rect’ function draws an outlined rectangle by connecting its four
corners using the ‘draw_line’ function. The ‘draw_filled_rect’ function, on the other hand, draws
a filled rectangle by iterating over its area and setting the color of each pixel inside the rectangle.
Finally, the ‘save_image’ function saves the image to a PPM file, which is a simple, uncompressed
image file format.
In the ‘main’ function, the image parameters, such as width, height, and the position and size of the
two rectangles are initialized. Then, a vector representing the image is created and initialized with
white pixels. After that, the two rectangles are drawn on the image. The resulting image is then
saved to a PPM file named “11_rectangles.ppm”.
For the source code, take a look in Appendix A: 11_rectangles.cpp

11_rectangles.ppm

Here we have a rectangle and a filled rectangle.


The code reads a series of rectangle specifications from a file, and then generates an image containing
those rectangles, with a background color and overlapping filled rectangles. The primary purpose
6 Rectangles with Standard Library 22

of the code is to create an image where the filled rectangles are blended with the background color
using an alpha channel for transparency.
The code starts by including necessary headers and defining helper functions such as ‘startsWith-
CaseInsensitive’, ‘get_index’, ‘calc_size’, ‘clear_image’, ‘parse_bginfo_line’, ‘parse_rect_line’,
‘blend_colors’, ‘draw_filled_rect’, and ‘save_image’. These functions perform various operations,
such as string manipulation, parsing input lines, calculating indices for a 2D image stored as a 1D
vector, blending colors, drawing rectangles, and saving the final image as a PPM file.
In the ‘main’ function, the program reads lines from the input file “11_squint_with_your_eyes.txt”.
If a line starts with “r”, it is considered a rectangle specification and parsed using the parse_rect_line
function. The rectangle’s coordinates, color, and alpha values are then used to draw the rectangle
on the image using the ‘draw_filled_rect’ function. If a line starts with “b”, it is considered a
background specification and parsed using the ‘parse_bginfo_line’ function. The background color
and image dimensions are extracted from the line, and the image vector is resized accordingly. The
‘clear_image’ function is called to fill the entire image with the background color.
After processing all the lines from the input file, the program saves the resulting image to a PPM
file called “11_squint_with_your_eyes.ppm” using the ‘save_image’ function. The PPM file format
is a simple, text-based format that stores pixel color information as plain text. The code writes the
PPM header, followed by the pixel color values, one pixel per line, in the output file.
For the source code, take a look in Appendix A: 11_rectangles_from_file.cpp
For the source code, take a look in Appendix A: 11_squint_with_your_eyes.txt

11_squint_with_your_eyes.ppm

This is an example how you can read data and present it into a image.
7 Circles with Standard Library
A circle is a round-shaped figure that has no corners or edges.
The midpoint circle algorithm is a widely-used technique for efficiently drawing circles on raster
displays, such as computer screens or images. The algorithm was developed as an extension of
Bresenham’s line algorithm, which is used for drawing lines. The midpoint circle algorithm employs
integer arithmetic and incremental calculations to minimize computational overhead and avoid
the use of computationally expensive floating-point arithmetic, such as square root operations. It
generates a set of points on the circle’s circumference, taking advantage of the circle’s inherent
symmetry to reduce the number of calculations required.
The algorithm works by starting at the topmost point of the circle and incrementally moving towards
the x-axis while calculating the appropriate y-coordinate for each x-coordinate. It does this by
evaluating a decision parameter at each step to determine whether to increment the x-coordinate,
the y-coordinate, or both. The decision parameter is based on the circle equation, and it helps to
determine whether the midpoint between two candidate pixels is inside or outside the circle. If the
midpoint is inside the circle, the algorithm chooses the pixel closer to the x-axis; if it is outside, the
algorithm chooses the pixel closer to the y-axis.
One of the key features of the midpoint circle algorithm is its ability to exploit the eightfold
symmetry of a circle. Since a circle is symmetrical about both the x and y axes, as well as the
lines y = x and y = -x, the algorithm only needs to compute the points in one-eighth of the
circle and then derive the remaining points by reflection. This significantly reduces the number
of calculations required to draw the entire circle. The result is an efficient method for drawing
circles in computer graphics, particularly when working with low-level raster graphics operations
or limited computational resources.
This C++ code generates an image containing two circles, one filled and one unfilled, with a white
background. The primary purpose of the code is to demonstrate the process of drawing circles using
a simple implementation of the midpoint circle algorithm and saving the resulting image as a PPM
file.
The code starts by including necessary headers and defining helper functions, such as ‘get_index’,
‘calc_size’, ‘clear_image’,‘draw_circle’, ‘draw_filled_circle’, and ‘save_image’. These functions
perform various operations, such as calculating indices for a 2D image stored as a 1D vector, clearing
the image by setting all pixel colors to white, drawing unfilled and filled circles using the midpoint
circle algorithm, and saving the final image as a PPM file.
In the ‘main’ function, the program sets the width and height of the image, as well as the positions
and radii of the two circles. The x and y coordinates, as well as the radius of the circles, are calculated
based on the dimensions of the image. The image vector is resized accordingly, and the ‘clear_image’
function is called to fill the entire image with the white background color.
7 Circles with Standard Library 24

Next, the ‘draw_circle’ function is called to draw the first circle (unfilled) on the image, and the
‘draw_filled_circle’ function is called to draw the second circle (filled) on the image. Both functions
use the midpoint circle algorithm to determine which pixels to set to the desired color (black in
this case). The ‘draw_filled_circle’ function additionally fills the interior of the circle by drawing
horizontal lines between the boundary points.
Finally, the ‘save_image’ function is called to save the resulting image as a PPM file called “12_-
circle.ppm”. The PPM file format is a simple, text-based format that stores pixel color information
as plain text. The code writes the PPM header, followed by the pixel color values, one pixel per line,
in the output file.
For the source code, take a look in Appendix A: 12_circle.cpp

12_circle.ppm

Here we have a circle and a filled circle.


A program that reads circle specifications from a text file and generates a Portable Pixmap (PPM) file
containing an image of the circles. The code starts by including necessary libraries, such as those for
file streams, tuples, vectors, and mathematical functions. Then, several utility functions are defined
to perform tasks like case-insensitive string matching, index calculations, image size determination,
and image clearing.
The program then includes functions for parsing the circle and background information from the
input file. These functions, ‘parse_circle_line’ and ‘parse_bginfo_line’, process each line of the
input file and extract the relevant information. For circle specifications, it extracts the coordinates,
radius, and color information, while for background information, it extracts the image dimensions
and color.
Next, the code defines several functions to handle color blending, region finding, and line clipping.
The ‘blend_colors’ function combines two colors based on their transparency, while ‘find_region’
and ‘clip_line’ deal with determining which portions of the circle are visible within the image
boundaries.
The main functionality of the program is found in the ‘draw_filled_circle’ function, which takes
the circle’s center coordinates, radius, color, and image dimensions as arguments. It uses an efficient
algorithm to draw filled circles, updating the image buffer with the circle’s color. The ‘save_image’
function saves the generated image to a PPM file.
Finally, the ‘main’ function reads the input file and calls the appropriate functions to parse the circle
and background information. It initializes an empty image and fills it with the background color,
then iterates through each circle specification and draws the circle onto the image. Once all circles
have been drawn, it saves the image to a file and exits.
7 Circles with Standard Library 25

For the source code, take a look in Appendix A: 12_circles_from_file.cpp


For the source code, take a look in Appendix A: 12_squint_with_your_eyes.txt

12_squint_with_your_eyes.ppm

Another example of reading data and rendering an image.


Let’s draw a wedge using arc.
The algorithm used to draw the wedge in the program is a combination of trigonometry and the
Bresenham’s line algorithm. The trigonometric aspect calculates the points along the arc of the
wedge, while Bresenham’s line algorithm is used to draw the straight lines that form the sides of the
wedge.
To calculate the points along the arc, the algorithm begins by converting the starting and ending
angles to radians. Then, it iteratively computes the x and y coordinates using the cosine and sine
functions of the current angle, and adds them to a list of coordinates. The iteration continues with
a small increment in the angle until the ending angle is reached.
For the straight sides of the wedge, Bresenham’s line algorithm is used to connect the center of the
circle to the start and end points of the arc. Bresenham’s line algorithm is a widely used technique
for drawing lines in computer graphics, as it efficiently calculates the integer points along the line
without using floating-point arithmetic. The algorithm iteratively updates the x and y coordinates
while minimizing the error between the actual line and the drawn points. The combination of the
arc points and the lines generated by Bresenham’s algorithm creates the complete wedge shape.

12_wedge.ppm

This C++ program generates an image with a radial pattern resembling a wedge or a pie slice. The
image is saved in the PPM format.
The program begins by including necessary headers and defining functions for handling image data,
such as calculating the size of the image, clearing it, and saving it to a file. It also contains functions
to draw lines and wedges, both filled and unfilled, on the image. The main part of the program
initializes the image dimensions and creates an empty white image of the specified size.
7 Circles with Standard Library 26

The program then sets the center, radius, and angles for the wedge to be drawn. The center of the
wedge is set to be the midpoint of the image, and the radius is set to 80% of half of the image height.
The starting and ending angles of the wedge are defined in degrees, with 0 and 348 degrees being
used in this example.
Next, the program draws a filled black wedge with the specified dimensions, followed by a filled gray
wedge with half the radius, creating a “doughnut” shape. Then, it draws an unfilled purple wedge
outline around the larger black wedge. Finally, the image is saved to a file named “12_wedge.ppm”.
For the source code, take a look in Appendix A: 12_wedge.cpp
8 Triangles with Standard Library
A triangle is a closed, 2 dimensional shape with 3 sides, 3 angles, and 3 vertices. A triangle is also a
polygon.
Create an image containing two triangles, one outlined and the other filled, and save it as a PPM
file. The code is divided into several sections, such as defining functions for operations on images,
drawing lines and triangles, and the main program logic.
The program begins by including necessary headers and then defining several utility functions.
The ‘get_index’ function calculates the index of a given pixel in a 1D vector based on its x and
y coordinates and the image width. The ‘calc_size’ function calculates the total number of pixels
in an image given its width and height. The ‘clear_image’ function sets all pixels in an image to a
specified color.
The ‘draw_line’ function uses a modified Bresenham’s line algorithm to draw a line between two
points on an image. The ‘draw_triangle’ and ‘draw_filled_triangle’ functions utilize the ‘draw_-
line’ function to draw the edges of triangles, either outlined or filled, using an incremental scanline
rendering approach.
The ‘save_image’ function takes an image represented as a vector of RGB color tuples, its width
and height, and a filename as arguments, and saves the image as a PPM file.
In the main function, the program first initializes the width and height of the image, as well as the
coordinates of the vertices of the two triangles. It then creates a vector to store the image and sets
its initial color to white using the ‘clear_image’ function. Next, it sets the color to black and calls
the ‘draw_triangle’ function to draw the first triangle and the ‘draw_filled_triangle’ function to
draw the second triangle.
Finally, the program saves the image using the ‘save_image’ function, resulting in a PPM file
containing the two triangles.
For the source code, take a look in Appendix A: 13_triangles.cpp

13_triangles.ppm

Here we have a triangle and a filled triangled


This C++ code reads a file containing information about triangles and their colors, then generates a
raster image of the triangles. The program starts by including necessary headers, such as iostream,
8 Triangles with Standard Library 28

fstream, tuple, vector, random, cmath, and algorithm. It defines several utility functions to handle
string processing, coordinate calculations, and image manipulation. The main part of the code
consists of functions to parse input strings, blend colors, find the region of a point, clip lines, draw
filled triangles, and save the generated image to a file.
The ‘parse_bginfo_line()’ and ‘parse_triangle_line()’ functions read lines from the input file
and convert the data into the appropriate data types for further processing. The ‘blend_colors()’
function is used to blend colors using the alpha value, which determines how transparent the color
should be when applied to the image. The ‘find_region()’ and ‘clip_line()’ functions are used to
determine if a point is within the image bounds and to clip any lines that are outside of the image
bounds, respectively.
The ‘draw_filled_triangle()’ function is responsible for rendering triangles onto the image. It uses
a scanline algorithm to fill the triangles with the specified color. This function takes care of edge
cases and ensures that the triangles are drawn correctly within the image boundaries. Finally, the
‘save_image()’ function writes the generated image data to a file in PPM (Portable Pixmap) format.
For the source code, take a look in Appendix A: 13_triangles_from_file.cpp
For the source code, take a look in Appendix A: 13_squint_with_your_eyes.txt

13_squint_with_your_eyes.ppm

Another example.
9 Animation with Standard Library
Below is four example of animation you can do… of course the animation might be more releated
to graphs then images.
You can animate shapes, color transition, opacity and movment.
A C++ program that creates a simple animation using a random walker algorithm. It reads an image
file in PPM format, generates a sequence of images, and saves them in a specified directory. The
user can then use a tool like FFmpeg to convert the image sequence into a video format.
The program begins by defining several helper functions for tasks such as reading and writing
PPM images, updating the positions of the walkers, and blending two images together. The ‘main’
function reads an image from a file, creates a second image buffer, and then initializes the walker
positions to the center of the image. It then iterates over a loop for a large number of steps, moving
the walkers randomly in one of the four cardinal directions and updating the image buffer with the
color from the first image at the new walker positions.
After every 100 steps, the program saves the current state of the image buffer as a new PPM file.
The animation created by this program consists of two walkers moving randomly over the image,
revealing its contents as they traverse it.
For the source code, take a look in Appendix A: 14_animation05.cpp
An animation program that generates a series of images based on input data from a text file. The
text file contains information about the background and rectangles to be drawn on the images.
The program begins by including necessary libraries and defining functions that will be used
later on. Functions include ‘startsWithCaseInsensitive’ for checking if a string starts with a
specific substring, ‘get_index’ and ‘calc_size’ for converting 2D coordinates into 1D indices, and
‘clear_image’ for initializing an image with a specified background color.
The program also contains functions for parsing the input text file, such as ‘parse_bginfo_line’
and ‘parse_rect_line’, which extract relevant information from the input lines. Another important
function is ‘blend_colors’, which combines two colors based on their alpha values. The ‘draw_-
filled_rect’ function is responsible for drawing filled rectangles on the image using the ‘blend_-
colors’ function. The ‘get_filname’ function generates a filename for the output image, and the
‘save_image’ function saves the image to a file.
The ‘main’ function of the program begins by creating an output directory and opening the input
text file. The program then iterates through each line of the text file, checking if the line starts
with ‘r’ for rectangle or ‘b’ for background. If it starts with ‘r’, the program parses the rectangle
information, draws the rectangle on the image, and saves the image. If the line starts with ‘b’, the
program parses the background information, resizes the image, sets the background color, and saves
9 Animation with Standard Library 30

the image. The program prints the filenames of the saved images to the console and closes the input
file at the end.
For the source code, take a look in Appendix A: 14_animation11.cpp
Works the same as 14_animation11.cpp. Uses cricles instead of rectangles.
For the source code, take a look in Appendix A: 14_animation12.cpp
Works the same as 14_animation11.cpp. Uses triangles instead of rectangles.
For the source code, take a look in Appendix A: 14_animation13.cpp
Just experiment and use what you think looks good.
10 Drawing Charts and a Font
The flood-fill algorithm is a popular technique in computer graphics and image processing for filling
an area with a specified color. This algorithm works by starting at a seed pixel and recursively or
iteratively filling neighboring pixels that share the same color as the seed pixel, ultimately replacing
them with a new target color. The process continues until all the connected pixels sharing the
original color are filled with the new color. The flood-fill algorithm has several variations, such as
4-way and 8-way connectivity, which determine how pixels are considered neighbors based on their
relative positions.
Flood-fill algorithms have various applications, particularly in image editing software, computer
games, and pattern recognition tasks. In image editing software, the flood-fill tool, commonly
known as the paint bucket, is used to fill areas with a uniform color or pattern. This tool allows
users to easily modify images by changing the color of specific regions or creating new shapes. In
computer games, the flood-fill algorithm can be employed for tasks like procedural map generation,
pathfinding, or detecting connected components in a game world. In pattern recognition, flood-fill
algorithms can be used to identify and isolate distinct regions or objects within an image based on
their color or texture properties.
Despite its popularity and numerous applications, the flood-fill algorithm does have some limita-
tions. Its performance can be affected by the size of the area to be filled and the complexity of the
image. Recursive implementations of the flood-fill algorithm are prone to stack overflows when
dealing with large areas, while iterative implementations can be memory-intensive. Additionally,
the algorithm may fail to provide the desired output if there are gaps or holes in the boundaries of
the region to be filled. In such cases, modifications to the algorithm, like tolerance-based flood-fill
techniques, can be applied to address these issues and achieve more accurate results.
A program that demonstrates the creation and manipulation of a radar chart, which is a graphical
representation of multivariate data in the form of a two-dimensional chart. This code can be
compiled using the command provided at the beginning of the code.
The program begins by including the required header files and defining a set of functions to
manipulate images, such as calculating the index, clearing the image, drawing shapes, and clipping
lines. Some functions, like ‘get_index’ and ‘calc_size’, are utility functions that help with image
manipulation, while others, like ‘draw_circle’ and ‘draw_filled_circle’, are responsible for drawing
specific shapes on the image.
The ‘floodfill_algorithm’ function is an implementation of the flood-fill algorithm that fills an
enclosed area of an image with a specified color. The ‘get_all_ys’ and ‘draw_line_coords’ functions
are used for drawing polygons on the image. The ‘draw_polygon’ and ‘draw_filled_polygon’
functions use these helper functions to draw and fill polygons, respectively.
10 Drawing Charts and a Font 32

The ‘draw_line’ function takes an image, a set of coordinates, a color, and the width and height of
the image, and draws a line on the image using the given coordinates and color. The ‘find_region’
and ‘clip_line’ functions are used to clip lines based on the width and height of the image, ensuring
that lines do not extend beyond the boundaries of the image.
For the source code, take a look in Appendix A: 15_radarchart.cpp

15_radarchart.ppm

As 15_radarchart.ppm width is 1920 pixels and height is 1080, the size of the PPM is getting a bit big
to write as a textfile. That is why save_image()-function saves the PPM as a P6 with the RGB as 3
byte binary data.
This code is written in C++ and is used to generate a radial chart with three colored segments
representing three different categories of data. The chart consists of 52 wedges, each representing a
week. The data for each category is provided in three arrays ‘a1’, ‘a2’, and ‘a3’. The chart is then
saved as an image in PPM (Portable Pixmap) format.
The program begins by including the necessary header files and defining some utility functions for
working with images, such as ‘get_index’, ‘calc_size’, ‘clear_image’, and others. These functions
are used for creating and manipulating the image data structure, a vector of tuples representing
RGB colors. Functions like ‘draw_filled_circle’, ‘draw_filled_wedge’, and ‘save_image’ are used
to draw and save the final image.
The ‘main’ function starts by initializing the image data structure and setting up color tuples
for the background and three data categories. It calculates the center of the image, the radius,
and other necessary parameters for drawing the radial chart. It then draws a filled circle with a
specific background color and iterates through the 52 wedges, drawing filled wedges for each of
the three categories using the data provided in ‘a1’, ‘a2’, and ‘a3’. The wedges are drawn using
the ‘draw_filled_wedge’ function, which in turn uses the ‘draw_line_coords’ function to create
line coordinates for the wedges. After drawing all the wedges, the image is saved to a file named
“15_weekchart.ppm” using the ‘save_image’ function.
For the source code, take a look in Appendix A: 15_weekchart.cpp

15_weekchart.ppm
10 Drawing Charts and a Font 33

Also as a P6 PPM as it has the same width and height as 15_radarchart.ppm.


This C++ code reads and writes P6 PPM (Portable PixMap) image files. The main purpose is to load
an image file, and then save it to another file without any modification. The code is organized in
three main sections: the ‘load_image’ function, the ‘save_image’ function, and the ‘main’ function.
The ‘load_image’ function takes a reference to a vector of tuples of floats, width and height integers,
and a string for the filename. It opens the file in binary mode, reads the magic number (which should
be “P6”), skips any comments, reads the image dimensions and maximum color value, and then reads
the pixel data into the vector of tuples. The pixel data is normalized by dividing the individual color
values by 255.0, which makes it easier to work with in future operations.
The ‘save_image’ function is responsible for writing an image back to a file. It takes the same
arguments as the ‘load_image’ function, but instead of reading the data, it writes the image data to
a file. It writes the magic number, image dimensions, and maximum color value, and then writes
the pixel data, converting the normalized float values back to the 0-255 range.
The ‘main’ function starts by defining a vector of tuples to store the image data and integer variables
for width and height. It then calls the ‘load_image’ function to read the image file, prints out the
width and height of the image, and finally calls the ‘save_image’ function to save the image data
to a new file.
This code can be used as a starting point for more complex image manipulation tasks, as it provides
a simple way to read and write PPM files.
To read a P6 PPM, take a look in Appendix A: 15_read_p6_ppm.cpp
Let’s create a font and render all the letters in it.

This code generates images of hand-drawn styled letters and numbers. The program defines a set of
functions to draw each character, using the Bresenham’s line algorithm to get the points of the lines
that make up the characters. It also defines functions to draw filled circles, clear the image, and save
the image in the PPM (Portable Pixmap) format.
The main function (draw_and_save_font) iterates through each character, draws it with the specified
color, width, height, margin, and line size, and saves the resulting image to a PPM file.
Each draw_font_ function has two main components:
10 Drawing Charts and a Font 34

• An array of points that define the character’s shape, where the points are represented by their
relative X and Y coordinates.
• An array of line segments that connect these points, where each line segment is represented
by a pair of indices corresponding to the points array.

In each function, the code iterates through the line segments, calculates the coordinates of the actual
points on the image canvas by scaling and translating the relative coordinates, and adds the points
to the points vector.
The draw function takes the points vector and the other parameters, and updates the image by either
drawing a single pixel (when the line size is 1) or drawing a filled circle centered at each point.
Finally, the save_image function writes the image data to a PPM file, using the specified filename.
Here’s a brief explanation of the purpose of each function:

• draw_font_: Draws the specified character by adding its line points to the points vector.
• get_line_points: Uses Bresenham’s line algorithm to get the points of a line segment.
• draw_filled_circle: Draws a filled circle centered at the specified point with the specified
radius.
• clear_image: Resets the image to a white background.
• save_image: Saves the image to a PPM file with the specified filename.
• draw: Updates the image with the specified points, color, line size, etc.
• draw_and_save_font: Main function that iterates through each character, draws it, and saves
the image to a file.

To draw each letter in the font, take a look in Appendix A: 15_draw_font.cpp


11 Presentation, Collaboration, and
Investigation
11.1 Presentation
Creating charts and diagrams can be a great way to visualize data and communicate information.
This chapter will show you how to create 2D charts and diagrams using C++.
We’ll start by showing you how to create basic shapes and lines. Then we’ll make more complex
shapes like circles and rectangles. Finally, we’ll show you how to add text and labels to your charts
and diagrams.
By the end of this chapter, you’ll know how to create professional-looking 2D charts and diagrams
using C++. So let’s get started!

11.2 Draw a bar chart


Draw a bar chart by just hacking away.
This generates an image of a bar chart with specific characteristics. The chart has 5 bars and 4 icons
drawn in the image, as well as percentage values. The code is structured in various functions that
are called in the ‘main’ function to build and save the image.
The program starts with the necessary includes, such as iostream, fstream, tuple, vector, random,
and cmath. The ‘get_index’ function calculates an index for accessing elements of the image vector.
The ‘calc_size’ function calculates the size of the image based on the width, height, and margin.
The ‘clear_image’ function initializes the image with a specific color (a shade of gray).
The ‘draw_filled_rect’ function takes the position (x, y), dimensions (w, h), image reference, color,
width, and height as parameters and draws a filled rectangle on the image. The ‘draw_line’ function
takes the image reference, a tuple of coordinates, color, width, and height as parameters and draws a
line on the image. The ‘save_image’ function takes the image reference, width, height, and filename,
and saves the image as a PPM file.
In the ‘main’ function, the program initializes the image, fills it with the background color, and
then draws the bar chart by calling ‘draw_filled_rect’ and ‘draw_line’ functions with specific
parameters. The bars, icons, and percentages are drawn using these functions. After drawing the
chart, the image is saved to a file with a specified filename.
11 Presentation, Collaboration, and Investigation 37

16_draw_bar_chart.ppm

Drawing a bar chart, take a look in Appendix A: 16_draw_bar_chart.cpp

11.3 Draw a pie chart


The code is designed to create and output a simple pie chart. It first includes necessary headers
such as iostream, fstream, tuple, vector, random, cmath, and algorithm to handle various functions
required in the program. It then defines a set of functions for various calculations and operations.
The function ‘get_width_from_height’ calculates the width of the pie chart based on the height.
‘get_margin_from_height’ calculates the margin size for the chart based on the height. ‘get_index’
returns the index of a pixel in the image vector given its x and y coordinates and the width of the
image. The ‘calc_size’ function calculates the size of the chart based on its width, height, and
margin.
The ‘stamp’ function is responsible for stamping the image of a letter onto the pie chart, while
the ‘clear_image’ function sets the initial color of the pie chart to a light orange color. Functions
‘get_line_points’, ‘draw_font_M’, ‘draw_font_A’, ‘draw_font_R’, ‘draw_font_S’, ‘draw_font_-
V’, ‘draw_font_E’, ‘draw_font_N’, ‘draw_font_U’, and ‘draw_font_C’ handle drawing of the
individual letters on the pie chart using line segments and points. Each letter is represented by
a set of coordinates and lines connecting them.

16_draw_pie_chart.ppm

Pie chart in PPM, take a look in Appendix A: 16_draw_pie_chart.cpp

11.4 Draw a donut chart


The code provided is a C++ program that creates a donut chart with the letters “MARS” in the
center. It uses a variety of functions to draw lines, circles, and characters on a 2D grid, ultimately
constructing the desired image.
11 Presentation, Collaboration, and Investigation 38

The program starts by including necessary headers and defining functions to perform operations
such as calculating width and margin based on height, calculating the index of a 2D point in a 1D
array, and clearing the image by setting a background color. Functions are also defined for drawing
lines between two points and drawing filled circles.
There are several functions dedicated to drawing individual characters like ‘M’, ‘A’, ‘R’, and ‘S’.
These functions first define an array of points representing the outline of each character and then
another array of lines connecting those points. Using the ‘get_line_points’ function, lines are drawn
between the specified points to create the shape of the characters.
The ‘draw_filled_circle’ function takes in the center coordinates of a circle, its radius, and a color,
and then fills the circle with that color. The ‘draw_filled_circle2’ function is a slightly modified
version of ‘draw_filled_circle’ without the margin parameter.
The ‘get_all_ys’ function collects all the y-coordinates from a set of coordinates, sorts them, and
removes duplicates. The ‘draw_line_coords’ function is a helper function for drawing lines between
two points and storing the resulting coordinates in a vector.
The ‘stamp’ function is used to place one image (letter) onto another image (donut chart) at a
specified offset. The ‘draw_filled_circle_segment’ function draws a filled segment of a circle, given
the start and end angles.
Finally, the ‘main’ function of the program sets up the dimensions and colors for the donut chart
and uses the functions defined earlier to draw the chart and letters. The resulting image is then
saved as a PPM file, which can be opened with an image viewer that supports the format.

16_draw_donut_chart.ppm

Pie chart in PPM, take a look in Appendix A: 16_draw_donut_chart.cpp

11.5 Draw a table


This C++ code is designed to draw a table, save the image as a PPM file, and demonstrate various
graphics functions such as drawing lines, circles, and rectangles. It includes various functions to
perform these tasks and a main function to tie them all together.
First, the necessary libraries are included at the beginning of the code. The ‘get_width_from_-
height’ function calculates the width of the table based on its height, while the ‘get_margin_from_-
height’ function calculates the margin based on the height. The ‘get_index’ function calculates the
index of a point in a one-dimensional vector based on its x and y coordinates and the given width.
11 Presentation, Collaboration, and Investigation 39

The ‘calc_size’ function calculates the size of the image, taking into account the width, height, and
margin. The ‘clear_image’ function initializes the image vector by setting the color of each pixel to
a light brownish color. The ‘stamp’ function stamps the input image (i.e., the letters) onto another
image at a specified position.
The ‘get_line_points’ function calculates the points along a line using Bresenham’s line algorithm,
given the coordinates of the two endpoints and a color. This function is used in the ’draw_font*’_-
functions, where each function (e.g., ‘draw_font_M’, ‘draw_font_A’, etc.) is responsible for
drawing the respective letter using lines. Each of these functions sets up arrays containing the
coordinates of the points and lines that make up the letter, and then calls ‘get_line_points’ to
calculate the points along each line.
The ‘draw_filled_circle’ and ‘draw_filled_rect’ functions draw filled circles and rectangles,
respectively, on the image. The ‘save_image’ function saves the image as a PPM file, given the
image data, its dimensions, and the output filename.
The draw function is used to draw a set of points on the image. The points are drawn as filled
circles with a specified line size. Finally, the ‘main’ function initializes the image, sets the colors
and dimensions for the table, and calls the various drawing functions to create the image. It then
saves the image to a file named “table.ppm”.

16_draw_table.ppm

Pie chart in PPM, take a look in Appendix A: 16_draw_table.cpp.cpp

11.6 Draw a more advanced chart 1


The given function, ‘generate_noise_image’, is designed to create a noise image by generating
random grayscale pixel values. The noise image is represented as a vector of tuples, where each
tuple contains three float values representing the red, green, and blue channels of a pixel.
The function takes two parameters: a reference to an ‘std::vector’ of tuples named image which will
store the generated noise ‘image’, and two integers ‘width’ and ‘height’ representing the dimensions
of the desired noise image. The function begins by defining a tuple named ‘color’ and a float variable
named ‘rndnum’, which will be used to store random grayscale values.
Next, the function sets up a random number generator using the ‘std::random_device’ and
‘std::mt19937’ classes from the C++ standard library. The random number generator is configured
to produce float values uniformly distributed between 0.0 and 1.0.
The function then iterates through each pixel in the image, using two nested loops. The outer loop
iterates through the height of the image, while the inner loop iterates through the width. For each
11 Presentation, Collaboration, and Investigation 40

pixel, a random number is generated using the previously configured random number generator,
and the ‘color’ tuple is set to contain the random number for all three channels (red, green, and
blue). This creates a grayscale color, as all channels have the same value. The ‘color’ tuple is then
assigned to the corresponding position in the ‘image’ vector using the ‘get_index’ function, which
converts 2D coordinates (x, y) into a 1D index suitable for accessing the vector.
By the end of the function, the ‘image’ vector will contain a representation of a noise image with
the specified width and height, where each pixel is a randomly generated grayscale value.

Step #1: 16_draw_market_size1.ppm

The ‘generate_linear_gradient_image’ function creates a linear gradient image by blending two


colors across the image vertically. The resulting image is represented as a vector of tuples, where
each tuple contains three float values representing the red, green, and blue channels of a pixel.
The function takes four parameters: a reference to an ‘std::vector’ of tuples named image which
will store the generated gradient ‘image’, two tuples named ‘fcolor’ and ‘tcolor’ representing the
starting and ending colors of the gradient, and two integers ‘width’ and ‘height’ representing the
dimensions of the desired gradient image. The function begins by defining a tuple named ‘color’
and double variables ‘resultRed’, ‘resultGreen’, and ‘resultBlue’ which will be used to store the
blended color values for each pixel.
Additionally, the function defines variables ‘fr’, ‘fg’, ‘fb’, ‘tr’, ‘tg’, and ‘tb’ for storing the individual
red, green, and blue components of the starting and ending colors. The ‘std::tie’ function is used to
unpack the ‘fcolor’ and ‘tcolor’ tuples into these separate variables.
The function then iterates through each row of the image using a loop that iterates through the
height of the image. For each row, the function calculates the percentage of the total height that the
current row represents. This percentage is then used to blend the starting and ending colors for that
row, by computing the weighted average of the respective color components (red, green, and blue).
The resulting blended color is stored in the ‘color’ tuple using the ‘std::make_tuple’ function.
Next, the function iterates through each column in the current row using a nested loop. For each
pixel in the row, the ‘color’ tuple containing the blended color for the current row is assigned to
the corresponding position in the ‘image’ vector using the ‘get_index’ function, which converts 2D
coordinates (x, y) into a 1D index suitable for accessing the vector.
By the end of the function, the ‘image’ vector will contain a representation of a linear gradient
image with the specified width and height, where the colors gradually blend from the starting color
at the top of the image to the ending color at the bottom.
11 Presentation, Collaboration, and Investigation 41

Step #2: 16_draw_market_size2.ppm

‘blended_two_images’ blends two images together using a specified alpha value. It takes five input
parameters: two vectors of tuples representing the colors of the two images, the width and height
of the images, and a float value called alpha.
First, the function initializes three tuple variables ‘color1’, ‘color2’, and three float variables ‘r’,
‘g’, and ‘b’. The tuples represent colors from the first and second images, while the float variables
represent the blended color components - red, green, and blue.
The function then uses two nested loops to iterate over the width and height of the images. The
outer loop iterates over the height of the images, and the inner loop iterates over the width. Inside
the inner loop, the function extracts the colors at the current position ‘(x, y)’ from both images using
the ‘get_index’ function, which computes the index in the vector based on the x, y coordinates and
the width.
Next, the function calculates the blended color components (red, green, and blue) using the alpha
value. The blending operation is performed by multiplying each color component of the second
image by the alpha value and adding the product of the color component from the first image and
(1.0 - alpha). This is done for all three color components - red, green, and blue.
After calculating the blended color components, the function stores the blended color as a tuple in
the first vector at the same position ‘(x, y)’. This overwrites the original color in the first image with
the blended color. Once the loops have finished, the first vector will contain the resulting blended
image.

Step #3: 16_draw_market_size3.ppm

‘generate_radial_gradient_image’ generates a radial gradient image using two input colors. It


takes four input parameters: a vector of tuples representing the colors of the output image, two
tuples representing the colors to create the gradient (from-color and to-color), and the width and
height of the image.
First, the function initializes several variables: color for storing the current ‘color’ being com-
puted, ‘pink’ for a predefined color, ‘mask’ for a vector of tuples to store an intermediate mask,
‘distanceFromCenter’ for calculating the distance from the center of the image, and ‘resultRed’,
‘resultGreen’, and ‘resultBlue’ for storing the resulting color components.
11 Presentation, Collaboration, and Investigation 42

The function starts with two nested loops to iterate over the width and height of the image. Inside
the inner loop, the function sets the initial values of the ‘mask’ and ‘image’ vectors at the current
position ‘(x, y)’ to the predefined ‘pink’ color and the ‘from-color’, respectively.
The function then initializes several variables for drawing a circle using Bresenham’s circle
algorithm. It declares a lambda function ‘drawline’ that is used to draw horizontal lines at the
specified positions. It loops over the circle, drawing lines for each quadrant, and updates the mask
vector accordingly.
After completing the circle drawing, the function starts another pair of nested loops to iterate over
the width and height of the image once more. Inside the inner loop, the function checks if the current
position ‘(x, y)’ in the ‘mask’ vector is not equal to the predefined ‘pink’ color. If this condition
is true, it calculates the distance from the center of the image and computes the resulting color
components based on the distance and the input ‘from-color’ and ‘to-color’. The function then
assigns the computed color to the ‘image’ vector at the current position ‘(x, y)’.
If the condition is false, meaning that the ‘mask’ vector has the ‘pink’ color at the current position
‘(x, y)’, the function assigns the ‘to-color’ to the ‘image’ vector at the current position. This way,
the final image vector will contain a radial gradient image generated using the input colors.

Step #4: 16_draw_market_size4.ppm

‘generate_repeating_texture_image’ generates a repeating texture image using an input color. The


function takes three input parameters: a vector of tuples representing the colors of the output image,
a tuple representing the color to create the texture, and the width and height of the image.
First, the function initializes a tuple called ‘bgcolor’ to store a predefined background color. Then,
it uses two nested loops to iterate over the width and height of the image. Inside the inner loop, the
function sets the initial value of the ‘image’ vector at the current position ‘(x, y)’’ to the background
color.
Next, the function defines two arrays named ‘arr’ and ‘arr2’, which store the coordinates and indices
of the line segments to draw the repeating texture pattern. The ‘arr’ array contains 13 pairs of
integers representing the x and y coordinates, and the ‘arr2’ array contains 13 pairs of integers
representing the indices of the line segments in the ‘arr’ array.
The function then uses a loop to iterate over the 13 line segments, creating a tuple ‘coords’ containing
the start and end coordinates of each line segment. Inside the loop, the function calls the ‘draw_line’
function, which draws the line segment on the ‘image’ vector using the input ‘color’, ‘width’, and
11 Presentation, Collaboration, and Investigation 43

‘height’. This process repeats for each line segment, resulting in a repeating texture pattern drawn
on the image vector.
In summary, the ‘generate_repeating_texture_image’ function creates a repeating texture image
by drawing a series of line segments on an image vector using a predefined background color and
an input color for the texture pattern. The function achieves this by iterating through a series of
coordinates and line segment indices, drawing the texture pattern on the image vector using the
‘draw_line’ function.

Step #5: 16_draw_market_size5.ppm

‘render_repeating_texture_image’ renders a repeating texture image by tiling a smaller texture


image across a larger image. The function takes five input parameters: a vector of tuples representing
the colors of the texture image, the width and height of the texture image (tw and th), a vector of
tuples representing the colors of the output image, and the width and height of the output image (iw
and ih).
The function uses two nested loops to iterate over the width and height of the output image. Inside
the inner loop, the function calculates the corresponding position in the texture image using the
modulo operator. The x and y coordinates of the output image are calculated as the remainder of
the division of the x and y coordinates by (tw - 1) and (th - 1), respectively. This approach ensures
that the texture image will be repeated across the output image, creating a tiled pattern.
Once the corresponding position in the texture image is determined, the function retrieves the color
at that position using the ‘get_index’ function, which computes the index in the vector based on
the x, y coordinates, and the texture image width (tw). The retrieved color is then assigned to the
output image vector at the current position ‘(x, y)’ using the ‘get_index’ function with the output
image width (iw).
11 Presentation, Collaboration, and Investigation 44

Step #6: 16_draw_market_size6.ppm

‘do_cookie_cut’ extracts a rectangular region, referred to as a “cookie,” from a larger image. The
function takes eight input parameters: a vector of tuples representing the colors of the input image,
the width and height of the input image (w and h), a vector of tuples representing the colors of the
output “cookie” image, the width and height of the “cookie” image (cw and ch), and the starting x
and y coordinates (startx and starty) of the region to extract from the input image.
The function initializes two variables, ‘cx’ and ‘cy’, which will be used to store the x and y
coordinates of the “cookie” image as it is being constructed. It then uses two nested loops to iterate
over the rectangular region defined by the starting coordinates (startx and starty) and the width and
height of the “cookie” image (cw and ch).
Inside the inner loop, the function retrieves the color from the input image at the current position
‘(x, y)’ using the ‘get_index’ function, which computes the index in the vector based on the x, y
coordinates and the input image width (w). The retrieved color is then assigned to the “cookie”
image vector at the position (cx, cy) using the get_index function with the “cookie” image width
(cw).
After each iteration of the inner loop, the function increments the x-coordinate of the “cookie” image
(cx) by 1. After each iteration of the outer loop, the function increments the y-coordinate of the
“cookie” image (cy) by 1 and resets the x-coordinate (cx) back to 0.

Step #7: 16_draw_market_size7.ppm

‘add_honeycomb’ overlays a texture image onto an input image using an alpha channel image to
control the blending. The function takes four input parameters: a vector of tuples representing the
colors of the input image, a vector of tuples representing the colors of the alpha channel image, a
vector of tuples representing the colors of the texture image, and the width and height of the images
11 Presentation, Collaboration, and Investigation 45

(w and h). The width and height are assumed to be the same for all three images.
First, the function initializes three color tuple variables (color1, color2, and color3) and a pink color
tuple, which will be used later to determine if a pixel should be affected by the texture overlay.
The function then iterates over the width and height of the input image using two nested loops.
Inside the inner loop, the function checks if the current pixel in the texture image is not equal to the
pink color. If it is not pink, the pixel will be affected by the texture overlay.
Next, the function retrieves the colors from the input image, texture image, and alpha channel image
at the current position ‘(x, y)’ using the ‘get_index’ function. The retrieved colors are assigned to
the corresponding color tuple variables (color1, color2, and color3).
The function then calculates the blended color by multiplying the texture color (color2) with the
alpha value (color3) and adding the input image color (color1) multiplied by the inverse of the alpha
value (1.0f - color3). This process is done separately for the red, green, and blue channels, resulting
in the final blended color components (ir, ig, and ib).
Finally, the blended color is assigned to the input image vector at the current position ‘(x, y)’ using
the ‘get_index’ function. This process updates the input image with the texture overlay, effectively
modifying the input image in-place.

Step #8: 16_draw_market_size8.ppm

‘stamp_cookie’ pastes a smaller image, referred to as a “cookie,” onto a larger image at a specified
position. The function takes eight input parameters: a vector of tuples representing the colors of
the input image, the width and height of the input image (w and h), a vector of tuples representing
the colors of the “cookie” image, the width and height of the “cookie” image (cw and ch), and the
starting x and y coordinates (startx and starty) of the position where the “cookie” image should be
pasted onto the input image.
The function initializes two variables, ‘cx’ and ‘cy’, which will be used to store the x and y
coordinates of the “cookie” image as it is being pasted onto the input image. It then uses two nested
loops to iterate over the rectangular region defined by the starting coordinates (startx and starty)
and the width and height of the “cookie” image (cw and ch).
Inside the inner loop, the function retrieves the color from the “cookie” image at the current position
‘(cx, cy)’ using the ‘get_index’ function, which computes the index in the vector based on the x,
y coordinates and the “cookie” image width (cw). The retrieved color is then assigned to the input
11 Presentation, Collaboration, and Investigation 46

image vector at the position ‘(x, y)’ using the ‘get_index’ function with the input image width (w).
After each iteration of the inner loop, the function increments the x-coordinate of the “cookie” image
(cx) by 1. After each iteration of the outer loop, the function increments the y-coordinate of the
“cookie” image (cy) by 1 and resets the x-coordinate (cx) back to 0.

Step #9: 16_draw_market_size9.ppm

The ‘draw_hexagon’ function is designed to draw a hexagon with a specified color onto an image.
The function takes eight parameters: a vector of tuples representing the colors of the input image, a
tuple representing the color of the hexagon, the x and y coordinates of the hexagon’s center (centerx
and centery), the hexagon’s radius, the width and height of the input image, and the “circle radius”
(cradius) used for drawing the lines that make up the hexagon.
First, the function initializes some variables used for calculating the hexagon’s vertices. It computes
the upper-left corner of a bounding box around the hexagon, given by ‘(ux, uy)’. It also initializes
six points (pt1x, pt1y) to (pt6x, pt6y), all initially set to ‘(ux, uy)’.
Next, the function calculates some auxiliary variables (A, B, C) using trigonometric formulas
involving the given hexagon radius and a constant PI value. The purpose of these calculations
is to help determine the coordinates of the hexagon’s vertices.
Using the auxiliary variables, the function computes the coordinates of each vertex of the hexagon
(pt1 to pt6). Each vertex’s x and y coordinates are updated based on the initial ‘(ux, uy)’ position
and the auxiliary variables.
The function then creates a vector of tuples called ‘points’ that will be used to store the points along
the lines that form the hexagon. For each pair of adjacent vertices, the function generates the line
points between them using the ‘get_line_points’ function and stores the result in the ‘points’ vector.
Then, the ‘draw’ function is called to draw the line using the points, the input image, the specified
color, the image dimensions, and the “circle radius” (cradius). After drawing each line, the function
clears the ‘points’ vector to prepare it for the next line.
The ‘flood_fill’ function is a simple recursive algorithm used to replace a specific color in an image
with another color within a connected region. It takes six parameters: a vector of tuples representing
the colors of the input image, the x and y coordinates of the starting point, tuples representing the
old and new colors, and the width of the input image.
The function begins by checking if the color at the current coordinates (x, y) in the image is equal
to the old color specified. If the colors match, it replaces the old color at that position with the new
color. Then, the function recursively calls itself to perform the flood fill operation in four directions:
right (x+1, y), down (x, y+1), left (x-1, y), and up (x, y-1).
11 Presentation, Collaboration, and Investigation 47

This process continues until the function reaches pixels with a color different from the old color,
effectively filling the connected region of pixels with the new color.

Step #10: 16_draw_market_size10.ppm

An image is being created with various hexagons drawn on it. The code starts by declaring a vector
of tuples called ‘image8’, which will represent the colors in the image. The ‘image8’ vector is
resized to fit the dimensions of the image, which are calculated using the ‘calc_size(width, height)’
function.
Next, the ‘fcolor’ tuple is created using the ‘std::make_tuple’ function with RGB values (1.0f, 1.0f,
1.0f), representing the color white. The ‘draw_hexagon’ function is then called four times with
different parameters, each time drawing a hexagon on ‘image8’ with the specified color, center
coordinates, radius, image width, image height, and circle radius used for drawing the hexagon
lines.
The first hexagon is drawn with its center at (784, 340) and a radius of 190. The second hexagon is
drawn with its center at (520, 500) and a radius of 143. The third hexagon is drawn with its center
at (730, 610) and a radius of 107. Finally, the fourth hexagon is drawn with its center at (900, 680)
and a radius of 76.

Step #11: 16_draw_market_size11.ppm

The ‘blend_hexagon’ function is designed to blend two images, represented by the vectors ‘blend1’
and ‘blend2’, based on a specific color condition. The function takes in four parameters: the two
image vectors ‘blend1’ and ‘blend2’, and the dimensions of the images, ‘width’ and ‘height’.
First, the function initializes two color tuples, ‘color1’ and ‘color2’. ‘color1’ is initialized to (0.0f,
0.0f, 0.0f), which represents black, while ‘color2’ is initialized to (1.0f, 1.0f, 1.0f), which represents
white. The function also initializes three float variables, ‘r’, ‘g’, and ‘b’, and an ‘alpha’ variable with
a value of 0.8f. The ‘alpha’ value will be used to blend the colors from the two images.
The function then iterates through all the pixels in the images using nested for-loops. For each pixel,
it checks if the color of the corresponding pixel in ‘blend2’ is equal to ‘color2’, which is white. If
the condition is met, it retrieves the color of the corresponding pixel in ‘blend1’ and blends it with
black (0.0f, 0.0f, 0.0f), using the ‘alpha’ value to determine the degree of blending.
After blending the colors, the result is stored back in the ‘blend1’ image at the corresponding pixel
11 Presentation, Collaboration, and Investigation 48

position. The blending is performed by multiplying each color component (red, green, and blue) of
the color from ‘blend1’ by the ‘alpha’ value, then adding the product of the black color component
and (1.0f - ‘alpha’). The new color tuple is created using the ‘std::make_tuple’ function and is
assigned to the corresponding pixel in the ‘blend1’ image.

Step #12: 16_draw_market_size12.ppm

The ‘add_white_hexagon_border’ function is designed to add a white border to an image based


on the white pixels in another image. The function takes in four parameters: two image vectors,
‘image1’ and ‘image2’, and the dimensions of the images, ‘width’ and ‘height’.
First, the function initializes a color tuple named ‘color’ with the values (1.0f, 1.0f, 1.0f), which
represents the color white.
Next, the function iterates through all the pixels in the images using nested for-loops. For each pixel,
it checks if the color of the corresponding pixel in ‘image2’ is equal to ‘color’, which is white. If the
condition is met, it sets the color of the corresponding pixel in ‘image1’ to white.

Step #13: 16_draw_market_size13.ppm

The ‘draw_label_lines’ function is designed to draw multiple lines on an image with a specific color
and thickness. The function accepts five parameters: a reference to the image vector, a reference
to the color tuple, the width and height of the image, and the thickness of the lines represented as
radius.
First, the function initializes a ‘coords’ tuple, which will store the coordinates of the starting and
ending points of the lines to be drawn. It also initializes a ‘points’ vector, which will store the points
on the line.

Step #14: 16_draw_market_size14.ppm

This code defines a function called ‘draw_labels’ that takes three arguments: a reference to a vector
11 Presentation, Collaboration, and Investigation 49

of tuples called ‘image’, a reference to a tuple called ‘color’, and two integers called ‘width’ and
‘height’. The function is designed to draw labels on an image using a specified color.
The image is represented by a vector of tuples, where each tuple contains three floating-point values
representing the red, green, and blue channels of a pixel. The ‘color’ tuple also contains three
floating-point values that represent the red, green, and blue channels of the desired color for the
labels.
The ‘draw_labels’ function begins by defining a hard-coded label called ‘lable_10’, which is a
series of 0s and 1s that represent the pixel values of an image. This label was created in a graphics
application and converted to a binary format to be used in this function. The 0s represent transparent
pixels, while the 1s represent the color specified by the ‘color’ argument.
The purpose of the function is to draw this ‘lable_10’ on the ‘image’ using the specified ‘color’,
‘width’, and ‘height’. However, the provided code only defines the ‘lable_10’ data and does not
include the necessary steps to draw the label on the image. The actual drawing process would
involve iterating through the lable_10 data, and for each 1 encountered, setting the corresponding
pixel in the ‘image’ vector to the specified ‘color’.

Step #15: 16_draw_market_size15.ppm

Pie chart in PPM, take a look in Appendix A: 16_draw_market_size.cpp


11 Presentation, Collaboration, and Investigation 50

11.7 Draw a more advanced chart 2


The code is designed to create a noise image. It is composed of two main parts: variable declarations
and initialization, and a function definition. The code first defines a vector of tuples called ‘image1’
to store the noise image data. Each tuple contains three float values that represent the red, green,
and blue channels of a pixel. The width and height of the image are then set to 1600 and 900
pixels, respectively. The ‘image1’ vector is resized to the appropriate size using the ‘calc_size(width,
height)’ function.
The ‘generate_noise_image’ function is defined to create the noise image. It takes a reference to
a vector of tuples (‘image’), as well as the width and height of the image as its parameters. The
function generates a random grayscale color for each pixel in the image using a random number
generator (‘std::mt19937’) seeded by a random device (‘std::random_device’). The random number
generator is used to create a uniform distribution of float values between 0.0 and 1.0, which represent
the intensity of the grayscale color.
In the nested for loop, the code iterates through each pixel of the image. It generates a random
number (‘rndnum’) using the uniform distribution and the random number generator. This random
number is then used to create a grayscale color by setting the red, green, and blue channels to the
same value (‘rndnum’). The color is stored as a tuple and assigned to the corresponding index in
the ‘image’ vector using the ‘get_index(x, y, width)’ function. This process is repeated for all the
pixels in the image, resulting in a noise image.

Step #1: 16_draw_investment1.ppm

This C++ code generates a linear gradient image. It consists of two main parts: the declaration and
initialization of variables, and the definition of the ‘generate_linear_gradient_image’ function.
In the first part of the code, a vector of tuples called ‘image2’ is created to store the linear gradient
image data. Each tuple holds three float values representing the red, green, and blue channels of
a pixel. The width and height of the image are assumed to be already defined with values of 1600
and 900 pixels, respectively. The ‘image2’ vector is resized to the appropriate size using the ‘calc_-
size(width, height)’ function. The code then defines two tuples, ‘fcolor’ and ‘tcolor’, representing
the starting and ending colors of the gradient, and calls the ‘generate_linear_gradient_image’
function.
The ‘generate_linear_gradient_image’ function is defined to create the linear gradient image. It
takes a reference to a vector of tuples (‘image’), references to the starting and ending colors (‘fcolor’
and ‘tcolor’), and the width and height of the image as its parameters. The function calculates the
color of each pixel in the image by interpolating between the starting and ending colors based on
11 Presentation, Collaboration, and Investigation 51

the pixel’s position.


First, the red, green, and blue channels of the starting and ending colors are extracted using the
‘std::tie’ function. Then, the code iterates through the height of the image using a for loop. In
each iteration, it calculates the interpolation percentage based on the current vertical position of
the pixel. The red, green, and blue channels of the interpolated color are calculated by linearly
interpolating between the corresponding channels of the starting and ending colors using the
calculated percentage. The interpolated color is then stored as a tuple.
In the inner for loop, the code iterates through the width of the image. For each pixel in the
current row, the code assigns the interpolated color to the corresponding index in the ‘image’ vector
using the ‘get_index(x, y, width)’ function. This process is repeated for all the rows in the image,
ultimately generating a linear gradient image.

Step #2: 16_draw_investment2.ppm

‘blended_two_images’ takes two input images and blends them together based on a specified alpha
value. The images are passed as vectors of tuples (float, float, float), representing the red, green, and
blue (RGB) color values of each pixel. The function also takes the width and height of the images
and an alpha value, which is a float between 0 and 1.
The function starts by initializing three tuples named ‘color1’, ‘color2’, and three float variables ‘r’,
‘g’, and ‘b’ that will be used to store the RGB values of each pixel in the two images and the resultant
blended image. Two nested for loops are then used to iterate through each pixel in the input images.
The outer loop iterates through the rows (height), while the inner loop iterates through the columns
(width).
For each pixel, the corresponding color values are retrieved from the input images using the ‘get_-
index’ function and stored in ‘color1’ and ‘color2’. The red, green, and blue values of the blended
image are calculated by multiplying the corresponding color values from the second image by the
alpha value, and the color values from the first image by (1 - alpha), then summing them. These
blended RGB values are then stored in the first image vector using the ‘get_index’ function again.
Once the loops have finished iterating through all the pixels, the function has effectively modified
the first input image vector to store the blended image, while the second input image vector remains
unchanged.
11 Presentation, Collaboration, and Investigation 52

Step #3: 16_draw_investment3.ppm

‘generate_radial_gradient_image’ creates a radial gradient image with a specified size and two
colors. The radial gradient image is stored as a vector of tuples (float, float, float), representing the
red, green, and blue (RGB) color values of each pixel.
The function takes the following parameters: a reference to the image vector, references to two color
tuples (fcolor and tcolor), and the width and height of the image. The function starts by initializing
some variables: ‘color’ (a tuple to store the current pixel’s color), ‘pink’ (a pre-defined color tuple),
‘mask’ (a vector to store a circular mask), ‘distanceFromCenter’, ‘resultRed’, ‘resultGreen’, and
‘resultBlue’.
The first nested for loops fill the ‘mask’ and ‘image’ vectors with the ‘pink’ color and ‘fcolor’
respectively. Then, the function calculates the midpoint of the image (x0, y0) and initializes variables
‘d’, ‘xx’, and ‘yy’ to draw a circle using Bresenham’s circle algorithm.
A lambda function ‘drawline’ is defined within the function to draw horizontal lines between two
points (sx, ex) at the given y-coordinate (ny) in the ‘mask’ vector. The while loop uses Bresenham’s
circle algorithm to create a circular mask by drawing lines in the ‘mask’ vector using the ‘drawline’
function.
Finally, another set of nested for loops iterates through each pixel in the image. For each pixel, it
checks if the corresponding mask pixel is not equal to the ‘pink’ color. If so, it calculates the distance
from the center of the image to the current pixel and computes the interpolated color values based on
the distance and input colors (fcolor and tcolor). The resulting color tuple is assigned to the ‘image’
vector at the current position. If the mask pixel is equal to the ‘pink’ color, the ‘tcolor’ is assigned
directly to the ‘image’ vector.

Step #4: 16_draw_investment4.ppm

‘generate_repeating_texture_image’ generates a repeating texture pattern with a given width,


height, and color. The texture image is stored as a vector of tuples (float, float, float), representing
the red, green, and blue (RGB) color values of each pixel.
11 Presentation, Collaboration, and Investigation 53

The function takes the following parameters: a reference to the image vector, a reference to the
color tuple, and the width and height of the image. It begins by initializing a background color tuple
named ‘bgcolor’ to be a pinkish color. Then, using two nested for loops, it fills the ‘image’ vector
with this background color.
The function proceeds to define two integer arrays ‘arr’ and ‘arr2’ with hardcoded coordinates and
indices, representing the positions and connections of points in the pattern. The ‘coords’ tuple is
initialized to store the coordinates of the line endpoints in the pattern.
Next, the function iterates through the 13 hardcoded points using a for loop. During each iteration,
it creates a ‘coords’ tuple using the coordinates from the ‘arr’ array based on the indices found in
the ‘arr2’ array. The ‘draw_line’ function is then called with the ‘image’ vector, ‘coords’ tuple,
input color, width, and height as parameters. This function draws lines between the coordinates
specified by the ‘coords’ tuple in the image vector using the input color.

Step #5: 16_draw_investment5.ppm

‘render_repeating_texture_image’ takes a texture image and renders it repeatedly across a larger


image. Both the texture and the larger image are stored as vectors of tuples (float, float, float),
representing the red, green, and blue (RGB) color values of each pixel.
The function takes the following parameters: a reference to the texture vector, the width and height
of the texture (tw, th), a reference to the image vector, and the width and height of the image (iw,
ih). It uses two nested for loops to iterate through each pixel in the larger image. For each pixel,
the function retrieves the corresponding color value from the texture vector using the ‘get_index’
function, with the x and y coordinates of the pixel modulo (tw-1) and (th-1), respectively. This
ensures that the texture is repeated across the entire image. The retrieved color value is then assigned
to the corresponding pixel in the image vector.
11 Presentation, Collaboration, and Investigation 54

Step #6: 16_draw_investment6.ppm

‘do_cookie_cut’ extracts a rectangular section from a source image and stores it in another image,
often referred to as ‘cookie-cutting’. Both the source image and the resulting image are stored as
vectors of tuples (float, float, float), representing the red, green, and blue (RGB) color values of each
pixel.
The function takes the following parameters: a reference to the source image vector, the width and
height of the source image (w, h), a reference to the resulting image vector, the width and height of
the resulting image (cw, ch), and the starting x and y coordinates (startx, starty) of the rectangular
section to be extracted from the source image. It initializes two variables, cx and cy, to keep track
of the current x and y coordinates in the resulting image.
The function uses two nested for loops to iterate through the rectangular section of the source image,
starting from the specified starting coordinates (startx, starty) and covering the width and height
of the resulting image (cw, ch). For each pixel in the section, it copies the color value from the
source image to the corresponding position in the resulting image, using the ‘get_index’ function
to convert the 2D coordinates to a linear index. The cx and cy variables are updated accordingly to
move through the resulting image.

Step #7: 16_draw_investment7.ppm

‘add_honeycomb’ combines three images: a base image, an alpha image, and a texture image. The
base image and the texture image are combined using the red channel of the alpha image as a weight.
All three images are stored as vectors of tuples (float, float, float), representing the red, green, and
blue (RGB) color values of each pixel.
The function takes the following parameters: references to the base image vector, alpha image vector,
texture image vector, and the width and height of the images (w, h). It initializes several tuple
11 Presentation, Collaboration, and Investigation 55

variables to store the color values of the three images at each pixel and a pink color tuple (1.0f, 0.0f,
1.0f) to check against the texture image.
Using two nested for loops, the function iterates through each pixel of the images. If the color value
of the texture image at the current pixel is not pink, the function retrieves the color values of the
base, texture, and alpha images at the current pixel. It then calculates the new red, green, and blue
color values for the base image by interpolating between the texture and base images’ color values
using the red channel of the alpha image as a weight. The resulting color value is assigned back to
the base image at the current pixel.

Step #8: 16_draw_investment8.ppm

‘stamp_cookie’ places a smaller ‘cookie’ image onto a larger base image at a specified position. The
base image and the cookie image are stored as vectors of tuples (float, float, float), representing the
red, green, and blue (RGB) color values of each pixel.
The function takes the following parameters: references to the base image vector, its width and
height (w, h), the cookie image vector, its width and height (cw, ch), and the starting x and y
coordinates (startx, starty) for placing the cookie image onto the base image.
The function initializes two integer variables, cx and cy, to keep track of the current position within
the cookie image. It then uses two nested for loops to iterate through each pixel of the area where
the cookie image will be placed on the base image.
For each pixel in the specified area, the function retrieves the color value from the cookie image at the
current cx and cy coordinates and assigns it to the base image at the current x and y coordinates. The
cx variable is incremented for each iteration of the inner loop, while the cy variable is incremented
for each iteration of the outer loop. After the inner loop is completed, the cx variable is reset to 0 to
start processing the next row of the cookie image.

Step #9: 16_draw_investment9.ppm

The code creates an image of a doughnut shape with various shades of gray and white, as well as
11 Presentation, Collaboration, and Investigation 56

some additional labels. The doughnut consists of a series of filled wedges and lines drawn on a base
image.
The base image, ‘image7’, is initialized as a vector of tuples (float, float, float), representing the red,
green, and blue (RGB) color values of each pixel. The base image is then resized to the desired width
and height.
The image is first cleared to a solid color (magenta) using the ‘clear_image’ function. Next, the
doughnut shape is constructed by drawing filled wedges and lines with different shades of gray and
white. The ‘draw_filled_wedge’ function is used to draw the filled wedges, while the ‘draw_line’
function is used to draw the lines. Each of these functions takes the image, coordinates, and color
information as input.
Finally, the ‘draw_labels’ function is called to add labels to the image. This function takes the image,
color (white), width, and height as input.

Step #10: 16_draw_investment10.ppm

The code adds the previously created doughnut shape to the ‘image1’ by copying the non-magenta
pixels from ‘image7’ to ‘image1’. The magenta color (1.0f, 0.0f, 1.0f) is used as a background color
in ‘image7’ and is not copied to ‘image1’.
The code first defines the magenta color as ‘fcolor’, which will be used to identify the background
pixels that should not be copied.
Then, two nested loops iterate over the height and width of the images. For each pixel coordinate (x,
y), the code checks if the pixel in ‘image7’ is not magenta (i.e., not equal to ‘fcolor’). If the condition
is true, the non-magenta pixel from ‘image7’ is copied to the corresponding position in ‘image1’.
In summary, the code adds the doughnut shape from ‘image7’ to ‘image1’ by copying only the
non-magenta pixels from ‘image7’ to their corresponding positions in ‘image1’.

Step #11: 16_draw_investment11.ppm

Pie chart in PPM, take a look in Appendix A: 16_draw_investment.cpp


11 Presentation, Collaboration, and Investigation 57

11.8 Collaboration
We can use 2D charts and diagrams to help us understand and solve problems collaboratively. For
example, we can use a chart to visualize the relationships between different elements in a problem
or a diagram to explore the potential solutions to a problem.
2D charts and diagrams are also helpful for communicating our ideas to others. We can use them
to explain our thinking process or present our findings clearly and concisely.
When working with 2D graphs and diagrams, it is vital to know the different types of data they
can represent. For instance, some charts are better suited for displaying quantitative data, while
others are more effective for visualizing qualitative data. Additionally, we must be careful when
interpreting data from 2D graphs and diagrams, as they can sometimes be misleading.
Despite these limitations, 2D graphs and diagrams are powerful tools that can help us think more
creatively and solve problems more effectively. With a bit of practice, we can learn to use them in
various ways to improve our collaborative problem-solving skills.
Peacock chart in PPM, take a look in Appendix A: 17_colab_peacock.cpp

peacock graph

11.9 Investigation
There is a reason that businesses, law enforcement agencies, military intelligence use data visualiza-
tion when investigating crimes or irregularities - it works. By taking large data sets and representing
them in an easily digestible format, investigators can quickly identify patterns and relationships
that would otherwise be difficult to spot. The right data can help investigators piece together what
happened and who was involved.
Also for a security incident a simple graph can give you some important information as when
something happend and the amout of actvity. Also what kind of activity in the log.

Investigating log
12 PPM++ header-only library
Hello everyone,
I am pleased to announce the release of my c++ header-only library for 2D graphics. This library is
designed to make it easy to create beautiful and performant 2D graphics applications using c++17.
It is available on Github under the MIT license. I would love to hear your feedback!
You’ll find the header-only library here: https://gist.github.com/chbtoys/cdd6a85e321593ea0a1e7141d0a09fbc
… and a test.cpp here: https://gist.github.com/chbtoys/a665b52f86768b8e601c82b47ce18e49
Or clone from Github.com.

1 git clone https://github.com/chbtoys/ppmpp.git


2 cd ppmpp
3 clang++ -std=c++20 test.cpp -o test
4 ./test

(C++20 for std::lerp when creating bezier curves)


13 In the Rearview Mirror
What’s next? Maybe make a header-only .HPP framework of your own or extend the one that
already exists.
There are of course more 2D graphic techniques then included in the book. Please, feel free to
expande the code the way you want.
There are some helpfull tools that definitely is nice to have. Image Magick1 to convert PPM to
PNG/JPG/GIF and FFMPEG2 to combine still images into a animation. Both are nice tools to have.
Thank you for your time.

1 https://imagemagick.org/index.php
2 https://ffmpeg.org/
14 Appendix A: Source Code Listings
01_tuples.cpp - 1521 bytes.

1 // Compile: clang++ -std=c++17 01_tuples.cpp -o 01_tuples


2
3 #include <iostream>
4 #include <tuple>
5
6 std::tuple<int, int, int> get_rgb_elements_as_a_tuple(int r, int g, int b)
7 {
8 return std::make_tuple(r, g, b);
9 }
10
11 int main()
12 {
13 int r1=212; int g1=24; int b1=118;
14 int r2=0; int g2=0; int b2=0;
15 int r3=0; int g3=0; int b3=0;
16 std::tuple<int, int, int> rgb;
17
18 std::cout << "r1: " << r1 << " g1: " << g1 << " b1: " << b1 << std::endl;
19 std::cout << "r2: " << r2 << " g2: " << g2 << " b2: " << b2 << std::endl;
20 std::cout << "r3: " << r3 << " g3: " << g3 << " b3: " << b3 << std::endl;
21
22 std::cout << "rgb=get_rgb_elements_as_a_tuple(r1, g1, b1);" << std::endl;
23 rgb=get_rgb_elements_as_a_tuple(r1, g1, b1);
24
25 // unroll #1
26 std::cout << "unroll #1" << std::endl;
27 r2=std::get<0>(rgb);
28 g2=std::get<1>(rgb);
29 b2=std::get<2>(rgb);
30 std::cout << "r2=std::get<0>(rgb); g2=std::get<1>(rgb); b2=std::get<2>(rgb);" << st\
31 d::endl;
32 std::cout << "r1: " << r1 << " g1: " << g1 << " b1: " << b1 << std::endl;
33 std::cout << "r2: " << r2 << " g2: " << g2 << " b2: " << b2 << std::endl;
34 std::cout << "r3: " << r3 << " g3: " << g3 << " b3: " << b3 << std::endl;
35 // unroll #2
36 std::cout << "unroll #2" << std::endl;
14 Appendix A: Source Code Listings 61

37 std::tie(r3, g3, b3) = rgb;


38 std::cout << "std::tie(r3, g3, b3) = rgb;" << std::endl;
39 std::cout << "r1: " << r1 << " g1: " << g1 << " b1: " << b1 << std::endl;
40 std::cout << "r2: " << r2 << " g2: " << g2 << " b2: " << b2 << std::endl;
41 std::cout << "r3: " << r3 << " g3: " << g3 << " b3: " << b3 << std::endl;
42
43 return 0;
44 }

02_index.cpp - 1630 bytes.

1 // Compile: clang++ -std=c++17 02_index.cpp -o 02_index


2
3 #include <iostream>
4
5 int get_index(int x, int y, int width)
6 {
7 return x+width*y;
8 }
9
10 int main()
11 {
12 int width=10;
13 int x=0;
14 int y=0;
15
16 std::cout << "Index: " << get_index(x,y,width) << " (for X:" << x << " Y:" << y << \
17 ")" << std::endl;
18 y=1;x=5;
19 std::cout << "Index: " << get_index(x,y,width) << " (for X:" << x << " Y:" << y << \
20 ")" << std::endl;
21 y=2;x=3;
22 std::cout << "Index: " << get_index(x,y,width) << " (for X:" << x << " Y:" << y << \
23 ")" << std::endl;
24 y=3;x=2;
25 std::cout << "Index: " << get_index(x,y,width) << " (for X:" << x << " Y:" << y << \
26 ")" << std::endl;
27 y=4;x=3;
28 std::cout << "Index: " << get_index(x,y,width) << " (for X:" << x << " Y:" << y << \
29 ")" << std::endl;
30 y=6;x=6;
31 std::cout << "Index: " << get_index(x,y,width) << " (for X:" << x << " Y:" << y << \
32 ")" << std::endl;
14 Appendix A: Source Code Listings 62

33 y=7;x=2;
34 std::cout << "Index: " << get_index(x,y,width) << " (for X:" << x << " Y:" << y << \
35 ")" << std::endl;
36 y=9;x=8;
37 std::cout << "Index: " << get_index(x,y,width) << " (for X:" << x << " Y:" << y << \
38 ")" << std::endl << std::endl;
39
40 std::cout << " 0123456789" << std::endl;
41 std::cout << "0+---------- I: 0" << std::endl;
42 std::cout << "1-----+----- I: 15" << std::endl;
43 std::cout << "2---+------- I: 23" << std::endl;
44 std::cout << "3--+-------- I: 32" << std::endl;
45 std::cout << "4---+------- I: 43" << std::endl;
46 std::cout << "5----------- N/A" << std::endl;
47 std::cout << "6------+---- I: 66" << std::endl;
48 std::cout << "7--+-------- I: 72" << std::endl;
49 std::cout << "8----------- N/A" << std::endl;
50 std::cout << "9--------+-- I: 98" << std::endl;
51
52 return 0;
53 }

03_calcsize.cpp - 908 bytes.

1 // Compile: clang++ -std=c++17 03_calcsize.cpp -o 03_calcsize


2
3 #include <iostream>
4 #include <tuple>
5 #include <vector>
6
7 int get_index(int x, int y, int width)
8 {
9 return x+width*y;
10 }
11
12 int calc_size(int width, int height)
13 {
14 return width*height;
15 }
16
17 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
18 at, float, float> &color, int width, int height)
19 {
14 Appendix A: Source Code Listings 63

20 for (int y=0;y<height;++y) {


21 for (int x=0;x<width;++x) {
22 image[get_index(x,y,width)]=color;
23 }
24 }
25 }
26
27 int main()
28 {
29 std::vector<std::tuple<float, float, float>> image;
30 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.0f);
31 int width=640;
32 int height=360;
33
34 image.resize(calc_size(width, height));
35 std::cout << "Created a vector with the size: " << calc_size(width, height) << std:\
36 :endl;
37 clear_image(image,color,width,height);
38 std::cout << "Cleared image with black color." << std::endl;
39
40 return 0;
41 }

04_helloworld.cpp - 2265 bytes.

1 // Compile: clang++ -std=c++17 04_helloworld.cpp -o 04_helloworld


2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7
8 int get_index(int x, int y, int width)
9 {
10 return x+width*y;
11 }
12
13 int calc_size(int width, int height)
14 {
15 return width*height;
16 }
17
18 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
14 Appendix A: Source Code Listings 64

19 at, float, float> &color, int width, int height)


20 {
21 for (int y=0;y<height;++y) {
22 for (int x=0;x<width;++x) {
23 image[get_index(x,y,width)]=color;
24 }
25 }
26 }
27
28 void first_draw(std::vector<std::tuple<float, float, float>> &image, int width, int \
29 height)
30 {
31 std::tuple<float, float, float> color;
32 int ctr=0;
33 for (int y=height-1;y>=0;--y)
34 {
35 for (int x=0;x<width;++x) {
36 float r = float(x) / float(width);
37 float g = float(y) / float(height);
38 float b = 0.2;
39 color=std::make_tuple(r, g, b);
40 image[ctr]=color;
41 ctr++;
42 }
43 }
44 }
45
46 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
47 height, std::string filename)
48 {
49 std::tuple<float, float, float> color;
50 std::ofstream out(filename, std::ofstream::out);
51 out << "P3\n" << width << " " << height << "\n255\n";
52 for (int i=0;i<(width*height);++i)
53 {
54 color=image[i];
55 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
56 " " << int(std::get<2>(color)*255.0f) << '\n';
57 }
58 out.close();
59 }
60
61 int main()
14 Appendix A: Source Code Listings 65

62 {
63 std::vector<std::tuple<float, float, float>> image;
64 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.06666666667f);
65 int width=640;
66 int height=360;
67
68 image.resize(calc_size(width, height));
69 std::cout << "Created a vector with the size: " << calc_size(width, height) << std:\
70 :endl;
71 clear_image(image,color,width,height);
72 std::cout << "Cleared image with dark blue color." << std::endl;
73 first_draw(image,width,height);
74 std::cout << "Drawing the first image pixel by pixel" << std::endl;
75 save_image(image,width,height,"04_helloworld.ppm");
76 std::cout << "Saved: 04_helloworld.ppm" << std::endl;
77
78 // Create square (for 08; blending colors).
79 std::vector<std::tuple<float, float, float>> square;
80 width=256;height=256;
81 square.resize(calc_size(width, height));
82 first_draw(square,width,height);
83 save_image(square,width,height,"04_helloworld_square.ppm");
84
85 return 0;
86 }

05_randomwalker.cpp - 5472 bytes.

1 // Compile: clang++ -std=c++17 05_randomwalker.cpp -o 05_randomwalker


2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <random>
8 #include <algorithm>
9
10 bool startsWithCaseInsensitive(std::string mainStr, std::string toMatch)
11 {
12 // Convert mainStr to lower case
13 std::transform(mainStr.begin(), mainStr.end(), mainStr.begin(), ::tolower);
14 // Convert toMatch to lower case
15 std::transform(toMatch.begin(), toMatch.end(), toMatch.begin(), ::tolower);
14 Appendix A: Source Code Listings 66

16 if(mainStr.find(toMatch) == 0)
17 return true;
18 else
19 return false;
20 }
21
22 int get_index(int x, int y, int width)
23 {
24 return x+width*y;
25 }
26
27 int calc_size(int width, int height)
28 {
29 return width*height;
30 }
31
32 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
33 at, float, float> &color, int width, int height)
34 {
35 for (int y=0;y<height;++y) {
36 for (int x=0;x<width;++x) {
37 image[get_index(x,y,width)]=color;
38 }
39 }
40 }
41
42 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
43 height, std::string filename)
44 {
45 std::tuple<float, float, float> color;
46 std::ofstream out(filename, std::ofstream::out);
47 out << "P3\n" << width << " " << height << "\n255\n";
48 for (int i=0;i<(width*height);++i)
49 {
50 color=image[i];
51 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
52 " " << int(std::get<2>(color)*255.0f) << '\n';
53 }
54 out.close();
55 }
56
57 std::tuple<int,int> get_width_and_height(const std::string str)
58 {
14 Appendix A: Source Code Listings 67

59 size_t start;
60 size_t end = 0;
61 std::vector<std::string> out;
62
63 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
64 {
65 end = str.find(' ', start);
66 out.push_back(str.substr(start, end - start));
67 }
68
69 int w=stoi(out[0]);
70 int h=stoi(out[1]);
71
72 return std::make_tuple(w,h);
73 }
74
75 std::tuple<int,int,int> get_color(const std::string str)
76 {
77 size_t start;
78 size_t end = 0;
79 std::vector<std::string> out;
80
81 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
82 {
83 end = str.find(' ', start);
84 out.push_back(str.substr(start, end - start));
85 }
86
87 int r=stoi(out[0]);
88 int g=stoi(out[1]);
89 int b=stoi(out[2]);
90
91 return std::make_tuple(r,g,b);
92 }
93
94 void read_image(std::vector<std::tuple<float, float, float>> &image, int &width, int\
95 &height, std::string filename)
96 {
97 std::ifstream infile(filename);
98 std::tuple<int, int, int> rcolor;
99 std::tuple<float, float, float> wcolor;
100 std::tuple<int,int> widthnheight;
101 std::string line;
14 Appendix A: Source Code Listings 68

102 int state=0;


103 bool done = false;
104
105 while (getline(infile, line))
106 {
107 if (startsWithCaseInsensitive(line,"P3") && state == 0) {
108 state=1;
109 }
110
111 if (!startsWithCaseInsensitive(line,"#") && !startsWithCaseInsensitive(line,"P3") \
112 && state == 1) {
113 widthnheight=get_width_and_height(line);
114 width=std::get<0>(widthnheight);
115 height=std::get<1>(widthnheight);
116 state=2;
117 }
118
119 if (startsWithCaseInsensitive(line,"255") && state == 2) {
120 state=3;
121 }
122
123 if (!(line.compare("255") == 0) && state == 3) {
124 rcolor=get_color(line);
125 wcolor=std::make_tuple(float(std::get<0>(rcolor)/255.0f), float(std::get<1>(
126 r)/255.0f), float(std::get<2>(rcolor)/255.0f));
127 image.push_back(wcolor);
128 done = true;
129 }
130 }
131 infile.close();
132 }
133
134 void update_x_and_y(int r, std::tuple<int,int> &walk1, std::tuple<int,int> &walk2, i\
135 nt width, int height)
136 {
137 int x1,y1,x2,y2;
138 std::tie(x1,y1) = walk1;
139 std::tie(x2,y2) = walk2;
140
141 switch(r) {
142 case 0:
143 x1+=1;
144 x2-=1;
14 Appendix A: Source Code Listings 69

145 break;
146 case 1:
147 x1-=1;
148 x2+=1;
149 break;
150 case 2:
151 y1+=1;
152 y2-=1;
153 break;
154 case 3:
155 y1-=1;
156 y2+=1;
157 break;
158 }
159
160 if (x1 < 0) {
161 x1 = 0;
162 } else if (x1 > width-1) {
163 x1=width-1;
164 }
165
166 if (x2 < 0) {
167 x2 = 0;
168 } else if (x2 > width-1) {
169 x2=width-1;
170 }
171
172 if (y1 < 0) {
173 y1 = 0;
174 } else if (y1 > height-1) {
175 y1 = height-1;
176 }
177
178 if (y2 < 0) {
179 y2 = 0;
180 } else if (y2 > height-1) {
181 y2 = height-1;
182 }
183
184 walk1=std::make_tuple(x1,y1);
185 walk2=std::make_tuple(x2,y2);
186 }
187
14 Appendix A: Source Code Listings 70

188 void walker(std::vector<std::tuple<float, float, float>> &image1, std::vector<std::t\


189 uple<float, float, float>> &image2, int width, int height)
190 {
191 // Randomize and draw walkers
192 std::tuple<float, float, float> color;
193 int x1=width/2;
194 int y1=height/2;
195 int x2=width/2;
196 int y2=height/2;
197
198 std::random_device rd;
199 std::mt19937 mt(rd());
200 std::uniform_int_distribution<> dist(0, 3);
201
202 std::tuple<int,int> walk1=std::make_tuple(x1,y1);
203 std::tuple<int,int> walk2=std::make_tuple(x2,y2);
204
205 int r=0;
206 for (int i=0;i<100000;++i) {
207 r=dist(mt);
208 update_x_and_y(r,walk1,walk2,width,height);
209 color=image1[get_index(std::get<0>(walk1), std::get<1>(walk1), width)];
210 image2[get_index(std::get<0>(walk1), std::get<1>(walk1), width)]=color;
211 color=image1[get_index(std::get<0>(walk2), std::get<1>(walk2), width)];
212 image2[get_index(std::get<0>(walk2), std::get<1>(walk2), width)]=color;
213 }
214 }
215
216 int main()
217 {
218 std::vector<std::tuple<float, float, float>> image1;
219 std::vector<std::tuple<float, float, float>> image2;
220 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.06666666667f);
221 int width=0;
222 int height=0;
223
224 read_image(image1, width, height, "04_helloworld.ppm");
225
226 image2.resize(calc_size(width, height));
227 std::cout << "Created a vector with the size: " << calc_size(width, height) << std:\
228 :endl;
229 clear_image(image2,color,width,height);
230 std::cout << "Cleared image with dark blue color." << std::endl;
14 Appendix A: Source Code Listings 71

231 // Random Walker


232 walker(image1,image2,width,height);
233 save_image(image2,width,height,"05_randomwalker.ppm");
234 std::cout << "Saved: 05_randomwalker.ppm" << std::endl;
235
236 return 0;
237 }

06_xor_and_or_texture.cpp - 3095 bytes.

1 // Compile: clang++ -std=c++17 06_xor_and_or_texture.cpp -o 06_xor_and_or_texture


2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7
8 int get_index(int x, int y, int width)
9 {
10 return x+width*y;
11 }
12
13 int calc_size(int width, int height)
14 {
15 return width*height;
16 }
17
18 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
19 at, float, float> &color, int width, int height)
20 {
21 for (int y=0;y<height;++y) {
22 for (int x=0;x<width;++x) {
23 image[get_index(x,y,width)]=color;
24 }
25 }
26 }
27
28 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
29 height, std::string filename)
30 {
31 std::tuple<float, float, float> color;
32 std::ofstream out(filename, std::ofstream::out);
33 out << "P3\n" << width << " " << height << "\n255\n";
14 Appendix A: Source Code Listings 72

34 for (int i=0;i<(width*height);++i)


35 {
36 color=image[i];
37 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
38 " " << int(std::get<2>(color)*255.0f) << '\n';
39 }
40 out.close();
41 }
42
43 void draw_xor(std::vector<std::tuple<float, float, float>> &image, int width, int he\
44 ight)
45 {
46 std::tuple<float, float, float> color;
47 int c=0;
48
49 for (int y=0;y<height;++y)
50 {
51 for (int x=0;x<width;++x) {
52 c = x ^ y;// XOR
53 color=std::make_tuple(float(c/255.0f), float(c/255.0f), float(c/255.0f));
54 image[get_index(x, y, width)]=color;
55 }
56 }
57 }
58
59 void draw_and(std::vector<std::tuple<float, float, float>> &image, int width, int he\
60 ight)
61 {
62 std::tuple<float, float, float> color;
63 int c=0;
64
65 for (int y=0;y<height;++y)
66 {
67 for (int x=0;x<width;++x) {
68 c = x & y;// AND
69 color=std::make_tuple(float(c/255.0f), float(c/255.0f), float(c/255.0f));
70 image[get_index(x, y, width)]=color;
71 }
72 }
73 }
74
75 void draw_or(std::vector<std::tuple<float, float, float>> &image, int width, int hei\
76 ght)
14 Appendix A: Source Code Listings 73

77 {
78 std::tuple<float, float, float> color;
79 int c=0;
80
81 for (int y=0;y<height;++y)
82 {
83 for (int x=0;x<width;++x) {
84 c = x | y;// OR
85 color=std::make_tuple(float(c/255.0f), float(c/255.0f), float(c/255.0f));
86 image[get_index(x, y, width)]=color;
87 }
88 }
89 }
90
91 int main()
92 {
93 std::vector<std::tuple<float, float, float>> image;
94 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.06666666667f);
95 int width=256;
96 int height=256;
97
98 image.resize(calc_size(width, height));
99 std::cout << "Created a vector with the size: " << calc_size(width, height) << std:\
100 :endl;
101 clear_image(image,color,width,height);
102 std::cout << "Cleared image with dark blue color." << std::endl;
103 // XOR Texture
104 draw_xor(image,width,height);
105 std::cout << "XOR Texture drawn." << std::endl;
106 save_image(image,width,height,"06_xor_texture.ppm");
107 std::cout << "Saved: 06_xor_texture.ppm" << std::endl;
108 // AND Texture
109 draw_and(image,width,height);
110 std::cout << "AND Texture drawn." << std::endl;
111 save_image(image,width,height,"06_and_texture.ppm");
112 std::cout << "Saved: 06_and_texture.ppm" << std::endl;
113 // OR Texture
114 draw_or(image,width,height);
115 std::cout << "OR Texture drawn." << std::endl;
116 save_image(image,width,height,"06_or_texture.ppm");
117 std::cout << "Saved: 06_or_texture.ppm" << std::endl;
118
119 return 0;
14 Appendix A: Source Code Listings 74

120 }

07_clouds_marble_wood_texture.cpp - 6128 bytes.

1 // Compile: clang++ -std=c++17 07_clouds_marble_wood_texture.cpp -o 07_clouds_marble\


2 _wood_texture
3 #define _USE_MATH_DEFINES
4
5 #include <iostream>
6 #include <fstream>
7 #include <tuple>
8 #include <vector>
9 #include <random>
10 #include <cmath>
11
12 int get_index(int x, int y, int width)
13 {
14 return x+width*y;
15 }
16
17 int calc_size(int width, int height)
18 {
19 return width*height;
20 }
21
22 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
23 at, float, float> &color, int width, int height)
24 {
25 for (int y=0;y<height;++y) {
26 for (int x=0;x<width;++x) {
27 image[get_index(x,y,width)]=color;
28 }
29 }
30 }
31
32 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
33 height, std::string filename)
34 {
35 std::tuple<float, float, float> color;
36 std::ofstream out(filename, std::ofstream::out);
37 out << "P3\n" << width << " " << height << "\n255\n";
38 for (int i=0;i<(width*height);++i)
39 {
14 Appendix A: Source Code Listings 75

40 color=image[i];
41 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
42 " " << int(std::get<2>(color)*255.0f) << '\n';
43 }
44 out.close();
45 }
46
47 void generate_noise(std::vector<double> &noise, int width, int height)
48 {
49 std::random_device rd;
50 std::mt19937 mt(rd());
51 std::uniform_real_distribution<> dist(0.0, 1.0);
52
53 for (int y=0;y<height;++y) {
54 for (int x=0;x<width;++x) {
55 noise[get_index(x,y,width)]=dist(mt);
56 }
57 }
58 }
59
60 double smooth_noise(double x, double y, int width, int height, std::vector<double> &\
61 noise)
62 {
63 // Get fractional part of X and Y.
64 double fractionX = x - int(x);
65 double fractionY = y - int(y);
66
67 // Wrap around.
68 int x1 = (int(x) + width) % width;
69 int y1 = (int(y) + height) % height;
70
71 // Neighbor values.
72 int x2 = (x1 + width - 1) % width;
73 int y2 = (y1 + height - 1) % height;
74
75 // Smoth the noise with bilinear interpolation.
76 double value=0.0;
77 value += fractionX * fractionY * noise[get_index(x1,y1,width)];
78 value += (1 - fractionX) * fractionY * noise[get_index(x2,y1,width)];
79 value += fractionX * (1 - fractionY) * noise[get_index(x1,y2,width)];
80 value += (1 - fractionX) * (1 - fractionY) * noise[get_index(x2,y2,width)];
81
82 return value;
14 Appendix A: Source Code Listings 76

83 }
84
85 double turbulence(double x, double y, int width, int height, double size, std::vecto\
86 r<double> &noise)
87 {
88 double value = 0.0;
89 double initialSize = size;
90
91 while (size >= 1)
92 {
93 value += smooth_noise(x/size,y/size,width,height,noise) * size;
94 size /= 2.0;
95 }
96
97 return (128.0 * value / initialSize);
98 }
99
100 void generate_cloud(std::vector<std::tuple<float, float, float>> &image, int width, \
101 int height, std::vector<double> &noise)
102 {
103 std::tuple<float, float, float> color;
104 int c=0;
105
106 for (int y=0;y<height;++y)
107 {
108 for (int x=0;x<width;++x) {
109 c=int(turbulence(double(x),double(y),width,height,64,noise));
110 color=std::make_tuple(float(c/255.0f), float(c/255.0f), float(c/255.0f));
111 image[get_index(x, y, width)]=color;
112 }
113 }
114 }
115
116 void generate_marble(std::vector<std::tuple<float, float, float>> &image, int width,\
117 int height, std::vector<double> &noise)
118 {
119 std::tuple<float, float, float> color;
120
121 // xPeriod and yPeriod together define the angle of the lines.
122 // xPeriod and yPeriod both 0 ==> it becomes a normal clouds or turbulence pattern.
123 double xPeriod = 5.0; // Defines repetition of marble lines in x direction.
124 double yPeriod = 10.0; // Defines repetition of marble lines in y direction.
125 // turbulencePower = 0 ==> it becomes a normal sine pattern.
14 Appendix A: Source Code Listings 77

126 double turbulencePower = 5.0; // Makes twists.


127 double turbulenceSize = 32.0; // Initial size of the turbulence.
128
129 double xyValue = 0.0;
130 double sineValue = 0.0;
131
132 for (int y=0;y<height;++y)
133 {
134 for (int x=0;x<width;++x) {
135 xyValue = x * xPeriod / width + y * yPeriod / height + turbulencePower * tur
136 ce(double(x),double(y),width,height,turbulenceSize,noise) / 255.0;
137 sineValue = 256 * fabs(sin(xyValue * M_PI));
138 color=std::make_tuple(float(sineValue/255.0f), float(sineValue/255.0f), floa
139 eValue/255.0f));
140 image[get_index(x, y, width)]=color;
141 }
142 }
143 }
144
145 void generate_wood(std::vector<std::tuple<float, float, float>> &image, int width, i\
146 nt height, std::vector<double> &noise)
147 {
148 std::tuple<float, float, float> color;
149
150 double xyPeriod = 25.0; // Number of rings.
151 double turbulencePower = 0.1; // Makes twists.
152 double turbulenceSize = 32.0; // Initial size of the turbulence.
153
154 double sineValue = 0.0;
155 double distValue = 0.0;
156 double xValue = 0.0;
157 double yValue = 0.0;
158
159 for (int y=0;y<height;++y)
160 {
161 for (int x=0;x<width;++x) {
162 xValue = (x - width / 2) / double(width);
163 yValue = (y - height / 2) / double(height);
164 distValue = sqrt(xValue * xValue + yValue * yValue) + turbulencePower * turb
165 e(double(x),double(y),width,height,turbulenceSize,noise) / 255.0;
166 sineValue = 128.0 * fabs(sin(2 * xyPeriod * distValue * M_PI));
167 color=std::make_tuple(float((80 + sineValue)/255.0f), float((30 + sineValue)
168 0f), float(30.0f/255.0f));
14 Appendix A: Source Code Listings 78

169 image[get_index(x, y, width)]=color;


170 }
171 }
172 }
173
174 int main()
175 {
176 std::vector<double> noise;
177 std::vector<std::tuple<float, float, float>> image;
178 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.06666666667f);
179 int width=256;
180 int height=256;
181
182 image.resize(calc_size(width, height));
183 std::cout << "Created a vector with the size: " << calc_size(width, height) << std:\
184 :endl;
185 clear_image(image,color,width,height);
186 std::cout << "Cleared image with dark blue color." << std::endl;
187 // Generate noise
188 noise.resize(calc_size(width, height));
189 generate_noise(noise,width,height);
190 std::cout << "Generated noise." << std::endl;
191 // Cloud Texture
192 generate_cloud(image,width,height,noise);
193 std::cout << "Generated Cloud." << std::endl;
194 save_image(image,width,height,"07_cloud_texture.ppm");
195 std::cout << "Save Cloud." << std::endl;
196 // Marble Texture
197 generate_marble(image,width,height,noise);
198 std::cout << "Generated Marble." << std::endl;
199 save_image(image,width,height,"07_marble_texture.ppm");
200 std::cout << "Save Marble." << std::endl;
201 // Wood Texture
202 generate_wood(image,width,height,noise);
203 std::cout << "Generated Wood." << std::endl;
204 save_image(image,width,height,"07_wood_texture.ppm");
205 std::cout << "Save Wood." << std::endl;
206
207 return 0;
208 }
14 Appendix A: Source Code Listings 79

08_light_and_color.cpp - 15132 bytes.


1 // Compile: clang++ -std=c++17 08_light_and_color.cpp -o 08_light_and_color
2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <algorithm>
8
9 bool startsWithCaseInsensitive(std::string mainStr, std::string toMatch)
10 {
11 // Convert mainStr to lower case
12 std::transform(mainStr.begin(), mainStr.end(), mainStr.begin(), ::tolower);
13 // Convert toMatch to lower case
14 std::transform(toMatch.begin(), toMatch.end(), toMatch.begin(), ::tolower);
15 if(mainStr.find(toMatch) == 0)
16 return true;
17 else
18 return false;
19 }
20
21 int get_index(int x, int y, int width)
22 {
23 return x+width*y;
24 }
25
26 int calc_size(int width, int height)
27 {
28 return width*height;
29 }
30
31 std::tuple<int,int> get_width_and_height(const std::string str)
32 {
33 size_t start;
34 size_t end = 0;
35 std::vector<std::string> out;
36
37 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
38 {
39 end = str.find(' ', start);
40 out.push_back(str.substr(start, end - start));
41 }
42
14 Appendix A: Source Code Listings 80

43 int w=stoi(out[0]);
44 int h=stoi(out[1]);
45
46 return std::make_tuple(w,h);
47 }
48
49 std::tuple<int,int,int> get_color(const std::string str)
50 {
51 size_t start;
52 size_t end = 0;
53 std::vector<std::string> out;
54
55 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
56 {
57 end = str.find(' ', start);
58 out.push_back(str.substr(start, end - start));
59 }
60
61 int r=stoi(out[0]);
62 int g=stoi(out[1]);
63 int b=stoi(out[2]);
64
65 return std::make_tuple(r,g,b);
66 }
67
68 void read_image(std::vector<std::tuple<float, float, float>> &image, int &width, int\
69 &height, std::string filename)
70 {
71 std::ifstream infile(filename);
72 std::tuple<int, int, int> rcolor;
73 std::tuple<float, float, float> wcolor;
74 std::tuple<int,int> widthnheight;
75 std::string line;
76 int state=0;
77 bool done = false;
78
79 while (getline(infile, line))
80 {
81 if (startsWithCaseInsensitive(line,"P3") && state == 0) {
82 state=1;
83 }
84
85 if (!startsWithCaseInsensitive(line,"#") && !startsWithCaseInsensitive(line,"P3") \
14 Appendix A: Source Code Listings 81

86 && state == 1) {
87 widthnheight=get_width_and_height(line);
88 width=std::get<0>(widthnheight);
89 height=std::get<1>(widthnheight);
90 state=2;
91 }
92
93 if (startsWithCaseInsensitive(line,"255") && state == 2) {
94 state=3;
95 }
96
97 if (!(line.compare("255") == 0) && state == 3) {
98 rcolor=get_color(line);
99 wcolor=std::make_tuple(float(std::get<0>(rcolor)/255.0f), float(std::get<1>(
100 r)/255.0f), float(std::get<2>(rcolor)/255.0f));
101 image.push_back(wcolor);
102 done = true;
103 }
104 }
105 infile.close();
106 }
107
108 void negative_image(std::vector<std::tuple<float, float, float>> &image, int width, \
109 int height)
110 {
111 std::tuple<float, float, float> oldColor=std::make_tuple(0.0f,0.0f,0.0f);
112 for (int y=0;y<height;++y) {
113 for (int x=0;x<width;++x) {
114 oldColor=image[get_index(x,y,width)];
115 image[get_index(x,y,width)]=std::make_tuple(1.0f-std::get<0>(oldColor), 1.0f
116 :get<1>(oldColor), 1.0f-std::get<2>(oldColor));
117 }
118 }
119 }
120
121 void double_as_dark(std::vector<std::tuple<float, float, float>> &image, int width, \
122 int height)
123 {
124 std::tuple<float, float, float> oldColor=std::make_tuple(0.0f,0.0f,0.0f);
125 for (int y=0;y<height;++y) {
126 for (int x=0;x<width;++x) {
127 oldColor=image[get_index(x,y,width)];
128 image[get_index(x,y,width)]=std::make_tuple(std::get<0>(oldColor) / 2.0f, st
14 Appendix A: Source Code Listings 82

129 t<1>(oldColor) / 2.0f, std::get<2>(oldColor) / 2.0f);


130 }
131 }
132 }
133
134 void onefive_as_dark(std::vector<std::tuple<float, float, float>> &image, int width,\
135 int height)
136 {
137 std::tuple<float, float, float> oldColor=std::make_tuple(0.0f,0.0f,0.0f);
138 for (int y=0;y<height;++y) {
139 for (int x=0;x<width;++x) {
140 oldColor=image[get_index(x,y,width)];
141 image[get_index(x,y,width)]=std::make_tuple(std::get<0>(oldColor) / 1.5f, st
142 t<1>(oldColor) / 1.5f, std::get<2>(oldColor) / 1.5f);
143 }
144 }
145 }
146
147 void twice_as_bright(std::vector<std::tuple<float, float, float>> &image, int width,\
148 int height)
149 {
150 std::tuple<float, float, float> oldColor=std::make_tuple(0.0f,0.0f,0.0f);
151 float r=0.0; float g=0.0; float b=0.0;
152 for (int y=0;y<height;++y) {
153 for (int x=0;x<width;++x) {
154 oldColor=image[get_index(x,y,width)];
155 r=std::get<0>(oldColor) * 2.0f; g=std::get<1>(oldColor) * 2.0f; b=std::get<2
156 Color) * 2.0f;
157 if (r > 1.0) {r=1.0f;} if (g > 1.0) {g=1.0f;} if (b > 1.0) {b=1.0f;}
158 image[get_index(x,y,width)]=std::make_tuple(r, g, b);
159 }
160 }
161 }
162
163 void add_for_brighter(std::vector<std::tuple<float, float, float>> &image, int width\
164 , int height)
165 {
166 std::tuple<float, float, float> oldColor=std::make_tuple(0.0f,0.0f,0.0f);
167 float r=0.0; float g=0.0; float b=0.0;
168 for (int y=0;y<height;++y) {
169 for (int x=0;x<width;++x) {
170 oldColor=image[get_index(x,y,width)];
171 r=std::get<0>(oldColor) + 0.2f; g=std::get<1>(oldColor) + 0.2f; b=std::get<2
14 Appendix A: Source Code Listings 83

172 Color) + 0.2f;


173 if (r > 1.0) {r=1.0f;} if (g > 1.0) {g=1.0f;} if (b > 1.0) {b=1.0f;}
174 image[get_index(x,y,width)]=std::make_tuple(r, g, b);
175 }
176 }
177 }
178
179 void sub_for_darker(std::vector<std::tuple<float, float, float>> &image, int width, \
180 int height)
181 {
182 std::tuple<float, float, float> oldColor=std::make_tuple(0.0f,0.0f,0.0f);
183 float r=0.0; float g=0.0; float b=0.0;
184 for (int y=0;y<height;++y) {
185 for (int x=0;x<width;++x) {
186 oldColor=image[get_index(x,y,width)];
187 r=std::get<0>(oldColor) - 0.2f; g=std::get<1>(oldColor) - 0.2f; b=std::get<2
188 Color) - 0.2f;
189 if (r < 0.0) {r=0.0f;} if (g < 0.0) {g=0.0f;} if (b < 0.0) {b=0.0f;}
190 image[get_index(x,y,width)]=std::make_tuple(r, g, b);
191 }
192 }
193 }
194
195 void greyscale_image(std::vector<std::tuple<float, float, float>> &image, int width,\
196 int height)
197 {
198 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.0f);
199 float c=0.0;
200 for (int y=0;y<height;++y) {
201 for (int x=0;x<width;++x) {
202 color=image[get_index(x,y,width)];
203 c=(0.2126 * std::get<0>(color))+(0.7152 * std::get<1>(color))+(0.0722 * std:
204 2>(color));
205 if (c > 1.0) {c=1.0f;}
206 image[get_index(x,y,width)]=std::make_tuple(c, c, c);
207 }
208 }
209 }
210
211 void zero_gb_image(std::vector<std::tuple<float, float, float>> &image, int width, i\
212 nt height)
213 {
214 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.0f);
14 Appendix A: Source Code Listings 84

215 for (int y=0;y<height;++y) {


216 for (int x=0;x<width;++x) {
217 color=image[get_index(x,y,width)];
218 image[get_index(x,y,width)]=std::make_tuple(0.0f, std::get<1>(color), std::g
219 (color));
220 }
221 }
222 }
223
224 void r_zero_b_image(std::vector<std::tuple<float, float, float>> &image, int width, \
225 int height)
226 {
227 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.0f);
228 for (int y=0;y<height;++y) {
229 for (int x=0;x<width;++x) {
230 color=image[get_index(x,y,width)];
231 image[get_index(x,y,width)]=std::make_tuple(std::get<0>(color), 0.0f, std::g
232 (color));
233 }
234 }
235 }
236
237 void rg_zero_image(std::vector<std::tuple<float, float, float>> &image, int width, i\
238 nt height)
239 {
240 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.0f);
241 for (int y=0;y<height;++y) {
242 for (int x=0;x<width;++x) {
243 color=image[get_index(x,y,width)];
244 image[get_index(x,y,width)]=std::make_tuple(std::get<0>(color), std::get<1>(
245 ), 0.0f);
246 }
247 }
248 }
249
250 void grb_image(std::vector<std::tuple<float, float, float>> &image, int width, int h\
251 eight)
252 {
253 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.0f);
254 for (int y=0;y<height;++y) {
255 for (int x=0;x<width;++x) {
256 color=image[get_index(x,y,width)];
257 image[get_index(x,y,width)]=std::make_tuple(std::get<1>(color), std::get<0>(
14 Appendix A: Source Code Listings 85

258 ), std::get<2>(color));
259 }
260 }
261 }
262
263 void bgr_image(std::vector<std::tuple<float, float, float>> &image, int width, int h\
264 eight)
265 {
266 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.0f);
267 for (int y=0;y<height;++y) {
268 for (int x=0;x<width;++x) {
269 color=image[get_index(x,y,width)];
270 image[get_index(x,y,width)]=std::make_tuple(std::get<2>(color), std::get<1>(
271 ), std::get<0>(color));
272 }
273 }
274 }
275
276 void rrb_image(std::vector<std::tuple<float, float, float>> &image, int width, int h\
277 eight)
278 {
279 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.0f);
280 for (int y=0;y<height;++y) {
281 for (int x=0;x<width;++x) {
282 color=image[get_index(x,y,width)];
283 image[get_index(x,y,width)]=std::make_tuple(std::get<0>(color), std::get<0>(
284 ), std::get<2>(color));
285 }
286 }
287 }
288
289 void blended_two_images(std::vector<std::tuple<float, float, float>> &blend1,std::ve\
290 ctor<std::tuple<float, float, float>> &blend2,int width,int height,float alpha)
291 {
292 std::tuple<float, float, float> color1=std::make_tuple(0.0f,0.0f,0.0f);
293 std::tuple<float, float, float> color2=std::make_tuple(0.0f,0.0f,0.0f);
294 float r=0.0f; float g=0.0f; float b=0.0f;
295
296 for (int y=0;y<height;++y) {
297 for (int x=0;x<width;++x) {
298 color1=blend1[get_index(x,y,width)];
299 color2=blend2[get_index(x,y,width)];
300 r = (std::get<0>(color2) * alpha) + (std::get<0>(color1) * (1.0f - alpha));
14 Appendix A: Source Code Listings 86

301 g = (std::get<1>(color2) * alpha) + (std::get<1>(color1) * (1.0f - alpha));


302 b = (std::get<2>(color2) * alpha) + (std::get<2>(color1) * (1.0f - alpha));
303 blend1[get_index(x,y,width)]=std::make_tuple(r, g, b);
304 }
305 }
306 }
307
308 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
309 height, std::string filename)
310 {
311 std::tuple<float, float, float> color;
312 std::ofstream out(filename, std::ofstream::out);
313 out << "P3\n" << width << " " << height << "\n255\n";
314 for (int i=0;i<(width*height);++i)
315 {
316 color=image[i];
317 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
318 " " << int(std::get<2>(color)*255.0f) << '\n';
319 }
320 out.close();
321 }
322
323 int main()
324 {
325 std::vector<std::tuple<float, float, float>> image;
326 int width=0;
327 int height=0;
328
329 // Negative Colors.
330 std::cout << "Loading: '04_helloworld.ppm'." << std::endl;
331 read_image(image, width, height, "04_helloworld.ppm");
332 std::cout << "Making a negative color image." << std::endl;
333 negative_image(image,width,height);
334 std::cout << "Saving: '08_negative_image.ppm'." << std::endl;
335 save_image(image,width,height,"08_negative_image.ppm");
336
337 // Double as dark.
338 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
339 image.clear();
340 read_image(image, width, height, "04_helloworld.ppm");
341 std::cout << "Making a double as dark image." << std::endl;
342 double_as_dark(image,width,height);
343 std::cout << "Saving: '08_double_as_dark.ppm'." << std::endl;
14 Appendix A: Source Code Listings 87

344 save_image(image,width,height,"08_double_as_dark.ppm");
345
346 // OneFive times as dark.
347 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
348 image.clear();
349 read_image(image, width, height, "04_helloworld.ppm");
350 std::cout << "Making a 1.5 times as dark image." << std::endl;
351 onefive_as_dark(image,width,height);
352 std::cout << "Saving: '08_onefive_as_dark.ppm'." << std::endl;
353 save_image(image,width,height,"08_onefive_as_dark.ppm");
354
355 // Twice as bright.
356 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
357 image.clear();
358 read_image(image, width, height, "04_helloworld.ppm");
359 std::cout << "Twice as bright image." << std::endl;
360 twice_as_bright(image,width,height);
361 std::cout << "Saving: '08_twice_as_bright.ppm'." << std::endl;
362 save_image(image,width,height,"08_twice_as_bright.ppm");
363
364 // Add for brighter.
365 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
366 image.clear();
367 read_image(image, width, height, "04_helloworld.ppm");
368 std::cout << "Add for brighter image." << std::endl;
369 add_for_brighter(image,width,height);
370 std::cout << "Saving: '08_add_for_brighter.ppm'." << std::endl;
371 save_image(image,width,height,"08_add_for_brighter.ppm");
372
373 // Sub for darker.
374 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
375 image.clear();
376 read_image(image, width, height, "04_helloworld.ppm");
377 std::cout << "Sub for darker image." << std::endl;
378 sub_for_darker(image,width,height);
379 std::cout << "Saving: '08_sub_for_darker.ppm'." << std::endl;
380 save_image(image,width,height,"08_sub_for_darker.ppm");
381
382 // Greyscale image.
383 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
384 image.clear();
385 read_image(image, width, height, "04_helloworld.ppm");
386 std::cout << "Greyscale image." << std::endl;
14 Appendix A: Source Code Listings 88

387 greyscale_image(image,width,height);
388 std::cout << "Saving: '08_greyscale_image.ppm'." << std::endl;
389 save_image(image,width,height,"08_greyscale_image.ppm");
390
391 // Swapping and removing color channels.
392 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
393 image.clear();
394 read_image(image, width, height, "04_helloworld.ppm");
395 std::cout << "Swapping and removing color channels." << std::endl;
396 zero_gb_image(image,width,height);
397 std::cout << "Saving: '08_zero_gb_image.ppm'." << std::endl;
398 save_image(image,width,height,"08_zero_gb_image.ppm");
399 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
400 image.clear();
401 read_image(image, width, height, "04_helloworld.ppm");
402 std::cout << "Swapping and removing color channels." << std::endl;
403 r_zero_b_image(image,width,height);
404 std::cout << "Saving: '08_r_zero_b_image.ppm'." << std::endl;
405 save_image(image,width,height,"08_r_zero_b_image.ppm");
406 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
407 image.clear();
408 read_image(image, width, height, "04_helloworld.ppm");
409 std::cout << "Swapping and removing color channels." << std::endl;
410 rg_zero_image(image,width,height);
411 std::cout << "Saving: '08_rg_zero_image.ppm'." << std::endl;
412 save_image(image,width,height,"08_rg_zero_image.ppm");
413 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
414 image.clear();
415 read_image(image, width, height, "04_helloworld.ppm");
416 std::cout << "Swapping and removing color channels." << std::endl;
417 grb_image(image,width,height);
418 std::cout << "Saving: '08_grb_image.ppm'." << std::endl;
419 save_image(image,width,height,"08_grb_image.ppm");
420 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
421 image.clear();
422 read_image(image, width, height, "04_helloworld.ppm");
423 std::cout << "Swapping and removing color channels." << std::endl;
424 bgr_image(image,width,height);
425 std::cout << "Saving: '08_bgr_image.ppm'." << std::endl;
426 save_image(image,width,height,"08_bgr_image.ppm");
427 std::cout << "Reverting to: '04_helloworld.ppm'." << std::endl;
428 image.clear();
429 read_image(image, width, height, "04_helloworld.ppm");
14 Appendix A: Source Code Listings 89

430 std::cout << "Swapping and removing color channels." << std::endl;
431 rrb_image(image,width,height);
432 std::cout << "Saving: '08_rrb_image.ppm'." << std::endl << std::endl;
433 save_image(image,width,height,"08_rrb_image.ppm");
434
435 // Blend colors
436 std::vector<std::tuple<float, float, float>> blend1;
437 std::vector<std::tuple<float, float, float>> blend2;
438 read_image(blend1, width, height, "06_xor_texture.ppm");
439 read_image(blend2, width, height, "04_helloworld_square.ppm");
440 std::cout << "Blended two images." << std::endl;
441 blended_two_images(blend1,blend2,width,height,0.5);
442 std::cout << "Saving: '08_blended_two_images.ppm'." << std::endl << std::endl;
443 save_image(blend1,width,height,"08_blended_two_images.ppm");
444 blend1.clear(); blend2.clear();
445 read_image(blend1, width, height, "05_randomwalker.ppm");
446 read_image(blend2, width, height, "04_helloworld.ppm");
447 std::cout << "Blended two images2." << std::endl;
448 blended_two_images(blend1,blend2,width,height,0.2);
449 std::cout << "Saving: '08_blended_two_images2.ppm'." << std::endl << std::endl;
450 save_image(blend1,width,height,"08_blended_two_images2.ppm");
451
452 return 0;
453 }

09_lines.cpp - 7290 bytes.

1 // Compile: clang++ -std=c++17 09_lines.cpp -o 09_lines


2 #define _USE_MATH_DEFINES
3
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10
11 int get_index(int x, int y, int width)
12 {
13 return x+width*y;
14 }
15
16 int calc_size(int width, int height)
14 Appendix A: Source Code Listings 90

17 {
18 return width*height;
19 }
20
21 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
22 height)
23 {
24 for (int y=0;y<height;++y) {
25 for (int x=0;x<width;++x) {
26 image[get_index(x,y,width)]=std::make_tuple(1.0f, 1.0f, 1.0f);
27 }
28 }
29 }
30
31 std::tuple<float, float, float> h_to_rgb(float h)
32 {
33 float r=0.0f; float g=0.0f; float b=0.0f; float H=0.0f; float s=0.9f; float v=1.0f;
34 float f=0.0f; float p=0.0f; float q=0.0f; float t=0.0f;
35 int i=0;
36
37 H=h*360;
38
39 if (H == 360)
40 H = 0;
41 else
42 H = H / 60;
43
44 i = (int)std::trunc(H);
45 f = H - i;
46
47 p = v * (1.0 - s);
48 q = v * (1.0 - (s * f));
49 t = v * (1.0 - (s * (1.0 - f)));
50
51 switch (i)
52 {
53 case 0:
54 r = v;
55 g = t;
56 b = p;
57 break;
58 case 1:
59 r = q;
14 Appendix A: Source Code Listings 91

60 g = v;
61 b = p;
62 break;
63 case 2:
64 r = p;
65 g = v;
66 b = t;
67 break;
68 case 3:
69 r = p;
70 g = q;
71 b = v;
72 break;
73 case 4:
74 r = t;
75 g = p;
76 b = v;
77 break;
78 default:
79 r = v;
80 g = p;
81 b = q;
82 break;
83 }
84
85 return std::make_tuple(r,g,b);
86 }
87
88 void draw_line(std::vector<std::tuple<float, float, float>> &image, std::tuple<int, \
89 int, int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
90 {
91 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
92 int y2=std::get<3>(coords);
93 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
94 dx = x2 - x1; dy = y2 - y1;
95 if (((x1 >= 0) && (x1 < width)) && ((x2 >= 0) && (x2 < width)) && ((y1 >= 0) && (y1\
96 < height)) && ((y2 >= 0) && (y2 < height))) {
97 if (dx == 0)
98 {
99 if (y2 < y1) std::swap(y1, y2);
100 for (y = y1; y <= y2; y++)
101 image[get_index(x1,y,width)]=color;
102 return;
14 Appendix A: Source Code Listings 92

103 }
104 if (dy == 0)
105 {
106 if (x2 < x1) std::swap(x1, x2);
107 for (x = x1; x <= x2; x++)
108 image[get_index(x,y1,width)]=color;
109 return;
110 }
111 dx1 = abs(dx); dy1 = abs(dy);
112 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
113 if (dy1 <= dx1)
114 {
115 if (dx >= 0)
116 {
117 x = x1; y = y1; xe = x2;
118 }
119 else
120 {
121 x = x2; y = y2; xe = x1;
122 }
123 image[get_index(x,y,width)]=color;
124 for (i = 0; x<xe; i++)
125 {
126 x = x + 1;
127 if (px<0)
128 px = px + 2 * dy1;
129 else
130 {
131 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
132 px = px + 2 * (dy1 - dx1);
133 }
134 image[get_index(x,y,width)]=color;
135 }
136 }
137 else
138 {
139 if (dy >= 0)
140 {
141 x = x1; y = y1; ye = y2;
142 }
143 else
144 {
145 x = x2; y = y2; ye = y1;
14 Appendix A: Source Code Listings 93

146 }
147 image[get_index(x,y,width)]=color;
148 for (i = 0; y<ye; i++)
149 {
150 y = y + 1;
151 if (py <= 0)
152 py = py + 2 * dx1;
153 else
154 {
155 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
156 py = py + 2 * (dx1 - dy1);
157 }
158 image[get_index(x,y,width)]=color;
159 }
160 }
161 }
162 }
163
164 int find_region(int x, int y, int width, int height)
165 {
166 int code=0;
167 if(y >= height)
168 code |= 1; //top
169 else if(y < 0)
170 code |= 2; //bottom
171 if(x >= width)
172 code |= 4; //right
173 else if (x < 0)
174 code |= 8; //left
175 return(code);
176 }
177
178 bool clip_line(std::tuple<int, int, int, int> &coords1, std::tuple<int, int, int, in\
179 t> &coords2, int width, int height)
180 {
181 int x1=std::get<0>(coords1); int y1=std::get<1>(coords1); int x2=std::get<2>(coords\
182 1); int y2=std::get<3>(coords1);
183 int x3=0; int y3=0; int x4=0; int y4=0;
184 int code1=0, code2=0, codeout=0;
185 bool accept = 0, done=0;
186 code1 = find_region(x1, y1, width, height); //the region outcodes for the endpoints
187 code2 = find_region(x2, y2, width, height);
188 do //In theory, this can never end up in an infinite loop, it'll always come in one\
14 Appendix A: Source Code Listings 94

189 of the trivial cases eventually


190 {
191 if(!(code1 | code2)) accept = done = 1; //accept because both endpoints are in sc\
192 reen or on the border, trivial accept
193 else if(code1 & code2) done = 1; //the line isn't visible on screen, trivial reject
194 else //if no trivial reject or accept, continue the loop
195 {
196 int x, y;
197 codeout = code1 ? code1 : code2;
198 if(codeout & 1) //top
199 {
200 x = x1 + (x2 - x1) * (height - y1) / (y2 - y1);
201 y = height - 1;
202 }
203 else if(codeout & 2) //bottom
204 {
205 x = x1 + (x2 - x1) * -y1 / (y2 - y1);
206 y = 0;
207 }
208 else if(codeout & 4) //right
209 {
210 y = y1 + (y2 - y1) * (width - x1) / (x2 - x1);
211 x = width - 1;
212 }
213 else //left
214 {
215 y = y1 + (y2 - y1) * -x1 / (x2 - x1);
216 x = 0;
217 }
218 if(codeout == code1) //first endpoint was clipped
219 {
220 x1 = x; y1 = y;
221 code1 = find_region(x1, y1, width, height);
222 }
223 else //second endpoint was clipped
224 {
225 x2 = x; y2 = y;
226 code2 = find_region(x2, y2, width, height);
227 }
228 }
229 }
230 while(done == 0);
231 if(accept)
14 Appendix A: Source Code Listings 95

232 {
233 x3 = x1;
234 x4 = x2;
235 y3 = y1;
236 y4 = y2;
237 coords2=std::make_tuple(x3,y3,x4,y4);
238 return 1;
239 }
240 else
241 {
242 x3 = x4 = y3 = y4 = 0;
243 coords2=std::make_tuple(x3,y3,x4,y4);
244 return 0;
245 }
246 }
247
248 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
249 height, std::string filename)
250 {
251 std::tuple<float, float, float> color;
252 std::ofstream out(filename, std::ofstream::out);
253 out << "P3\n" << width << " " << height << "\n255\n";
254 for (int i=0;i<(width*height);++i)
255 {
256 color=image[i];
257 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
258 " " << int(std::get<2>(color)*255.0f) << '\n';
259 }
260 out.close();
261 }
262
263 int main()
264 {
265 // Draw random lines (with line clipping).
266 std::vector<std::tuple<float, float, float>> image;
267
268 std::random_device rd;
269 std::mt19937 mt(rd());
270
271 std::uniform_int_distribution<> dist1(-100,740);
272 std::uniform_int_distribution<> dist2(-100,460);
273 std::uniform_real_distribution<float> dist3(0.0, 1.0);
274
14 Appendix A: Source Code Listings 96

275 std::tuple<float,float,float> color;


276 std::tuple<int, int, int, int> coords1;
277 std::tuple<int, int, int, int> coords2;
278
279 int width=640;
280 int height=360;
281 int x1=0,y1=0,x2=0,y2=0;
282 float h=0.0f;
283
284 image.resize(calc_size(width, height));
285 clear_image(image,width,height);
286
287 for (int i=0;i<15000;++i)
288 {
289 x1=dist1(mt);
290 y1=dist2(mt);
291 x2=dist1(mt);
292 y2=dist2(mt);
293 coords1=std::make_tuple(x1,y1,x2,y2);
294 h=dist3(mt);
295 color=h_to_rgb(h);
296 if (clip_line(coords1,coords2,width,height)) {
297 draw_line(image,coords2,color,width,height);
298 }
299 }
300
301 save_image(image,width,height,"09_random_lines.ppm");
302
303 // Draw damped sine.
304 image.clear();
305 width=1920;height=640;
306 image.resize(calc_size(width, height));
307 clear_image(image,width,height);
308
309 double numb_of_samples=1920.0;
310 int y=0; int ox=0; int oy=0;
311
312 std::tuple<float,float,float> black=std::make_tuple(0.0,0.0,0.0);
313 std::tuple<float,float,float> grey=std::make_tuple(0.5,0.5,0.5);
314 std::tuple<float,float,float> red=std::make_tuple(1.0,0.0,0.0);
315
316 coords1=std::make_tuple(0,height/2,width,height/2);
317 draw_line(image,coords1,red,width,height);
14 Appendix A: Source Code Listings 97

318
319 for (int x=0;x<width;++x) {
320 y=639-(319.0-(339.0*pow(1.0-(1.0/339.0),x))*sin(2*M_PI*x*(15.0/numb_of_samples)-1.\
321 0)+0);
322 if (x == 0) {ox=x;oy=y;}
323 coords1=std::make_tuple(x,y,ox,oy);
324 draw_line(image,coords1,black,width,height);
325 ox=x;oy=y;
326 }
327
328 for (int x=0;x<width;++x) {
329 y=319.0-(339.0*pow(1.0-(1.0/339.0),x));
330 if (x == 0) {ox=x;oy=y;}
331 coords1=std::make_tuple(x,y,ox,oy);
332 draw_line(image,coords1,grey,width,height);
333 ox=x;oy=y;
334 }
335
336 save_image(image,width,height,"09_damped_sine.ppm");
337
338 return 0;
339 }

09_angle_lines.cpp - 6576 bytes.

1 // Compile: clang++ -std=c++17 09_angle_lines.cpp -o 09_angle_lines


2 #define _USE_MATH_DEFINES
3
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10
11 int get_index(int x, int y, int width)
12 {
13 return x+width*y;
14 }
15
16 int calc_size(int width, int height)
17 {
18 return width*height;
14 Appendix A: Source Code Listings 98

19 }
20
21 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
22 height)
23 {
24 for (int y=0;y<height;++y) {
25 for (int x=0;x<width;++x) {
26 image[get_index(x,y,width)]=std::make_tuple(1.0f, 1.0f, 1.0f);
27 }
28 }
29 }
30
31 void draw_line(std::vector<std::tuple<float, float, float>> &image, std::tuple<int, \
32 int, int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
33 {
34 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
35 int y2=std::get<3>(coords);
36 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
37 dx = x2 - x1; dy = y2 - y1;
38 if (dx == 0)
39 {
40 if (y2 < y1) std::swap(y1, y2);
41 for (y = y1; y <= y2; y++)
42 image[get_index(x1,y,width)]=color;
43 return;
44 }
45 if (dy == 0)
46 {
47 if (x2 < x1) std::swap(x1, x2);
48 for (x = x1; x <= x2; x++)
49 image[get_index(x,y1,width)]=color;
50 return;
51 }
52 dx1 = abs(dx); dy1 = abs(dy);
53 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
54 if (dy1 <= dx1)
55 {
56 if (dx >= 0)
57 {
58 x = x1; y = y1; xe = x2;
59 }
60 else
61 {
14 Appendix A: Source Code Listings 99

62 x = x2; y = y2; xe = x1;


63 }
64 image[get_index(x,y,width)]=color;
65 for (i = 0; x<xe; i++)
66 {
67 x = x + 1;
68 if (px<0)
69 px = px + 2 * dy1;
70 else
71 {
72 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
73 px = px + 2 * (dy1 - dx1);
74 }
75 image[get_index(x,y,width)]=color;
76 }
77 }
78 else
79 {
80 if (dy >= 0)
81 {
82 x = x1; y = y1; ye = y2;
83 }
84 else
85 {
86 x = x2; y = y2; ye = y1;
87 }
88 image[get_index(x,y,width)]=color;
89 for (i = 0; y<ye; i++)
90 {
91 y = y + 1;
92 if (py <= 0)
93 py = py + 2 * dx1;
94 else
95 {
96 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
97 py = py + 2 * (dx1 - dy1);
98 }
99 image[get_index(x,y,width)]=color;
100 }
101 }
102 }
103
104 int find_region(int x, int y, int width, int height)
14 Appendix A: Source Code Listings 100

105 {
106 int code=0;
107 if(y >= height)
108 code |= 1; //top
109 else if(y < 0)
110 code |= 2; //bottom
111 if(x >= width)
112 code |= 4; //right
113 else if (x < 0)
114 code |= 8; //left
115 return(code);
116 }
117
118 bool clip_line(std::tuple<int, int, int, int> &coords1, std::tuple<int, int, int, in\
119 t> &coords2, int width, int height)
120 {
121 int x1=std::get<0>(coords1); int y1=std::get<1>(coords1); int x2=std::get<2>(coords\
122 1); int y2=std::get<3>(coords1);
123 int x3=0; int y3=0; int x4=0; int y4=0;
124 int code1=0, code2=0, codeout=0;
125 bool accept = 0, done=0;
126 code1 = find_region(x1, y1, width, height); //the region outcodes for the endpoints
127 code2 = find_region(x2, y2, width, height);
128 do //In theory, this can never end up in an infinite loop, it'll always come in one\
129 of the trivial cases eventually
130 {
131 if(!(code1 | code2)) accept = done = 1; //accept because both endpoints are in sc\
132 reen or on the border, trivial accept
133 else if(code1 & code2) done = 1; //the line isn't visible on screen, trivial reject
134 else //if no trivial reject or accept, continue the loop
135 {
136 int x, y;
137 codeout = code1 ? code1 : code2;
138 if(codeout & 1) //top
139 {
140 x = x1 + (x2 - x1) * (height - y1) / (y2 - y1);
141 y = height - 1;
142 }
143 else if(codeout & 2) //bottom
144 {
145 x = x1 + (x2 - x1) * -y1 / (y2 - y1);
146 y = 0;
147 }
14 Appendix A: Source Code Listings 101

148 else if(codeout & 4) //right


149 {
150 y = y1 + (y2 - y1) * (width - x1) / (x2 - x1);
151 x = width - 1;
152 }
153 else //left
154 {
155 y = y1 + (y2 - y1) * -x1 / (x2 - x1);
156 x = 0;
157 }
158 if(codeout == code1) //first endpoint was clipped
159 {
160 x1 = x; y1 = y;
161 code1 = find_region(x1, y1, width, height);
162 }
163 else //second endpoint was clipped
164 {
165 x2 = x; y2 = y;
166 code2 = find_region(x2, y2, width, height);
167 }
168 }
169 }
170 while(done == 0);
171 if(accept)
172 {
173 x3 = x1;
174 x4 = x2;
175 y3 = y1;
176 y4 = y2;
177 coords2=std::make_tuple(x3,y3,x4,y4);
178 return 1;
179 }
180 else
181 {
182 x3 = x4 = y3 = y4 = 0;
183 coords2=std::make_tuple(x3,y3,x4,y4);
184 return 0;
185 }
186 }
187
188 void get_angle_line(std::tuple<int, int, int, int> &coords,int x_cen,int y_cen,doubl\
189 e degrees,int length)
190 {
14 Appendix A: Source Code Listings 102

191 double angle = degrees * (M_PI / 180);


192 coords=std::make_tuple(x_cen,y_cen,int(double(x_cen) + cos(angle)*double(length)),i\
193 nt(double(y_cen) + sin(angle)*double(length)));
194 }
195
196 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
197 height, std::string filename)
198 {
199 std::tuple<float, float, float> color;
200 std::ofstream out(filename, std::ofstream::out);
201 out << "P3\n" << width << " " << height << "\n255\n";
202 for (int i=0;i<(width*height);++i)
203 {
204 color=image[i];
205 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
206 " " << int(std::get<2>(color)*255.0f) << '\n';
207 }
208 out.close();
209 }
210
211 int main()
212 {
213 // Draw random lines (with line clipping).
214 std::vector<std::tuple<float, float, float>> image;
215
216
217 std::tuple<float,float,float> color=std::make_tuple(0.0,0.0,0.0);
218 std::tuple<int, int, int, int> coords;
219
220 int width=640;
221 int height=360;
222
223 image.resize(calc_size(width, height));
224 clear_image(image,width,height);
225
226 int x_cen=width/2;
227 int y_cen=height/2;
228 int length=y_cen*0.8;
229 double degrees=0.0;
230
231 get_angle_line(coords,x_cen,y_cen,degrees,length);
232 if (clip_line(coords,coords,width,height)) {
233 draw_line(image,coords,color,width,height);
14 Appendix A: Source Code Listings 103

234 }
235 degrees=45.0;
236 get_angle_line(coords,x_cen,y_cen,degrees,length);
237 if (clip_line(coords,coords,width,height)) {
238 draw_line(image,coords,color,width,height);
239 }
240 degrees=90.0;
241 get_angle_line(coords,x_cen,y_cen,degrees,length);
242 if (clip_line(coords,coords,width,height)) {
243 draw_line(image,coords,color,width,height);
244 }
245 degrees=135.0;
246 get_angle_line(coords,x_cen,y_cen,degrees,length);
247 if (clip_line(coords,coords,width,height)) {
248 draw_line(image,coords,color,width,height);
249 }
250 degrees=180.0;
251 get_angle_line(coords,x_cen,y_cen,degrees,length);
252 if (clip_line(coords,coords,width,height)) {
253 draw_line(image,coords,color,width,height);
254 }
255 degrees=225.0;
256 get_angle_line(coords,x_cen,y_cen,degrees,length);
257 if (clip_line(coords,coords,width,height)) {
258 draw_line(image,coords,color,width,height);
259 }
260 degrees=270.0;
261 get_angle_line(coords,x_cen,y_cen,degrees,length);
262 if (clip_line(coords,coords,width,height)) {
263 draw_line(image,coords,color,width,height);
264 }
265 degrees=315.0;
266 get_angle_line(coords,x_cen,y_cen,degrees,length);
267 if (clip_line(coords,coords,width,height)) {
268 draw_line(image,coords,color,width,height);
269 }
270
271 save_image(image,width,height,"09_angle_lines.ppm");
272
273 return 0;
274 }
14 Appendix A: Source Code Listings 104

10_curved_dots.cpp - 7387 bytes.


1 // Compile: clang++ -std=c++20 10_curved_dots.cpp -o 10_curved_dots
2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <random>
8 #include <cmath>
9
10 void linear_bezier_curves(std::tuple<int, int, int, int> &coords, int split, std::ve\
11 ctor<std::tuple<int,int>>& xy)
12 {
13 float t=0.0;
14 float delta=(float(1)/float(split));
15 int x=0;
16 int y=0;
17
18 for (int i=0;i<split;++i)
19 {
20 x = std::lerp(std::get<0>(coords),std::get<2>(coords),t);
21 y = std::lerp(std::get<1>(coords),std::get<3>(coords),t);
22 xy.push_back(std::make_tuple(x,y));
23 t+=delta;
24 }
25 }
26
27 void quadratic_bezier_curves(int px0, int py0, int px1, int py1, int px2, int py2, i\
28 nt split, std::vector<std::tuple<int,int>>& xy)
29 {
30 double t=0.0;
31 double delta=(double(1)/double(split));
32 int x=0;
33 int y=0;
34 int x1=0;
35 int y1=0;
36 int x2=0;
37 int y2=0;
38 for (int i=0;i<split;++i)
39 {
40 x1 = std::lerp(px0,px1,t);
41 y1 = std::lerp(py0,py1,t);
42 x2 = std::lerp(px1,px2,t);
14 Appendix A: Source Code Listings 105

43 y2 = std::lerp(py1,py2,t);
44 x = std::lerp(x1,x2,t);
45 y = std::lerp(y1,y2,t);
46 xy.push_back(std::make_tuple(x,y));
47 t+=delta;
48 }
49 }
50
51 void cubic_bezier_curves(int px0, int py0, int px1, int py1, int px2, int py2, int p\
52 x3, int py3, int split, std::vector<std::tuple<int,int>>& xy)
53 {
54 float t=0.0;
55 float delta=(float(1)/float(split));
56 int x=0;
57 int y=0;
58 int x1=0;
59 int y1=0;
60 int x2=0;
61 int y2=0;
62 int x3=0;
63 int y3=0;
64 int x4=0;
65 int y4=0;
66 int xx1=0;
67 int yy1=0;
68 int xx2=0;
69 int yy2=0;
70 for (int i=0;i<split;++i)
71 {
72 x1 = std::lerp(px0,px1,t);
73 y1 = std::lerp(py0,py1,t);
74 x2 = std::lerp(px1,px2,t);
75 y2 = std::lerp(py1,py2,t);
76
77 x3 = std::lerp(px1,px2,t);
78 y3 = std::lerp(py1,py2,t);
79 x4 = std::lerp(px2,px3,t);
80 y4 = std::lerp(py2,py3,t);
81
82 xx1 = std::lerp(x1,x2,t);
83 yy1 = std::lerp(y1,y2,t);
84 xx2 = std::lerp(x3,x4,t);
85 yy2 = std::lerp(y3,y4,t);
14 Appendix A: Source Code Listings 106

86
87 x = std::lerp(xx1,xx2,t);
88 y = std::lerp(yy1,yy2,t);
89 xy.push_back(std::make_tuple(x,y));
90 t+=delta;
91 }
92 }
93
94 int get_index(int x, int y, int width)
95 {
96 return x+width*y;
97 }
98
99 int calc_size(int width, int height)
100 {
101 return width*height;
102 }
103
104 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
105 height)
106 {
107 for (int y=0;y<height;++y) {
108 for (int x=0;x<width;++x) {
109 image[get_index(x,y,width)]=std::make_tuple(1.0f, 1.0f, 1.0f);
110 }
111 }
112 }
113
114 void draw_line(std::vector<std::tuple<float, float, float>> &image, std::tuple<int, \
115 int, int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
116 {
117 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
118 int y2=std::get<3>(coords);
119 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
120 dx = x2 - x1; dy = y2 - y1;
121 if (dx == 0)
122 {
123 if (y2 < y1) std::swap(y1, y2);
124 for (y = y1; y <= y2; y++)
125 image[get_index(x1,y,width)]=color;
126 return;
127 }
128 if (dy == 0)
14 Appendix A: Source Code Listings 107

129 {
130 if (x2 < x1) std::swap(x1, x2);
131 for (x = x1; x <= x2; x++)
132 image[get_index(x,y1,width)]=color;
133 return;
134 }
135 dx1 = abs(dx); dy1 = abs(dy);
136 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
137 if (dy1 <= dx1)
138 {
139 if (dx >= 0)
140 {
141 x = x1; y = y1; xe = x2;
142 }
143 else
144 {
145 x = x2; y = y2; xe = x1;
146 }
147 image[get_index(x,y,width)]=color;
148 for (i = 0; x<xe; i++)
149 {
150 x = x + 1;
151 if (px<0)
152 px = px + 2 * dy1;
153 else
154 {
155 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
156 px = px + 2 * (dy1 - dx1);
157 }
158 image[get_index(x,y,width)]=color;
159 }
160 }
161 else
162 {
163 if (dy >= 0)
164 {
165 x = x1; y = y1; ye = y2;
166 }
167 else
168 {
169 x = x2; y = y2; ye = y1;
170 }
171 image[get_index(x,y,width)]=color;
14 Appendix A: Source Code Listings 108

172 for (i = 0; y<ye; i++)


173 {
174 y = y + 1;
175 if (py <= 0)
176 py = py + 2 * dx1;
177 else
178 {
179 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
180 py = py + 2 * (dx1 - dy1);
181 }
182 image[get_index(x,y,width)]=color;
183 }
184 }
185 }
186
187 void draw_xy_dots(std::vector<std::tuple<float, float, float>> &image,std::tuple<flo\
188 at,float,float> &color,std::vector<std::tuple<int,int>>& xy,int width,int height)
189 {
190 for (auto& pt : xy)
191 {
192 image[get_index(std::get<0>(pt),std::get<1>(pt),width)]=color;
193 }
194 }
195
196 void draw_marker(int x, int y, std::vector<std::tuple<float, float, float>> &image, \
197 std::tuple<float,float,float> &color, int width, int height)
198 {
199 image[get_index(x-1,y-1,width)]=color;
200 image[get_index(x,y-1,width)]=color;
201 image[get_index(x+1,y-1,width)]=color;
202 image[get_index(x+1,y,width)]=color;
203 image[get_index(x+1,y+1,width)]=color;
204 image[get_index(x,y+1,width)]=color;
205 image[get_index(x-1,y+1,width)]=color;
206 image[get_index(x-1,y,width)]=color;
207
208 color=std::make_tuple(1.0f, 1.0f, 1.0f);
209 image[get_index(x,y,width)]=color;
210 }
211
212 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
213 height, std::string filename)
214 {
14 Appendix A: Source Code Listings 109

215 std::tuple<float, float, float> color;


216 std::ofstream out(filename, std::ofstream::out);
217 out << "P3\n" << width << " " << height << "\n255\n";
218 for (int i=0;i<(width*height);++i)
219 {
220 color=image[i];
221 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
222 " " << int(std::get<2>(color)*255.0f) << '\n';
223 }
224 out.close();
225 }
226
227 int main()
228 {
229 int width=640;
230 int height=360;
231 std::vector<std::tuple<float, float, float>> image;
232 std::tuple<float,float,float> color;
233
234 image.resize(calc_size(width, height));
235 clear_image(image,width,height);
236
237 std::vector<std::tuple<int,int>> xy;
238 std::tuple<int, int, int, int> coords;
239
240 // Draw dots in a line with Bezier.
241 color=std::make_tuple(0.9296875, 0.9296875, 0.9296875);
242 coords=std::make_tuple(20,90,300,90);
243 draw_line(image,coords,color,width,height);
244 linear_bezier_curves(coords,10,xy);
245 color=std::make_tuple(0.0, 0.0, 0.0);
246 draw_xy_dots(image,color,xy,width,height);
247 xy.clear();
248 color=std::make_tuple(0.0, 0.8784313725, 0.0);
249 draw_marker(20,90,image,color,width,height);
250 color=std::make_tuple(0.0, 0.8784313725, 0.0);
251 draw_marker(300,90,image,color,width,height);
252
253 // Draw dots in a curve 1.
254 color=std::make_tuple(0.9296875, 0.9296875, 0.9296875);
255 coords=std::make_tuple(340,90,480,2);
256 draw_line(image,coords,color,width,height);
257 coords=std::make_tuple(480,2,620,90);
14 Appendix A: Source Code Listings 110

258 draw_line(image,coords,color,width,height);
259 quadratic_bezier_curves(340,90,480,2,620,90,10,xy);
260 color=std::make_tuple(0.0, 0.0, 0.0);
261 draw_xy_dots(image,color,xy,width,height);
262 xy.clear();
263 color=std::make_tuple(0.0, 0.8784313725, 0.0);
264 draw_marker(340,90,image,color,width,height);
265 color=std::make_tuple(0.0, 0.8784313725, 0.0);
266 draw_marker(480,2,image,color,width,height);
267 color=std::make_tuple(0.0, 0.8784313725, 0.0);
268 draw_marker(620,90,image,color,width,height);
269
270 // Draw dots in a curve 2.
271 color=std::make_tuple(0.9296875, 0.9296875, 0.9296875);
272 coords=std::make_tuple(200,270,293,182);
273 draw_line(image,coords,color,width,height);
274 coords=std::make_tuple(386,357,480,270);
275 draw_line(image,coords,color,width,height);
276 cubic_bezier_curves(200,270,293,182,386,357,480,270,10,xy);
277 color=std::make_tuple(0.0, 0.0, 0.0);
278 draw_xy_dots(image,color,xy,width,height);
279 xy.clear();
280 color=std::make_tuple(0.0, 0.8784313725, 0.0);
281 draw_marker(200,270,image,color,width,height);
282 color=std::make_tuple(0.0, 0.8784313725, 0.0);
283 draw_marker(293,182,image,color,width,height);
284 color=std::make_tuple(0.0, 0.8784313725, 0.0);
285 draw_marker(386,357,image,color,width,height);
286 color=std::make_tuple(0.0, 0.8784313725, 0.0);
287 draw_marker(480,270,image,color,width,height);
288
289 save_image(image,width,height,"10_curved_dots.ppm");
290
291 return 0;
292 }
14 Appendix A: Source Code Listings 111

10_curved_lines.cpp - 8643 bytes.


1 // Compile: clang++ -std=c++20 10_curved_lines.cpp -o 10_curved_lines
2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <random>
8 #include <cmath>
9
10 void linear_bezier_curves(std::tuple<int, int, int, int> &coords, int split, std::ve\
11 ctor<std::tuple<int,int>>& xy)
12 {
13 float t=0.0;
14 float delta=(float(1)/float(split));
15 int x=0;
16 int y=0;
17
18 for (int i=0;i<split;++i)
19 {
20 x = std::lerp(std::get<0>(coords),std::get<2>(coords),t);
21 y = std::lerp(std::get<1>(coords),std::get<3>(coords),t);
22 xy.push_back(std::make_tuple(x,y));
23 t+=delta;
24 }
25 }
26
27 void quadratic_bezier_curves(int px0, int py0, int px1, int py1, int px2, int py2, i\
28 nt split, std::vector<std::tuple<int,int>>& xy)
29 {
30 double t=0.0;
31 double delta=(double(1)/double(split));
32 int x=0;
33 int y=0;
34 int x1=0;
35 int y1=0;
36 int x2=0;
37 int y2=0;
38 for (int i=0;i<split;++i)
39 {
40 x1 = std::lerp(px0,px1,t);
41 y1 = std::lerp(py0,py1,t);
42 x2 = std::lerp(px1,px2,t);
14 Appendix A: Source Code Listings 112

43 y2 = std::lerp(py1,py2,t);
44 x = std::lerp(x1,x2,t);
45 y = std::lerp(y1,y2,t);
46 xy.push_back(std::make_tuple(x,y));
47 t+=delta;
48 }
49 }
50
51 void cubic_bezier_curves(int px0, int py0, int px1, int py1, int px2, int py2, int p\
52 x3, int py3, int split, std::vector<std::tuple<int,int>>& xy)
53 {
54 float t=0.0;
55 float delta=(float(1)/float(split));
56 int x=0;
57 int y=0;
58 int x1=0;
59 int y1=0;
60 int x2=0;
61 int y2=0;
62 int x3=0;
63 int y3=0;
64 int x4=0;
65 int y4=0;
66 int xx1=0;
67 int yy1=0;
68 int xx2=0;
69 int yy2=0;
70 for (int i=0;i<split;++i)
71 {
72 x1 = std::lerp(px0,px1,t);
73 y1 = std::lerp(py0,py1,t);
74 x2 = std::lerp(px1,px2,t);
75 y2 = std::lerp(py1,py2,t);
76
77 x3 = std::lerp(px1,px2,t);
78 y3 = std::lerp(py1,py2,t);
79 x4 = std::lerp(px2,px3,t);
80 y4 = std::lerp(py2,py3,t);
81
82 xx1 = std::lerp(x1,x2,t);
83 yy1 = std::lerp(y1,y2,t);
84 xx2 = std::lerp(x3,x4,t);
85 yy2 = std::lerp(y3,y4,t);
14 Appendix A: Source Code Listings 113

86
87 x = std::lerp(xx1,xx2,t);
88 y = std::lerp(yy1,yy2,t);
89 xy.push_back(std::make_tuple(x,y));
90 t+=delta;
91 }
92 }
93
94 int get_index(int x, int y, int width)
95 {
96 return x+width*y;
97 }
98
99 int calc_size(int width, int height)
100 {
101 return width*height;
102 }
103
104 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
105 height)
106 {
107 for (int y=0;y<height;++y) {
108 for (int x=0;x<width;++x) {
109 image[get_index(x,y,width)]=std::make_tuple(1.0f, 1.0f, 1.0f);
110 }
111 }
112 }
113
114 void draw_line(std::vector<std::tuple<float, float, float>> &image, std::tuple<int, \
115 int, int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
116 {
117 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
118 int y2=std::get<3>(coords);
119 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
120 dx = x2 - x1; dy = y2 - y1;
121 if (dx == 0)
122 {
123 if (y2 < y1) std::swap(y1, y2);
124 for (y = y1; y <= y2; y++)
125 image[get_index(x1,y,width)]=color;
126 return;
127 }
128 if (dy == 0)
14 Appendix A: Source Code Listings 114

129 {
130 if (x2 < x1) std::swap(x1, x2);
131 for (x = x1; x <= x2; x++)
132 image[get_index(x,y1,width)]=color;
133 return;
134 }
135 dx1 = abs(dx); dy1 = abs(dy);
136 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
137 if (dy1 <= dx1)
138 {
139 if (dx >= 0)
140 {
141 x = x1; y = y1; xe = x2;
142 }
143 else
144 {
145 x = x2; y = y2; xe = x1;
146 }
147 image[get_index(x,y,width)]=color;
148 for (i = 0; x<xe; i++)
149 {
150 x = x + 1;
151 if (px<0)
152 px = px + 2 * dy1;
153 else
154 {
155 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
156 px = px + 2 * (dy1 - dx1);
157 }
158 image[get_index(x,y,width)]=color;
159 }
160 }
161 else
162 {
163 if (dy >= 0)
164 {
165 x = x1; y = y1; ye = y2;
166 }
167 else
168 {
169 x = x2; y = y2; ye = y1;
170 }
171 image[get_index(x,y,width)]=color;
14 Appendix A: Source Code Listings 115

172 for (i = 0; y<ye; i++)


173 {
174 y = y + 1;
175 if (py <= 0)
176 py = py + 2 * dx1;
177 else
178 {
179 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
180 py = py + 2 * (dx1 - dy1);
181 }
182 image[get_index(x,y,width)]=color;
183 }
184 }
185 }
186
187 void draw_xy_line(std::vector<std::tuple<float, float, float>> &image,std::tuple<flo\
188 at,float,float> &color,std::vector<std::tuple<int,int>>& xy,int width,int height,int
189 x_stop,int y_stop)
190 {
191 std::tuple<int, int> temp=xy[0];
192 std::tuple<int, int> store;
193 store=std::make_tuple(x_stop,y_stop);
194 xy.push_back(store);
195 std::vector<std::tuple<int,int,int,int>> xyxy;
196 for (int i=1;i<xy.size();++i)
197 {
198 store=xy[i];
199 xyxy.push_back(std::make_tuple(std::get<0>(temp),std::get<1>(temp),std::get<0>(sto\
200 re),std::get<1>(store)));
201 temp=xy[i];
202 }
203
204 for (auto& li : xyxy)
205 {
206 draw_line(image,li,color,width,height);
207 }
208 }
209
210 void draw_xy_dots(std::vector<std::tuple<float, float, float>> &image,std::tuple<flo\
211 at,float,float> &color,std::vector<std::tuple<int,int>>& xy,int width,int height)
212 {
213 for (auto& pt : xy)
214 {
14 Appendix A: Source Code Listings 116

215 image[get_index(std::get<0>(pt),std::get<1>(pt),width)]=color;
216 }
217 }
218
219 void draw_marker(int x, int y, std::vector<std::tuple<float, float, float>> &image, \
220 std::tuple<float,float,float> &color, int width, int height)
221 {
222 image[get_index(x-1,y-1,width)]=color;
223 image[get_index(x,y-1,width)]=color;
224 image[get_index(x+1,y-1,width)]=color;
225 image[get_index(x+1,y,width)]=color;
226 image[get_index(x+1,y+1,width)]=color;
227 image[get_index(x,y+1,width)]=color;
228 image[get_index(x-1,y+1,width)]=color;
229 image[get_index(x-1,y,width)]=color;
230
231 color=std::make_tuple(1.0f, 1.0f, 1.0f);
232 image[get_index(x,y,width)]=color;
233 }
234
235 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
236 height, std::string filename)
237 {
238 std::tuple<float, float, float> color;
239 std::ofstream out(filename, std::ofstream::out);
240 out << "P3\n" << width << " " << height << "\n255\n";
241 for (int i=0;i<(width*height);++i)
242 {
243 color=image[i];
244 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
245 " " << int(std::get<2>(color)*255.0f) << '\n';
246 }
247 out.close();
248 }
249
250 int main()
251 {
252 int width=640;
253 int height=360;
254 std::vector<std::tuple<float, float, float>> image;
255 std::tuple<float,float,float> color;
256
257 image.resize(calc_size(width, height));
14 Appendix A: Source Code Listings 117

258 clear_image(image,width,height);
259
260 std::vector<std::tuple<int,int>> xy;
261 std::tuple<int, int, int, int> coords;
262
263 // Draw a line with Bezier.
264 color=std::make_tuple(0.9296875, 0.9296875, 0.9296875);
265 coords=std::make_tuple(20,90,300,90);
266 draw_line(image,coords,color,width,height);
267 linear_bezier_curves(coords,40,xy);
268 color=std::make_tuple(0.7019607843, 0.2196078431, 0.6078431373);
269 draw_xy_line(image,color,xy,width,height,300,90);
270 xy.clear();
271 coords=std::make_tuple(20,90,300,90);
272 linear_bezier_curves(coords,10,xy);
273 color=std::make_tuple(0.8784313725, 0.8784313725, 0.0);
274 draw_xy_dots(image,color,xy,width,height);
275 xy.clear();
276 color=std::make_tuple(0.0, 0.8784313725, 0.0);
277 draw_marker(20,90,image,color,width,height);
278 color=std::make_tuple(0.0, 0.8784313725, 0.0);
279 draw_marker(300,90,image,color,width,height);
280
281 // Draw line as a curve 1.
282 color=std::make_tuple(0.9296875, 0.9296875, 0.9296875);
283 coords=std::make_tuple(340,90,480,2);
284 draw_line(image,coords,color,width,height);
285 coords=std::make_tuple(480,2,620,90);
286 draw_line(image,coords,color,width,height);
287 quadratic_bezier_curves(340,90,480,2,620,90,40,xy);
288 color=std::make_tuple(0.7019607843, 0.2196078431, 0.6078431373);
289 draw_xy_line(image,color,xy,width,height,620,90);
290 xy.clear();
291 quadratic_bezier_curves(340,90,480,2,620,90,10,xy);
292 color=std::make_tuple(0.8784313725, 0.8784313725, 0.0);
293 draw_xy_dots(image,color,xy,width,height);
294 xy.clear();
295 color=std::make_tuple(0.0, 0.8784313725, 0.0);
296 draw_marker(340,90,image,color,width,height);
297 color=std::make_tuple(0.0, 0.8784313725, 0.0);
298 draw_marker(480,2,image,color,width,height);
299 color=std::make_tuple(0.0, 0.8784313725, 0.0);
300 draw_marker(620,90,image,color,width,height);
14 Appendix A: Source Code Listings 118

301
302 // Draw line as a curve 2.
303 xy.clear();
304 color=std::make_tuple(0.9296875, 0.9296875, 0.9296875);
305 coords=std::make_tuple(200,270,293,182);
306 draw_line(image,coords,color,width,height);
307 coords=std::make_tuple(386,357,480,270);
308 draw_line(image,coords,color,width,height);
309 cubic_bezier_curves(200,270,293,182,386,357,480,270,40,xy);
310 color=std::make_tuple(0.7019607843, 0.2196078431, 0.6078431373);
311 draw_xy_line(image,color,xy,width,height,480,270);
312 xy.clear();
313 cubic_bezier_curves(200,270,293,182,386,357,480,270,10,xy);
314 color=std::make_tuple(0.8784313725, 0.8784313725, 0.0);
315 draw_xy_dots(image,color,xy,width,height);
316 xy.clear();
317 color=std::make_tuple(0.0, 0.8784313725, 0.0);
318 draw_marker(200,270,image,color,width,height);
319 color=std::make_tuple(0.0, 0.8784313725, 0.0);
320 draw_marker(293,182,image,color,width,height);
321 color=std::make_tuple(0.0, 0.8784313725, 0.0);
322 draw_marker(386,357,image,color,width,height);
323 color=std::make_tuple(0.0, 0.8784313725, 0.0);
324 draw_marker(480,270,image,color,width,height);
325
326 save_image(image,width,height,"10_curved_lines.ppm");
327
328 return 0;
329 }

11_rectangles.cpp - 4120 bytes.

1 // Compile: clang++ -std=c++17 11_rectangles.cpp -o 11_rectangles


2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <random>
8 #include <cmath>
9
10 int get_index(int x, int y, int width)
11 {
14 Appendix A: Source Code Listings 119

12 return x+width*y;
13 }
14
15 int calc_size(int width, int height)
16 {
17 return width*height;
18 }
19
20 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
21 height)
22 {
23 for (int y=0;y<height;++y) {
24 for (int x=0;x<width;++x) {
25 image[get_index(x,y,width)]=std::make_tuple(1.0f, 1.0f, 1.0f);
26 }
27 }
28 }
29
30 void draw_line(std::vector<std::tuple<float, float, float>> &image, std::tuple<int, \
31 int, int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
32 {
33 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
34 int y2=std::get<3>(coords);
35 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
36 dx = x2 - x1; dy = y2 - y1;
37 if (dx == 0)
38 {
39 if (y2 < y1) std::swap(y1, y2);
40 for (y = y1; y <= y2; y++)
41 image[get_index(x1,y,width)]=color;
42 return;
43 }
44 if (dy == 0)
45 {
46 if (x2 < x1) std::swap(x1, x2);
47 for (x = x1; x <= x2; x++)
48 image[get_index(x,y1,width)]=color;
49 return;
50 }
51 dx1 = abs(dx); dy1 = abs(dy);
52 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
53 if (dy1 <= dx1)
54 {
14 Appendix A: Source Code Listings 120

55 if (dx >= 0)
56 {
57 x = x1; y = y1; xe = x2;
58 }
59 else
60 {
61 x = x2; y = y2; xe = x1;
62 }
63 image[get_index(x,y,width)]=color;
64 for (i = 0; x<xe; i++)
65 {
66 x = x + 1;
67 if (px<0)
68 px = px + 2 * dy1;
69 else
70 {
71 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
72 px = px + 2 * (dy1 - dx1);
73 }
74 image[get_index(x,y,width)]=color;
75 }
76 }
77 else
78 {
79 if (dy >= 0)
80 {
81 x = x1; y = y1; ye = y2;
82 }
83 else
84 {
85 x = x2; y = y2; ye = y1;
86 }
87 image[get_index(x,y,width)]=color;
88 for (i = 0; y<ye; i++)
89 {
90 y = y + 1;
91 if (py <= 0)
92 py = py + 2 * dx1;
93 else
94 {
95 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
96 py = py + 2 * (dx1 - dy1);
97 }
14 Appendix A: Source Code Listings 121

98 image[get_index(x,y,width)]=color;
99 }
100 }
101 }
102
103 void draw_rect(int x, int y, int w, int h, std::vector<std::tuple<float, float, floa\
104 t>> &image, std::tuple<float,float,float> &color, int width, int height)
105 {
106 w=w-1;
107 h=h-1;
108 std::tuple<int, int, int, int> coords=std::make_tuple(x, y, x+w, y);
109 draw_line(image, coords, color, width, height);
110 coords=std::make_tuple(x+w, y, x+w, y+h);
111 draw_line(image, coords, color, width, height);
112 coords=std::make_tuple(x+w, y+h, x, y+h);
113 draw_line(image, coords, color, width, height);
114 coords=std::make_tuple(x, y+h, x, y);
115 draw_line(image, coords, color, width, height);
116 }
117
118 void draw_filled_rect(int x, int y, int w, int h, std::vector<std::tuple<float, floa\
119 t, float>> &image, std::tuple<float,float,float> &color, int width, int height)
120 {
121 int x2 = x + w;
122 int y2 = y + h;
123
124 if (x < 0) {x = 0;}
125 if (x >= width) {x = width;}
126 if (y < 0) {y = 0;}
127 if (y >= height) {y = height;}
128
129 if (x2 < 0) {x2 = 0;}
130 if (x2 >= width) {x2 = width;}
131 if (y2 < 0) {y2 = 0;}
132 if (y2 >= height) {y2 = height;}
133
134 for (int i = y; i < y2; i++) {
135 for (int j = x; j < x2; j++) {
136 image[get_index(j,i,width)]=color;
137 }
138 }
139 }
140
14 Appendix A: Source Code Listings 122

141 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \


142 height, std::string filename)
143 {
144 std::tuple<float, float, float> color;
145 std::ofstream out(filename, std::ofstream::out);
146 out << "P3\n" << width << " " << height << "\n255\n";
147 for (int i=0;i<(width*height);++i)
148 {
149 color=image[i];
150 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
151 " " << int(std::get<2>(color)*255.0f) << '\n';
152 }
153 out.close();
154 }
155
156 int main()
157 {
158 int width=640;
159 int height=360;
160 int x1=0; int y=0; int wh=0; int x2=0;
161
162 wh=(height/2)*0.8;
163 x1=(width-(wh*3))/2;
164 y=(height-wh)/2;
165 x2=width-x1-wh;
166
167 std::vector<std::tuple<float, float, float>> image;
168 std::tuple<float,float,float> color=std::make_tuple(0.0f,0.0f,0.0f);
169
170 image.resize(calc_size(width, height));
171 clear_image(image,width,height);
172
173 draw_rect(x1,y,wh,wh,image,color,width,height);
174 draw_filled_rect(x2,y,wh,wh,image,color,width,height);
175
176 save_image(image,width,height,"11_rectangles.ppm");
177
178 return 0;
179 }
14 Appendix A: Source Code Listings 123

11_rectangles_from_file.cpp - 4451 bytes.


1 // Compile: clang++ -std=c++17 11_rectangles_from_file.cpp -o 11_rectangles_from_file
2
3 #include <algorithm>
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10
11 bool startsWithCaseInsensitive(std::string mainStr, std::string toMatch)
12 {
13 // Convert mainStr to lower case
14 std::transform(mainStr.begin(), mainStr.end(), mainStr.begin(), ::tolower);
15 // Convert toMatch to lower case
16 std::transform(toMatch.begin(), toMatch.end(), toMatch.begin(), ::tolower);
17 if(mainStr.find(toMatch) == 0)
18 return true;
19 else
20 return false;
21 }
22
23 int get_index(int x, int y, int width)
24 {
25 return x+width*y;
26 }
27
28 int calc_size(int width, int height)
29 {
30 return width*height;
31 }
32
33 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
34 at,float,float> &colorRGB, int width, int height)
35 {
36 for (int y=0;y<height;++y) {
37 for (int x=0;x<width;++x) {
38 image[get_index(x,y,width)]=colorRGB;
39 }
40 }
41 }
42
14 Appendix A: Source Code Listings 124

43 std::tuple<int,int,float,float,float> parse_bginfo_line(const std::string str, int &\


44 width, int &height)
45 {
46 size_t start;
47 size_t end = 0;
48 std::vector<std::string> out;
49
50 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
51 {
52 end = str.find(' ', start);
53 out.push_back(str.substr(start, end - start));
54 }
55
56 width=stoi(out[1]);
57 height=stoi(out[2]);
58 float rf=stof(out[3]);
59 float gf=stof(out[4]);
60 float bf=stof(out[5]);
61
62 return std::make_tuple(width,height,rf,gf,bf);
63 }
64
65 std::tuple<int,int,int,int,float,float,float,float> parse_rect_line(const std::strin\
66 g str)
67 {
68 size_t start;
69 size_t end = 0;
70 std::vector<std::string> out;
71
72 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
73 {
74 end = str.find(' ', start);
75 out.push_back(str.substr(start, end - start));
76 }
77
78 int x1=stoi(out[1]);
79 int y1=stoi(out[2]);
80 int x2=stoi(out[3]);
81 int y2=stoi(out[4]);
82 float rf=stof(out[5]);
83 float gf=stof(out[6]);
84 float bf=stof(out[7]);
85 float af=stof(out[8]);
14 Appendix A: Source Code Listings 125

86
87 return std::make_tuple(x1,y1,x2,y2,rf,gf,bf,af);
88 }
89
90 std::tuple<float,float,float> blend_colors(std::tuple<float,float,float> &colorBGRGB\
91 , std::tuple<float,float,float,float> &colorRGBA)
92 {
93 float r=0.0f; float g=0.0f; float b=0.0f;
94 r = (std::get<0>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<0>(colorBGRGB) * \
95 (1.0 - std::get<3>(colorRGBA)));
96 g = (std::get<1>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<1>(colorBGRGB) * \
97 (1.0 - std::get<3>(colorRGBA)));
98 b = (std::get<2>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<2>(colorBGRGB) * \
99 (1.0 - std::get<3>(colorRGBA)));
100
101 return std::make_tuple(r,g,b);
102 }
103
104 void draw_filled_rect(int x1,int y1,int x2,int y2, std::vector<std::tuple<float, flo\
105 at, float>> &image, std::tuple<float,float,float,float> &colorRGBA, int width, int h
106 eight)
107 {
108 for (int i = y1; i < y2; i++) {
109 for (int j = x1; j < x2; j++) {
110 image[get_index(j,i,width)]=blend_colors(image[get_index(j,i,width)],colorRG
111 }
112 }
113 }
114
115 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
116 height, std::string filename)
117 {
118 std::tuple<float, float, float> color;
119 std::ofstream out(filename, std::ofstream::out);
120 out << "P3\n" << width << " " << height << "\n255\n";
121 for (int i=0;i<(width*height);++i)
122 {
123 color=image[i];
124 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
125 " " << int(std::get<2>(color)*255.0f) << '\n';
126 }
127 out.close();
128 }
14 Appendix A: Source Code Listings 126

129
130 int main()
131 {
132 std::ifstream infile("11_squint_with_your_eyes.txt");
133 std::string line;
134 std::tuple<int,int,int,int,float,float,float,float> rect;
135 std::tuple<int,int,float,float,float> bginfo;
136 std::tuple<float,float,float> colorBGRGB;
137 std::tuple<float,float,float,float> colorRGBA;
138 int width,height,x1,y1,x2,y2;
139 float rf,gf,bf,af;
140 float bg_rf,bg_gf,bg_bf;
141 std::vector<std::tuple<float, float, float>> image;
142 while (getline(infile, line))
143 {
144 if (startsWithCaseInsensitive(line,"r")) {
145 rect=parse_rect_line(line);
146 std::tie(x1,y1,x2,y2,rf,gf,bf,af) = rect;
147 colorRGBA=std::make_tuple(rf,gf,bf,af);
148 draw_filled_rect(x1,y1,x2,y2,image,colorRGBA,width,height);
149 }
150
151 if (startsWithCaseInsensitive(line,"b")) {
152 bginfo=parse_bginfo_line(line,width,height);
153 std::tie(width,height,bg_rf,bg_gf,bg_bf) = bginfo;
154 image.resize(calc_size(width, height));
155 colorBGRGB=std::make_tuple(bg_rf,bg_gf,bg_bf);
156 clear_image(image,colorBGRGB,width,height);
157 }
158 }
159 infile.close();
160
161 save_image(image,width,height,"11_squint_with_your_eyes.ppm");
162
163 return 0;
164 }
14 Appendix A: Source Code Listings 127

11_squint_with_your_eyes.txt - 26913 bytes.


1 b 540 720 0.211765 0.172549 0.152941
2 r 211 190 333 441 0.796078 0.517647 0.305882 0.501961
3 r 58 398 200 719 0.47451 0.231373 0.239216 0.501961
4 r 253 601 393 719 0.396078 0.368627 0.392157 0.501961
5 r 278 326 348 479 0.737255 0.423529 0.329412 0.501961
6 r 377 0 539 692 0.0117647 0.0627451 0.0784314 0.501961
7 r 93 318 142 506 0.380392 0.423529 0.419608 0.501961
8 r 211 413 265 595 0.054902 0.0470588 0.0392157 0.501961
9 r 303 39 431 301 0.0588235 0.0784314 0.0470588 0.501961
10 r 132 107 183 373 0 0.0235294 0 0.501961
11 r 186 170 320 271 0.552941 0.423529 0.211765 0.501961
12 r 37 562 144 719 0.447059 0.0705882 0.0745098 0.501961
13 r 180 76 371 146 0 0.0156863 0 0.501961
14 r 268 550 319 585 0.631373 0.396078 0.25098 0.501961
15 r 198 352 302 379 0.756863 0.521569 0.356863 0.501961
16 r 328 595 405 692 0.392157 0.317647 0.32549 0.501961
17 r 245 467 291 544 0 0.00784314 0 0.501961
18 r 166 396 228 440 0.0117647 0.0901961 0.0627451 0.501961
19 r 188 276 252 317 0.286275 0.152941 0.0745098 0.501961
20 r 250 372 339 451 0.533333 0.305882 0.294118 0.501961
21 r 228 196 286 243 0.643137 0.588235 0.364706 0.501961
22 r 114 390 162 473 0.407843 0.403922 0.384314 0.501961
23 r 273 317 297 372 0.929412 0.603922 0.352941 0.501961
24 r 0 202 76 534 0.0941176 0.172549 0.168627 0.501961
25 r 183 427 202 633 0.317647 0.372549 0.372549 0.501961
26 r 241 587 315 672 0.196078 0.219608 0.231373 0.501961
27 r 97 165 131 294 0 0.054902 0.027451 0.501961
28 r 287 250 383 303 0.266667 0.172549 0.12549 0.501961
29 r 213 144 306 198 0.4 0.211765 0.0823529 0.501961
30 r 395 211 458 461 0.00392157 0.0156863 0.00784314 0.501961
31 r 159 94 210 192 0.0509804 0.0705882 0.0431373 0.501961
32 r 179 621 249 679 0.415686 0.2 0.203922 0.501961
33 r 289 454 386 484 0.537255 0.329412 0.152941 0.501961
34 r 121 307 141 398 0.372549 0.364706 0.356863 0.501961
35 r 248 697 294 719 0.603922 0.196078 0.2 0.501961
36 r 398 628 408 699 0.486275 0.027451 0.0313726 0.501961
37 r 111 548 154 631 0.231373 0.133333 0.133333 0.501961
38 r 327 293 387 353 0.215686 0.156863 0.117647 0.501961
39 r 156 329 179 404 0.00392157 0.0196078 0.00784314 0.501961
40 r 0 0 116 219 0.180392 0.290196 0.294118 0.501961
41 r 223 372 261 400 0.733333 0.505882 0.317647 0.501961
42 r 241 662 269 688 0.0196078 0.0901961 0.0823529 0.501961
14 Appendix A: Source Code Listings 128

43 r 360 345 406 424 0.0901961 0.0745098 0.054902 0.501961


44 r 4 279 50 622 0.137255 0.152941 0.141176 0.501961
45 r 287 643 337 702 0.34902 0.380392 0.388235 0.501961
46 r 262 352 275 390 0.321569 0.207843 0.172549 0.501961
47 r 194 266 230 353 0.313726 0.219608 0.156863 0.501961
48 r 307 418 335 480 0.686275 0.403922 0.341176 0.501961
49 r 202 479 232 548 0.305882 0.196078 0.211765 0.501961
50 r 284 355 300 364 1 0.890196 0.74902 0.501961
51 r 299 477 365 560 0.345098 0.184314 0.0941176 0.501961
52 r 278 622 301 650 0.054902 0.0901961 0.0901961 0.501961
53 r 42 598 72 718 0.501961 0.105882 0.109804 0.501961
54 r 197 681 239 719 0.239216 0.027451 0.027451 0.501961
55 r 77 189 100 365 0.0980392 0.141176 0.137255 0.501961
56 r 65 522 108 635 0.454902 0.109804 0.105882 0.501961
57 r 198 421 238 450 0.027451 0.0352941 0.0117647 0.501961
58 r 335 587 381 655 0.298039 0.356863 0.368627 0.501961
59 r 353 249 364 362 0 0.0705882 0.0941176 0.501961
60 r 346 373 364 543 0.317647 0.196078 0.129412 0.501961
61 r 117 0 539 81 0.117647 0.188235 0.184314 0.501961
62 r 408 693 539 719 0.0745098 0.0509804 0.101961 0.501961
63 r 287 205 331 233 0.537255 0.411765 0.258824 0.501961
64 r 234 407 326 423 0.498039 0.262745 0.262745 0.501961
65 r 88 0 162 128 0.156863 0.227451 0.223529 0.501961
66 r 285 288 326 331 0.509804 0.317647 0.223529 0.501961
67 r 329 136 392 203 0.0313726 0.0431373 0.0235294 0.501961
68 r 73 384 109 516 0.290196 0.290196 0.286275 0.501961
69 r 284 584 315 600 0.360784 0.384314 0.403922 0.501961
70 r 369 277 377 328 0.517647 0.290196 0.152941 0.501961
71 r 396 435 520 632 0.0823529 0.0901961 0.129412 0.501961
72 r 199 302 236 311 0.619608 0.403922 0.301961 0.501961
73 r 274 378 291 399 0.27451 0.2 0.113725 0.501961
74 r 328 679 410 719 0.356863 0.203922 0.207843 0.501961
75 r 268 293 280 361 0.756863 0.482353 0.309804 0.501961
76 r 105 152 161 266 0.0705882 0.0705882 0.0392157 0.501961
77 r 29 666 49 719 0.482353 0.0784314 0.0862745 0.501961
78 r 196 219 298 258 0.541176 0.45098 0.239216 0.501961
79 r 269 439 353 459 0.513726 0.384314 0.235294 0.501961
80 r 350 540 401 578 0.0784314 0.105882 0.160784 0.501961
81 r 162 680 220 707 0.447059 0.168627 0.164706 0.501961
82 r 263 644 281 663 0.0156863 0.0666667 0.0705882 0.501961
83 r 216 695 240 719 0 0.0862745 0.0666667 0.501961
84 r 302 598 320 621 0.0313726 0.0980392 0.121569 0.501961
85 r 240 612 254 668 0.376471 0.305882 0.309804 0.501961
14 Appendix A: Source Code Listings 129

86 r 225 438 258 495 0.054902 0.0627451 0.0313726 0.501961


87 r 297 422 331 435 0.807843 0.384314 0.505882 0.501961
88 r 241 194 278 226 0.654902 0.564706 0.376471 0.501961
89 r 168 278 229 290 0.141176 0.0862745 0.0352941 0.501961
90 r 163 407 193 475 0.254902 0.266667 0.25098 0.501961
91 r 197 165 213 274 0.466667 0.290196 0.172549 0.501961
92 r 314 615 352 662 0.317647 0.388235 0.4 0.501961
93 r 244 475 299 540 0.0901961 0.0705882 0.0431373 0.501961
94 r 321 247 335 268 0.505882 0.352941 0.219608 0.501961
95 r 70 465 124 525 0.384314 0.235294 0.231373 0.501961
96 r 316 573 347 597 0.0470588 0.12549 0.180392 0.501961
97 r 384 0 539 179 0.14902 0.168627 0.14902 0.501961
98 r 324 343 354 374 0.454902 0.341176 0.262745 0.501961
99 r 180 562 193 719 0.4 0.286275 0.282353 0.501961
100 r 216 627 224 653 0.0627451 0.0235294 0 0.501961
101 r 280 261 313 293 0.345098 0.188235 0.0941176 0.501961
102 r 314 147 409 180 0.0509804 0.0666667 0.0431373 0.501961
103 r 306 242 321 263 0.156863 0.101961 0.0784314 0.501961
104 r 354 447 394 470 0.219608 0.12549 0.0901961 0.501961
105 r 317 525 356 551 0.403922 0.262745 0.164706 0.501961
106 r 311 398 348 411 0.376471 0.152941 0.247059 0.501961
107 r 233 622 240 641 0.643137 0.0196078 0.0196078 0.501961
108 r 232 676 256 701 0.0352941 0.0901961 0.0823529 0.501961
109 r 139 316 216 328 0.0901961 0.0784314 0.0431373 0.501961
110 r 358 197 368 251 0.329412 0.164706 0.0823529 0.501961
111 r 97 370 151 412 0.352941 0.345098 0.341176 0.501961
112 r 311 373 335 394 0.705882 0.490196 0.337255 0.501961
113 r 43 100 81 208 0.266667 0.262745 0.254902 0.501961
114 r 216 68 304 129 0.0431373 0.0705882 0.0509804 0.501961
115 r 284 557 304 575 0.639216 0.380392 0.192157 0.501961
116 r 212 577 272 600 0.12549 0.105882 0.0980392 0.501961
117 r 195 350 265 364 0.556863 0.364706 0.235294 0.501961
118 r 256 604 271 648 0.360784 0.32549 0.32549 0.501961
119 r 148 104 215 162 0.0666667 0.0823529 0.054902 0.501961
120 r 231 317 239 329 0.568627 0.572549 0.607843 0.501961
121 r 221 646 235 682 0.478431 0.176471 0.184314 0.501961
122 r 287 446 314 450 0.231373 0.152941 0.0862745 0.501961
123 r 130 269 142 368 0.231373 0.223529 0.207843 0.501961
124 r 282 705 291 719 0.713726 0.0588235 0.0588235 0.501961
125 r 128 404 136 538 0.27451 0.341176 0.341176 0.501961
126 r 240 396 278 422 0.584314 0.403922 0.254902 0.501961
127 r 285 321 303 345 0.713726 0.364706 0.109804 0.501961
128 r 110 590 122 660 0.196078 0.12549 0.12549 0.501961
14 Appendix A: Source Code Listings 130

129 r 245 274 292 296 0.560784 0.356863 0.160784 0.501961


130 r 206 326 233 339 0.423529 0.403922 0.337255 0.501961
131 r 196 390 214 438 0.0823529 0.0588235 0.0235294 0.501961
132 r 363 417 369 446 0.447059 0.305882 0.215686 0.501961
133 r 370 386 473 434 0.0666667 0.0705882 0.0627451 0.501961
134 r 207 380 230 402 0.513726 0.290196 0.184314 0.501961
135 r 260 681 286 698 0.439216 0.32549 0.321569 0.501961
136 r 276 163 315 200 0.372549 0.215686 0.109804 0.501961
137 r 170 368 180 429 0.0588235 0.0666667 0.0431373 0.501961
138 r 372 508 450 603 0.105882 0.117647 0.145098 0.501961
139 r 57 398 71 472 0.0941176 0.152941 0.129412 0.501961
140 r 386 611 399 661 0.384314 0.172549 0.160784 0.501961
141 r 286 452 340 472 0.603922 0.419608 0.219608 0.501961
142 r 362 709 373 719 0.647059 0.141176 0.133333 0.501961
143 r 265 548 276 574 0.298039 0.313726 0.360784 0.501961
144 r 474 81 539 386 0.141176 0.176471 0.160784 0.501961
145 r 290 485 380 515 0.243137 0.137255 0.0823529 0.501961
146 r 445 181 539 246 0.141176 0.164706 0.14902 0.501961
147 r 48 556 57 624 0.305882 0.235294 0.231373 0.501961
148 r 277 223 312 246 0.470588 0.447059 0.282353 0.501961
149 r 209 459 219 558 0.286275 0.188235 0.188235 0.501961
150 r 69 706 80 719 0.258824 0.329412 0.309804 0.501961
151 r 294 614 307 632 0.0431373 0.0784314 0.0980392 0.501961
152 r 259 462 281 524 0.0352941 0.0509804 0.027451 0.501961
153 r 414 263 470 336 0.0196078 0.0352941 0.027451 0.501961
154 r 328 162 358 210 0.145098 0.133333 0.0901961 0.501961
155 r 167 663 180 719 0.490196 0.14902 0.145098 0.501961
156 r 208 647 215 677 0.211765 0.027451 0.00784314 0.501961
157 r 275 314 282 332 0.854902 0.647059 0.521569 0.501961
158 r 283 411 320 422 0.435294 0.160784 0.258824 0.501961
159 r 175 304 192 357 0.133333 0.160784 0.141176 0.501961
160 r 267 597 288 606 0.117647 0.0862745 0.0627451 0.501961
161 r 318 327 328 347 0.678431 0.517647 0.427451 0.501961
162 r 0 623 25 719 0.117647 0.145098 0.137255 0.501961
163 r 324 410 340 426 0.717647 0.396078 0.47451 0.501961
164 r 140 395 163 459 0.403922 0.333333 0.313726 0.501961
165 r 356 578 377 608 0.247059 0.282353 0.290196 0.501961
166 r 408 581 539 697 0.12549 0.101961 0.133333 0.501961
167 r 361 357 374 405 0.0196078 0.0784314 0.0901961 0.501961
168 r 218 316 223 320 0.643137 0.690196 0.701961 0.501961
169 r 327 276 333 279 0.603922 0.639216 0.65098 0.501961
170 r 259 0 376 75 0.105882 0.133333 0.121569 0.501961
171 r 207 313 237 316 0.0941176 0.0705882 0.0352941 0.501961
14 Appendix A: Source Code Listings 131

172 r 191 287 247 302 0.32549 0.172549 0.0980392 0.501961


173 r 253 297 261 354 0.454902 0.243137 0.101961 0.501961
174 r 394 402 406 435 0.215686 0.145098 0.109804 0.501961
175 r 190 442 200 588 0.309804 0.341176 0.341176 0.501961
176 r 263 616 283 632 0.352941 0.341176 0.352941 0.501961
177 r 365 31 495 125 0.129412 0.145098 0.129412 0.501961
178 r 445 427 485 465 0.121569 0.14902 0.156863 0.501961
179 r 139 496 161 570 0.329412 0.113725 0.12549 0.501961
180 r 96 98 136 171 0.137255 0.188235 0.184314 0.501961
181 r 294 542 337 566 0.388235 0.223529 0.129412 0.501961
182 r 244 142 291 178 0.376471 0.227451 0.101961 0.501961
183 r 334 312 345 358 0.403922 0.278431 0.192157 0.501961
184 r 127 605 146 647 0.431373 0.0941176 0.0901961 0.501961
185 r 253 421 284 443 0.447059 0.27451 0.215686 0.501961
186 r 402 663 408 694 0.52549 0.0313726 0.027451 0.501961
187 r 342 217 359 307 0.0666667 0.129412 0.133333 0.501961
188 r 0 275 77 430 0.145098 0.160784 0.14902 0.501961
189 r 161 204 170 281 0.235294 0.129412 0.0745098 0.501961
190 r 111 457 125 519 0.490196 0.247059 0.243137 0.501961
191 r 213 138 256 156 0.176471 0.14902 0.0784314 0.501961
192 r 294 255 312 270 0.192157 0.12549 0.0862745 0.501961
193 r 82 350 100 383 0.231373 0.239216 0.235294 0.501961
194 r 274 581 298 584 0.737255 0.403922 0.2 0.501961
195 r 309 579 317 591 0.278431 0.431373 0.478431 0.501961
196 r 101 0 191 88 0.168627 0.219608 0.215686 0.501961
197 r 310 449 331 483 0.611765 0.4 0.243137 0.501961
198 r 125 146 192 195 0.0745098 0.0823529 0.0509804 0.501961
199 r 193 370 199 403 0.0666667 0.0784314 0.0352941 0.501961
200 r 82 366 89 548 0.266667 0.258824 0.247059 0.501961
201 r 203 159 227 195 0.32549 0.2 0.117647 0.501961
202 r 297 78 364 152 0.0431373 0.0666667 0.054902 0.501961
203 r 137 652 170 719 0.329412 0.164706 0.156863 0.501961
204 r 223 257 280 281 0.501961 0.372549 0.176471 0.501961
205 r 309 270 320 277 0.533333 0.376471 0.270588 0.501961
206 r 1 354 43 639 0.160784 0.160784 0.14902 0.501961
207 r 207 584 235 629 0.215686 0.121569 0.109804 0.501961
208 r 280 354 291 369 0.921569 0.678431 0.498039 0.501961
209 r 118 561 132 614 0.2 0.172549 0.184314 0.501961
210 r 144 276 165 375 0.0588235 0.0470588 0.0156863 0.501961
211 r 204 359 250 384 0.643137 0.439216 0.286275 0.501961
212 r 98 288 121 331 0.160784 0.188235 0.180392 0.501961
213 r 291 434 335 443 0.6 0.231373 0.313726 0.501961
214 r 271 377 302 389 0.380392 0.243137 0.156863 0.501961
14 Appendix A: Source Code Listings 132

215 r 215 661 229 686 0.360784 0.258824 0.266667 0.501961


216 r 201 660 211 717 0.368627 0.0745098 0.0705882 0.501961
217 r 291 641 318 708 0.329412 0.333333 0.341176 0.501961
218 r 185 203 197 275 0.439216 0.294118 0.180392 0.501961
219 r 293 594 307 605 0.364706 0.364706 0.372549 0.501961
220 r 309 184 324 211 0.431373 0.231373 0.0901961 0.501961
221 r 404 576 437 645 0.0784314 0.121569 0.152941 0.501961
222 r 238 708 275 719 0.352941 0.262745 0.258824 0.501961
223 r 348 271 354 352 0.117647 0.184314 0.215686 0.501961
224 r 518 582 533 606 0.262745 0.0980392 0.105882 0.501961
225 r 372 171 417 264 0.054902 0.0509804 0.0431373 0.501961
226 r 385 430 437 457 0.0352941 0.0509804 0.0392157 0.501961
227 r 312 290 321 296 0.486275 0.454902 0.466667 0.501961
228 r 271 691 284 711 0.607843 0.2 0.203922 0.501961
229 r 312 593 324 607 0.027451 0.0823529 0.121569 0.501961
230 r 155 465 178 523 0.286275 0.156863 0.164706 0.501961
231 r 24 689 70 719 0.403922 0.137255 0.133333 0.501961
232 r 319 275 328 291 0.172549 0.0823529 0 0.501961
233 r 100 646 112 718 0.290196 0.109804 0.117647 0.501961
234 r 358 649 400 710 0.290196 0.239216 0.239216 0.501961
235 r 87 265 124 302 0.105882 0.0980392 0.0705882 0.501961
236 r 448 316 503 376 0.105882 0.12549 0.0980392 0.501961
237 r 185 394 193 491 0.262745 0.290196 0.27451 0.501961
238 r 265 287 276 353 0.639216 0.419608 0.258824 0.501961
239 r 376 292 388 394 0.207843 0.101961 0.0627451 0.501961
240 r 234 370 262 389 0.682353 0.501961 0.360784 0.501961
241 r 306 321 314 373 0.54902 0.309804 0.176471 0.501961
242 r 271 571 278 581 0.47451 0.45098 0.45098 0.501961
243 r 223 529 265 592 0.109804 0.117647 0.0980392 0.501961
244 r 52 617 69 671 0.494118 0.0627451 0.0666667 0.501961
245 r 216 301 224 310 0.662745 0.498039 0.384314 0.501961
246 r 253 658 263 682 0.0588235 0.0862745 0.0784314 0.501961
247 r 224 646 232 657 0.556863 0.0196078 0.0156863 0.501961
248 r 281 14 309 91 0.129412 0.14902 0.137255 0.501961
249 r 220 406 234 429 0.27451 0.164706 0.0941176 0.501961
250 r 94 518 123 584 0.392157 0.168627 0.168627 0.501961
251 r 275 441 288 467 0.458824 0.380392 0.14902 0.501961
252 r 363 463 382 489 0.372549 0.243137 0.172549 0.501961
253 r 300 349 323 364 0.741176 0.462745 0.294118 0.501961
254 r 279 197 291 262 0.529412 0.494118 0.301961 0.501961
255 r 199 442 206 502 0.192157 0.231373 0.231373 0.501961
256 r 378 597 386 650 0.384314 0.278431 0.270588 0.501961
257 r 149 431 175 451 0.411765 0.32549 0.309804 0.501961
14 Appendix A: Source Code Listings 133

258 r 325 300 340 318 0.266667 0.14902 0.0980392 0.501961


259 r 289 392 301 399 0.682353 0.529412 0.403922 0.501961
260 r 215 124 227 161 0.235294 0.168627 0.113725 0.501961
261 r 334 565 353 588 0.0666667 0.109804 0.152941 0.501961
262 r 288 505 307 543 0.180392 0.113725 0.0745098 0.501961
263 r 179 297 183 449 0.129412 0.14902 0.129412 0.501961
264 r 353 186 359 207 0.337255 0.176471 0.0941176 0.501961
265 r 317 258 328 272 0.47451 0.333333 0.227451 0.501961
266 r 16 112 46 148 0.266667 0.270588 0.262745 0.501961
267 r 226 334 270 357 0.564706 0.356863 0.215686 0.501961
268 r 190 289 209 317 0.364706 0.203922 0.129412 0.501961
269 r 342 377 354 406 0.309804 0.196078 0.117647 0.501961
270 r 190 320 201 341 0.160784 0.0705882 0.027451 0.501961
271 r 193 620 201 691 0.27451 0.227451 0.219608 0.501961
272 r 207 321 230 324 0.156863 0.121569 0.0588235 0.501961
273 r 199 202 233 245 0.537255 0.392157 0.223529 0.501961
274 r 297 217 335 230 0.478431 0.34902 0.219608 0.501961
275 r 323 442 351 452 0.568627 0.435294 0.341176 0.501961
276 r 366 230 381 282 0.239216 0.109804 0.0666667 0.501961
277 r 0 165 55 262 0.172549 0.215686 0.211765 0.501961
278 r 234 643 246 671 0.321569 0.282353 0.286275 0.501961
279 r 78 610 102 693 0.439216 0.164706 0.160784 0.501961
280 r 396 624 402 638 0.494118 0.0352941 0.0313726 0.501961
281 r 439 387 484 407 0.027451 0.0509804 0.0431373 0.501961
282 r 223 493 239 535 0.211765 0.156863 0.160784 0.501961
283 r 361 529 405 567 0.113725 0.113725 0.141176 0.501961
284 r 0 578 2 598 0.486275 0.054902 0.0666667 0.501961
285 r 66 660 92 709 0.415686 0.172549 0.168627 0.501961
286 r 316 237 339 249 0.231373 0.152941 0.105882 0.501961
287 r 368 296 373 338 0.443137 0.27451 0.172549 0.501961
288 r 493 543 507 655 0.0588235 0.0705882 0.0705882 0.501961
289 r 159 704 178 719 0.517647 0.172549 0.168627 0.501961
290 r 100 349 128 389 0.352941 0.34902 0.360784 0.501961
291 r 103 280 112 324 0.215686 0.235294 0.227451 0.501961
292 r 135 351 140 422 0.388235 0.368627 0.356863 0.501961
293 r 253 594 259 663 0.290196 0.258824 0.25098 0.501961
294 r 207 688 222 702 0.431373 0.0745098 0.0745098 0.501961
295 r 0 206 92 250 0.168627 0.211765 0.207843 0.501961
296 r 293 299 318 322 0.509804 0.360784 0.294118 0.501961
297 r 327 270 341 276 0.0588235 0.0431373 0.0235294 0.501961
298 r 53 157 72 206 0.305882 0.262745 0.254902 0.501961
299 r 87 538 96 562 0.427451 0.0470588 0.0509804 0.501961
300 r 121 385 128 470 0.439216 0.403922 0.376471 0.501961
14 Appendix A: Source Code Listings 134

301 r 314 514 326 576 0.337255 0.207843 0.133333 0.501961


302 r 274 543 298 553 0.309804 0.160784 0.0901961 0.501961
303 r 311 136 330 174 0.0980392 0.121569 0.101961 0.501961
304 r 278 660 316 688 0.313726 0.34902 0.356863 0.501961
305 r 35 654 59 695 0.462745 0.0823529 0.0823529 0.501961
306 r 508 503 535 548 0.0745098 0.0705882 0.0705882 0.501961
307 r 383 455 391 478 0.313726 0.192157 0.133333 0.501961
308 r 408 655 425 719 0.2 0.0980392 0.113725 0.501961
309 r 402 445 425 486 0.0352941 0.0509804 0.0509804 0.501961
310 r 196 344 201 377 0.470588 0.282353 0.152941 0.501961
311 r 270 640 285 656 0.0705882 0.105882 0.109804 0.501961
312 r 259 570 269 597 0.0705882 0.109804 0.12549 0.501961
313 r 325 433 335 443 0.431373 0.266667 0.188235 0.501961
314 r 68 475 73 543 0.392157 0.172549 0.164706 0.501961
315 r 186 256 224 273 0.423529 0.317647 0.239216 0.501961
316 r 221 456 270 467 0.0470588 0.0470588 0.0235294 0.501961
317 r 318 610 382 630 0.313726 0.356863 0.360784 0.501961
318 r 25 613 32 679 0.117647 0.152941 0.145098 0.501961
319 r 183 186 189 249 0.286275 0.219608 0.133333 0.501961
320 r 180 0 236 77 0.141176 0.188235 0.188235 0.501961
321 r 205 393 218 412 0.192157 0.12549 0.0823529 0.501961
322 r 0 460 60 574 0.152941 0.168627 0.152941 0.501961
323 r 345 120 376 167 0.0235294 0.0431373 0.0313726 0.501961
324 r 354 234 361 322 0.0470588 0.0745098 0.0666667 0.501961
325 r 261 355 267 373 0.380392 0.207843 0.172549 0.501961
326 r 238 311 251 348 0.533333 0.364706 0.239216 0.501961
327 r 54 555 61 599 0.364706 0.223529 0.219608 0.501961
328 r 133 458 150 489 0.321569 0.317647 0.313726 0.501961
329 r 74 434 108 509 0.321569 0.278431 0.270588 0.501961
330 r 249 203 282 212 0.690196 0.592157 0.396078 0.501961
331 r 353 634 370 651 0.439216 0.298039 0.298039 0.501961
332 r 152 551 180 664 0.290196 0.184314 0.176471 0.501961
333 r 213 640 218 662 0.0862745 0.0627451 0.0313726 0.501961
334 r 214 613 220 633 0.368627 0.215686 0.211765 0.501961
335 r 323 419 331 428 0.788235 0.545098 0.564706 0.501961
336 r 305 630 323 686 0.333333 0.341176 0.34902 0.501961
337 r 361 427 372 443 0.392157 0.266667 0.196078 0.501961
338 r 262 107 355 135 0.0313726 0.0470588 0.0352941 0.501961
339 r 210 713 230 719 0.00784314 0.0627451 0.0235294 0.501961
340 r 412 308 444 383 0.0117647 0.0235294 0.0196078 0.501961
341 r 339 46 374 110 0.101961 0.113725 0.0862745 0.501961
342 r 346 352 351 390 0.458824 0.313726 0.231373 0.501961
343 r 248 694 265 706 0.317647 0.286275 0.262745 0.501961
14 Appendix A: Source Code Listings 135

344 r 228 688 244 713 0.0509804 0.109804 0.0980392 0.501961


345 r 344 472 356 484 0.239216 0.113725 0.0705882 0.501961
346 r 150 352 181 387 0.0666667 0.0627451 0.0431373 0.501961
347 r 131 344 133 388 0.168627 0.196078 0.184314 0.501961
348 r 177 643 184 719 0.466667 0.231373 0.227451 0.501961
349 r 294 470 345 478 0.529412 0.352941 0.192157 0.501961
350 r 291 354 296 364 0.964706 0.843137 0.733333 0.501961
351 r 289 406 346 414 0.501961 0.239216 0.27451 0.501961
352 r 91 397 98 474 0.341176 0.345098 0.333333 0.501961
353 r 237 84 273 93 0 0.0156863 0.00392157 0.501961
354 r 436 447 459 485 0.117647 0.141176 0.156863 0.501961
355 r 293 242 306 251 0.470588 0.509804 0.329412 0.501961
356 r 98 0 152 116 0.172549 0.219608 0.211765 0.501961
357 r 117 648 139 691 0.435294 0.109804 0.109804 0.501961
358 r 242 416 260 429 0.462745 0.294118 0.180392 0.501961
359 r 183 681 193 719 0.298039 0.27451 0.266667 0.501961
360 r 266 429 279 432 0.294118 0.101961 0.121569 0.501961
361 r 439 679 532 699 0.160784 0.129412 0.145098 0.501961
362 r 47 594 53 638 0.356863 0.215686 0.211765 0.501961
363 r 258 655 273 669 0.0588235 0.0980392 0.109804 0.501961
364 r 239 186 285 196 0.454902 0.329412 0.223529 0.501961
365 r 193 708 206 719 0.403922 0.0862745 0.0823529 0.501961
366 r 123 524 131 575 0.290196 0.235294 0.258824 0.501961
367 r 87 154 110 193 0.168627 0.184314 0.180392 0.501961
368 r 346 394 356 407 0.203922 0.0862745 0.0588235 0.501961
369 r 224 397 238 410 0.490196 0.294118 0.164706 0.501961
370 r 282 373 292 381 0.709804 0.427451 0.258824 0.501961
371 r 243 712 257 719 0.521569 0.188235 0.188235 0.501961
372 r 384 481 412 497 0.0431373 0.054902 0.0627451 0.501961
373 r 281 630 297 645 0.0862745 0.109804 0.105882 0.501961
374 r 223 311 230 327 0.203922 0.172549 0.113725 0.501961
375 r 400 639 404 653 0.545098 0.0235294 0.0156863 0.501961
376 r 367 382 379 421 0.027451 0.0666667 0.0705882 0.501961
377 r 251 139 299 145 0.180392 0.14902 0.0784314 0.501961
378 r 307 296 329 310 0.396078 0.27451 0.219608 0.501961
379 r 162 277 219 285 0.145098 0.105882 0.0705882 0.501961
380 r 232 571 240 593 0.235294 0.172549 0.160784 0.501961
381 r 189 503 196 636 0.388235 0.321569 0.32549 0.501961
382 r 277 291 289 308 0.552941 0.298039 0.137255 0.501961
383 r 319 336 323 373 0.698039 0.494118 0.403922 0.501961
384 r 60 586 112 624 0.454902 0.109804 0.109804 0.501961
385 r 253 98 271 110 0.133333 0.156863 0.137255 0.501961
386 r 87 578 94 611 0.388235 0.2 0.192157 0.501961
14 Appendix A: Source Code Listings 136

387 r 198 376 208 386 0.360784 0.2 0.129412 0.501961


388 r 117 285 118 342 0.0901961 0.0862745 0.0627451 0.501961
389 r 291 268 312 296 0.34902 0.196078 0.117647 0.501961
390 r 482 525 497 571 0.133333 0.133333 0.156863 0.501961
391 r 381 230 457 285 0.0509804 0.0627451 0.0509804 0.501961
392 r 335 269 342 290 0.0941176 0.0588235 0.0235294 0.501961
393 r 287 424 303 434 0.698039 0.25098 0.317647 0.501961
394 r 385 379 398 420 0.168627 0.101961 0.0745098 0.501961
395 r 361 445 386 463 0.211765 0.137255 0.0980392 0.501961
396 r 282 309 300 320 0.552941 0.313726 0.172549 0.501961
397 r 172 90 216 156 0.0705882 0.0823529 0.0666667 0.501961
398 r 267 293 273 305 0.619608 0.505882 0.427451 0.501961
399 r 271 337 298 347 0.756863 0.427451 0.184314 0.501961
400 r 262 715 283 719 0.290196 0.301961 0.313726 0.501961
401 r 273 305 277 320 0.701961 0.564706 0.486275 0.501961
402 r 282 347 291 360 0.886275 0.572549 0.360784 0.501961
403 r 73 517 82 580 0.388235 0.117647 0.117647 0.501961
404 r 171 229 184 285 0.137255 0.145098 0.101961 0.501961
405 r 203 341 217 351 0.305882 0.172549 0.117647 0.501961
406 r 291 447 311 452 0.329412 0.219608 0.133333 0.501961
407 r 358 327 366 383 0.0588235 0.105882 0.109804 0.501961
408 r 239 604 256 625 0.262745 0.207843 0.2 0.501961
409 r 340 590 363 620 0.298039 0.321569 0.329412 0.501961
410 r 345 235 348 306 0.184314 0.203922 0.196078 0.501961
411 r 143 69 177 97 0.141176 0.192157 0.184314 0.501961
412 r 208 281 235 294 0.235294 0.137255 0.0784314 0.501961
413 r 203 335 224 339 0.541176 0.352941 0.290196 0.501961
414 r 147 389 160 411 0.333333 0.286275 0.262745 0.501961
415 r 218 318 223 321 0.694118 0.67451 0.654902 0.501961
416 r 250 637 266 651 0.329412 0.32549 0.333333 0.501961
417 r 224 679 231 688 0.368627 0.0392157 0.027451 0.501961
418 r 353 546 365 568 0.0784314 0.0980392 0.133333 0.501961
419 r 241 303 257 320 0.372549 0.223529 0.145098 0.501961
420 r 237 434 254 445 0.215686 0.152941 0.0784314 0.501961
421 r 318 511 368 532 0.329412 0.207843 0.133333 0.501961
422 r 189 184 213 199 0.368627 0.223529 0.117647 0.501961
423 r 321 286 332 293 0.372549 0.160784 0 0.501961
424 r 146 363 153 379 0.211765 0.172549 0.145098 0.501961
425 r 204 311 216 313 0.560784 0.388235 0.290196 0.501961
426 r 243 313 250 316 0.686275 0.443137 0.219608 0.501961
427 r 183 346 192 404 0.133333 0.2 0.184314 0.501961
428 r 299 433 319 443 0.721569 0.313726 0.364706 0.501961
429 r 208 545 220 592 0.168627 0.14902 0.156863 0.501961
14 Appendix A: Source Code Listings 137

430 r 220 621 227 635 0.0941176 0.117647 0.101961 0.501961


431 r 262 585 276 602 0.101961 0.113725 0.109804 0.501961
432 r 477 402 512 430 0.109804 0.141176 0.160784 0.501961
433 r 307 368 317 371 0.388235 0.196078 0.160784 0.501961
434 r 308 691 334 719 0.286275 0.282353 0.286275 0.501961
435 r 332 483 347 500 0.180392 0.105882 0.0784314 0.501961
436 r 333 198 354 217 0.0627451 0.109804 0.101961 0.501961
437 r 463 377 500 385 0.172549 0.196078 0.180392 0.501961
438 r 124 312 130 350 0.392157 0.380392 0.372549 0.501961
439 r 364 149 399 212 0.0470588 0.0588235 0.0431373 0.501961
440 r 361 214 366 248 0.341176 0.2 0.109804 0.501961
441 r 291 419 304 421 0.4 0.0470588 0.0705882 0.501961
442 r 137 378 147 395 0.403922 0.380392 0.352941 0.501961
443 r 134 680 147 719 0.341176 0.203922 0.192157 0.501961
444 r 97 192 113 233 0.133333 0.137255 0.12549 0.501961
445 r 104 308 108 366 0.278431 0.286275 0.286275 0.501961
446 r 163 360 172 408 0.0509804 0.0588235 0.0431373 0.501961
447 r 351 350 357 364 0.137255 0.196078 0.243137 0.501961
448 r 180 461 187 497 0.34902 0.32549 0.317647 0.501961
449 r 266 358 271 397 0.376471 0.309804 0.290196 0.501961
450 r 424 423 451 436 0.0117647 0.027451 0.0196078 0.501961
451 r 372 318 382 365 0.243137 0.129412 0.0823529 0.501961
452 r 208 602 215 616 0.12549 0.054902 0.0352941 0.501961
453 r 66 359 85 406 0.168627 0.188235 0.172549 0.501961
454 r 135 528 150 600 0.321569 0.109804 0.117647 0.501961
455 r 278 230 297 256 0.498039 0.443137 0.235294 0.501961
456 r 250 149 300 174 0.380392 0.231373 0.117647 0.501961
457 r 107 447 112 523 0.403922 0.270588 0.270588 0.501961
458 r 238 448 263 502 0.0784314 0.0784314 0.0588235 0.501961
459 r 224 346 244 356 0.560784 0.415686 0.313726 0.501961
460 r 313 268 333 270 0.486275 0.356863 0.270588 0.501961
461 r 66 505 103 523 0.301961 0.207843 0.203922 0.501961
462 r 310 244 324 253 0.196078 0.12549 0.0862745 0.501961
463 r 310 221 317 239 0.45098 0.443137 0.305882 0.501961
464 r 108 691 129 719 0.447059 0.133333 0.129412 0.501961
465 r 95 681 105 719 0.294118 0.12549 0.12549 0.501961
466 r 282 443 322 446 0.435294 0.258824 0.239216 0.501961
467 r 364 287 367 333 0.254902 0.2 0.184314 0.501961
468 r 438 106 467 223 0.105882 0.12549 0.0980392 0.501961
469 r 269 561 274 573 0.443137 0.411765 0.423529 0.501961
470 r 286 561 299 572 0.619608 0.392157 0.235294 0.501961
471 r 287 714 293 719 0.701961 0.0392157 0.0431373 0.501961
472 r 218 655 228 680 0.345098 0.258824 0.266667 0.501961
14 Appendix A: Source Code Listings 138

473 r 354 481 371 492 0.376471 0.239216 0.14902 0.501961


474 r 219 605 225 616 0.372549 0.207843 0.203922 0.501961
475 r 269 380 285 388 0.294118 0.192157 0.160784 0.501961
476 r 308 427 321 433 0.815686 0.482353 0.517647 0.501961
477 r 242 248 252 288 0.556863 0.4 0.2 0.501961
478 r 328 276 333 279 0.572549 0.560784 0.541176 0.501961
479 r 239 221 272 249 0.588235 0.486275 0.247059 0.501961
480 r 399 540 416 626 0.101961 0.101961 0.121569 0.501961
481 r 296 364 304 374 0.694118 0.372549 0.188235 0.501961
482 r 461 210 505 250 0.14902 0.168627 0.152941 0.501961
483 r 390 221 400 354 0.0784314 0.0901961 0.0784314 0.501961
484 r 297 199 329 207 0.443137 0.278431 0.133333 0.501961
485 r 145 117 191 180 0.0784314 0.0823529 0.0588235 0.501961
486 r 83 282 95 335 0.12549 0.113725 0.0901961 0.501961
487 r 281 570 286 578 0.294118 0.172549 0.113725 0.501961
488 r 269 91 290 97 0.145098 0.156863 0.145098 0.501961
489 r 165 281 186 309 0.129412 0.105882 0.0666667 0.501961
490 r 343 448 352 467 0.509804 0.309804 0.203922 0.501961
491 r 79 69 121 158 0.176471 0.223529 0.215686 0.501961
492 r 396 30 425 153 0.133333 0.156863 0.14902 0.501961
493 r 255 375 261 386 0.701961 0.564706 0.47451 0.501961
494 r 209 424 224 453 0.0392157 0.0509804 0.0392157 0.501961
495 r 268 415 293 427 0.521569 0.262745 0.317647 0.501961
496 r 163 417 166 476 0.372549 0.309804 0.305882 0.501961
497 r 230 536 283 546 0.109804 0.101961 0.0823529 0.501961
498 r 283 265 309 274 0.282353 0.180392 0.113725 0.501961
499 r 502 486 519 521 0.12549 0.12549 0.145098 0.501961
500 r 313 396 321 397 0.823529 0.572549 0.533333 0.501961
501 r 256 624 261 632 0.25098 0.121569 0.117647 0.501961

12_circle.cpp - 3157 bytes.

1 // Compile: clang++ -std=c++17 12_circle.cpp -o 12_circle


2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <random>
8 #include <cmath>
9
10 int get_index(int x, int y, int width)
11 {
14 Appendix A: Source Code Listings 139

12 return x+width*y;
13 }
14
15 int calc_size(int width, int height)
16 {
17 return width*height;
18 }
19
20 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
21 height)
22 {
23 for (int y=0;y<height;++y) {
24 for (int x=0;x<width;++x) {
25 image[get_index(x,y,width)]=std::make_tuple(1.0f, 1.0f, 1.0f);
26 }
27 }
28 }
29
30 void draw_circle(int x, int y, int radius, std::vector<std::tuple<float, float, floa\
31 t>> &image, std::tuple<float, float, float> &color, int width, int height)
32 {
33 int x0 = 0;
34 int y0 = radius;
35 int d = 3 - 2 * radius;
36 int xx=0;
37 int yy=0;
38 unsigned char mask=255;
39 if (!radius) return;
40
41 while (y0 >= x0)
42 {
43 if (mask & 0x01) {xx=x + x0;yy=y - y0;image[get_index(xx, yy, width)]=color;}
44 if (mask & 0x02) {xx=x + y0;yy=y - x0;image[get_index(xx, yy, width)]=color;}
45 if (mask & 0x04) {xx=x + y0;yy=y + x0;image[get_index(xx, yy, width)]=color;}
46 if (mask & 0x08) {xx=x + x0;yy=y + y0;image[get_index(xx, yy, width)]=color;}
47 if (mask & 0x10) {xx=x - x0;yy=y + y0;image[get_index(xx, yy, width)]=color;}
48 if (mask & 0x20) {xx=x - y0;yy=y + x0;image[get_index(xx, yy, width)]=color;}
49 if (mask & 0x40) {xx=x - y0;yy=y - x0;image[get_index(xx, yy, width)]=color;}
50 if (mask & 0x80) {xx=x - x0;yy=y - y0;image[get_index(xx, yy, width)]=color;}
51 if (d < 0) d += 4 * x0++ + 6;
52 else d += 4 * (x0++ - y0--) + 10;
53 }
54 }
14 Appendix A: Source Code Listings 140

55
56 void draw_filled_circle(int x, int y, int radius, std::vector<std::tuple<float, floa\
57 t, float>> &image, std::tuple<float, float, float> &color, int width, int height)
58 {
59 int x0 = 0;
60 int y0 = radius;
61 int d = 3 - 2 * radius;
62 if (!radius) return;
63
64 auto drawline = [&](int sx, int ex, int ny)
65 {
66 for (int i = sx; i <= ex; i++)
67 image[get_index(i, ny, width)]=color;
68 };
69
70 while (y0 >= x0)
71 {
72 drawline(x - x0, x + x0, y - y0);
73 drawline(x - y0, x + y0, y - x0);
74 drawline(x - x0, x + x0, y + y0);
75 drawline(x - y0, x + y0, y + x0);
76 if (d < 0) d += 4 * x0++ + 6;
77 else d += 4 * (x0++ - y0--) + 10;
78 }
79 }
80
81 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
82 height, std::string filename)
83 {
84 std::tuple<float, float, float> color;
85 std::ofstream out(filename, std::ofstream::out);
86 out << "P3\n" << width << " " << height << "\n255\n";
87 for (int i=0;i<(width*height);++i)
88 {
89 color=image[i];
90 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
91 " " << int(std::get<2>(color)*255.0f) << '\n';
92 }
93 out.close();
94 }
95
96 int main()
97 {
14 Appendix A: Source Code Listings 141

98 int width=640;
99 int height=360;
100 int x1=0,y=0,r=0,x2=0;
101
102 r=((height/2)*0.8)/2;
103 y=height/2;
104 x1=((width-(((height/2)*0.8)*3))/2)+r;
105 x2=width-x1;
106
107 std::vector<std::tuple<float, float, float>> image;
108 std::tuple<float,float,float> color=std::make_tuple(0.0f,0.0f,0.0f);
109
110 image.resize(calc_size(width, height));
111 clear_image(image,width,height);
112
113 draw_circle(x1,y,r,image,color,width,height);
114 draw_filled_circle(x2,y,r,image,color,width,height);
115
116 save_image(image,width,height,"12_circle.ppm");
117
118 return 0;
119 }

12_circles_from_file.cpp - 6998 bytes.

1 // Compile: clang++ -std=c++17 12_circles_from_file.cpp -o 12_circles_from_file


2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <random>
8 #include <cmath>
9 #include <algorithm>
10
11 bool startsWithCaseInsensitive(std::string mainStr, std::string toMatch)
12 {
13 // Convert mainStr to lower case
14 std::transform(mainStr.begin(), mainStr.end(), mainStr.begin(), ::tolower);
15 // Convert toMatch to lower case
16 std::transform(toMatch.begin(), toMatch.end(), toMatch.begin(), ::tolower);
17 if(mainStr.find(toMatch) == 0)
18 return true;
14 Appendix A: Source Code Listings 142

19 else
20 return false;
21 }
22
23 int get_index(int x, int y, int width)
24 {
25 return x+width*y;
26 }
27
28 int calc_size(int width, int height)
29 {
30 return width*height;
31 }
32
33 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
34 at,float,float> &color, int width, int height)
35 {
36 for (int y=0;y<height;++y) {
37 for (int x=0;x<width;++x) {
38 image[get_index(x,y,width)]=color;
39 }
40 }
41 }
42
43 std::tuple<int,int,int,float,float,float,float> parse_circle_line(const std::string \
44 str)
45 {
46 size_t start;
47 size_t end = 0;
48 std::vector<std::string> out;
49
50 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
51 {
52 end = str.find(' ', start);
53 out.push_back(str.substr(start, end - start));
54 }
55
56 int dx=stoi(out[1]);
57 int dy=stoi(out[2]);
58 int r=stoi(out[3]);
59 float rf=stof(out[4]);
60 float gf=stof(out[5]);
61 float bf=stof(out[6]);
14 Appendix A: Source Code Listings 143

62 float af=stof(out[7]);
63
64 return std::make_tuple(dx,dy,r,rf,gf,bf,af);
65 }
66
67 std::tuple<int,int,float,float,float> parse_bginfo_line(const std::string str, int &\
68 width, int &height)
69 {
70 size_t start;
71 size_t end = 0;
72 std::vector<std::string> out;
73
74 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
75 {
76 end = str.find(' ', start);
77 out.push_back(str.substr(start, end - start));
78 }
79
80 width=stoi(out[1]);
81 height=stoi(out[2]);
82 float rf=stof(out[3]);
83 float gf=stof(out[4]);
84 float bf=stof(out[5]);
85
86 return std::make_tuple(width,height,rf,gf,bf);
87 }
88
89 std::tuple<float,float,float> blend_colors(std::tuple<float,float,float> &colorBGRGB\
90 , std::tuple<float,float,float,float> &colorRGBA)
91 {
92 float r=0.0f; float g=0.0f; float b=0.0f;
93 r = (std::get<0>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<0>(colorBGRGB) * \
94 (1.0 - std::get<3>(colorRGBA)));
95 g = (std::get<1>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<1>(colorBGRGB) * \
96 (1.0 - std::get<3>(colorRGBA)));
97 b = (std::get<2>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<2>(colorBGRGB) * \
98 (1.0 - std::get<3>(colorRGBA)));
99
100 return std::make_tuple(r,g,b);
101 }
102
103 int find_region(int x, int y, int width, int height)
104 {
14 Appendix A: Source Code Listings 144

105 int code=0;


106 if(y >= height)
107 code |= 1; //top
108 else if(y < 0)
109 code |= 2; //bottom
110 if(x >= width)
111 code |= 4; //right
112 else if (x < 0)
113 code |= 8; //left
114 return(code);
115 }
116
117 bool clip_line(std::tuple<int, int, int, int> &coords1, std::tuple<int, int, int, in\
118 t> &coords2, int width, int height)
119 {
120 int x1=std::get<0>(coords1); int y1=std::get<1>(coords1); int x2=std::get<2>(coords\
121 1); int y2=std::get<3>(coords1);
122 int x3=0; int y3=0; int x4=0; int y4=0;
123 int code1=0, code2=0, codeout=0;
124 bool accept = 0, done=0;
125 code1 = find_region(x1, y1, width, height); //the region outcodes for the endpoints
126 code2 = find_region(x2, y2, width, height);
127 do //In theory, this can never end up in an infinite loop, it'll always come in one\
128 of the trivial cases eventually
129 {
130 if(!(code1 | code2)) accept = done = 1; //accept because both endpoints are in sc\
131 reen or on the border, trivial accept
132 else if(code1 & code2) done = 1; //the line isn't visible on screen, trivial reject
133 else //if no trivial reject or accept, continue the loop
134 {
135 int x, y;
136 codeout = code1 ? code1 : code2;
137 if(codeout & 1) //top
138 {
139 x = x1 + (x2 - x1) * (height - y1) / (y2 - y1);
140 y = height - 1;
141 }
142 else if(codeout & 2) //bottom
143 {
144 x = x1 + (x2 - x1) * -y1 / (y2 - y1);
145 y = 0;
146 }
147 else if(codeout & 4) //right
14 Appendix A: Source Code Listings 145

148 {
149 y = y1 + (y2 - y1) * (width - x1) / (x2 - x1);
150 x = width - 1;
151 }
152 else //left
153 {
154 y = y1 + (y2 - y1) * -x1 / (x2 - x1);
155 x = 0;
156 }
157 if(codeout == code1) //first endpoint was clipped
158 {
159 x1 = x; y1 = y;
160 code1 = find_region(x1, y1, width, height);
161 }
162 else //second endpoint was clipped
163 {
164 x2 = x; y2 = y;
165 code2 = find_region(x2, y2, width, height);
166 }
167 }
168 }
169 while(done == 0);
170 if(accept)
171 {
172 x3 = x1;
173 x4 = x2;
174 y3 = y1;
175 y4 = y2;
176 coords2=std::make_tuple(x3,y3,x4,y4);
177 return 1;
178 }
179 else
180 {
181 x3 = x4 = y3 = y4 = 0;
182 coords2=std::make_tuple(x3,y3,x4,y4);
183 return 0;
184 }
185 }
186
187 void draw_filled_circle(int x, int y, int radius, std::vector<std::tuple<float, floa\
188 t, float>> &image, std::tuple<float, float, float, float> &colorRGBA, int width, int
189 height)
190 {
14 Appendix A: Source Code Listings 146

191 int x0 = 0;
192 int y0 = radius;
193 int d = 3 - 2 * radius;
194 std::tuple<int, int, int, int> coords1;
195 std::tuple<int, int, int, int> coords2;
196 if (!radius) return;
197
198 auto drawline = [&](int sx, int ex, int ny)
199 {
200 coords1=std::make_tuple(sx,ny,ex,ny);
201 if (clip_line(coords1,coords2,width,height)) {
202 sx=std::get<0>(coords2);
203 ny=std::get<1>(coords2);
204 ex=std::get<2>(coords2);
205 for (int i = sx; i <= ex; i++) {
206 image[get_index(i, ny, width)]=blend_colors(image[get_index(i, ny, w
207 RGBA);
208 }
209 }
210 };
211
212 while (y0 >= x0)
213 {
214 drawline(x - x0, x + x0, y - y0);
215 drawline(x - y0, x + y0, y - x0);
216 drawline(x - x0, x + x0, y + y0);
217 drawline(x - y0, x + y0, y + x0);
218 if (d < 0) d += 4 * x0++ + 6;
219 else d += 4 * (x0++ - y0--) + 10;
220 }
221 }
222
223 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
224 height, std::string filename)
225 {
226 std::tuple<float, float, float> color;
227 std::ofstream out(filename, std::ofstream::out);
228 out << "P3\n" << width << " " << height << "\n255\n";
229 for (int i=0;i<(width*height);++i)
230 {
231 color=image[i];
232 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
233 " " << int(std::get<2>(color)*255.0f) << '\n';
14 Appendix A: Source Code Listings 147

234 }
235 out.close();
236 }
237
238 int main()
239 {
240 std::ifstream infile("12_squint_with_your_eyes.txt");
241 std::string line;
242 std::tuple<int,int,int,float,float,float,float> circle;
243 std::tuple<int,int,float,float,float> bginfo;
244 std::tuple<float,float,float> colorBGRGB;
245 std::tuple<float,float,float,float> colorRGBA;
246 int width,height,xx,yy,r;
247 float rf,gf,bf,af;
248 float bg_rf,bg_gf,bg_bf;
249 std::vector<std::tuple<float, float, float>> image;
250 while (getline(infile, line))
251 {
252 if (startsWithCaseInsensitive(line,"c")) {
253 circle=parse_circle_line(line);
254 std::tie(xx,yy,r,rf,gf,bf,af) = circle;
255 colorRGBA=std::make_tuple(rf,gf,bf,af);
256 draw_filled_circle(xx,yy,r,image,colorRGBA,width,height);
257 }
258 if (startsWithCaseInsensitive(line,"b")) {
259 bginfo=parse_bginfo_line(line,width,height);
260 std::tie(width,height,bg_rf,bg_gf,bg_bf) = bginfo;
261 image.resize(calc_size(width, height));
262 colorBGRGB=std::make_tuple(bg_rf,bg_gf,bg_bf);
263 clear_image(image,colorBGRGB,width,height);
264 }
265 }
266 infile.close();
267
268 save_image(image,width,height,"12_squint_with_your_eyes.ppm");
269
270 return 0;
271 }
14 Appendix A: Source Code Listings 148

12_squint_with_your_eyes.txt - 23606 bytes.


1 b 960 720 0.329412 0.337255 0.337255
2 c 430 320 257 0.843137 0.772549 0.733333 0.501961
3 c 731 359 228 0.0588235 0.0941176 0.129412 0.501961
4 c 414 636 118 0.85098 0.858824 0.803922 0.501961
5 c 307 101 119 0.886275 0.843137 0.721569 0.501961
6 c 122 238 122 0 0.0666667 0.145098 0.501961
7 c 237 477 101 0.196078 0.192157 0.133333 0.501961
8 c 279 284 88 0.847059 0.866667 0.807843 0.501961
9 c 549 256 189 0.623529 0.552941 0.537255 0.501961
10 c 433 325 54 1 1 1 0.501961
11 c 602 702 34 0.87451 1 1 0.501961
12 c 227 366 68 0.439216 0.47451 0.419608 0.501961
13 c 359 400 55 0.921569 0.87451 0.827451 0.501961
14 c 379 233 47 0.176471 0.211765 0.243137 0.501961
15 c 88 582 88 0 0 0.054902 0.501961
16 c 604 120 128 0.376471 0.298039 0.247059 0.501961
17 c 187 609 27 0.898039 0.984314 0.941176 0.501961
18 c 528 511 105 0.596078 0.498039 0.486275 0.501961
19 c 279 602 58 0.184314 0.0784314 0 0.501961
20 c 398 539 68 0.866667 0.878431 0.811765 0.501961
21 c 757 650 32 0.576471 0.74902 0.835294 0.501961
22 c 328 695 34 0.952941 1 1 0.501961
23 c 297 476 40 0.0941176 0 0 0.501961
24 c 348 143 67 0.937255 0.94902 0.964706 0.501961
25 c 329 299 55 0.941176 0.94902 0.956863 0.501961
26 c 207 155 71 0.396078 0.415686 0.356863 0.501961
27 c 217 486 37 0.670588 0.713726 0.654902 0.501961
28 c 409 28 52 0.243137 0.109804 0 0.501961
29 c 492 471 40 0.360784 0.105882 0.152941 0.501961
30 c 438 413 28 0.972549 0.980392 0.980392 0.501961
31 c 204 552 36 0.592157 0.615686 0.568627 0.501961
32 c 136 465 55 0 0.0666667 0.160784 0.501961
33 c 572 243 32 0.0509804 0.117647 0.188235 0.501961
34 c 714 359 39 0.101961 0.0901961 0.0588235 0.501961
35 c 845 500 113 0 0.0666667 0.145098 0.501961
36 c 83 110 83 0 0.105882 0.168627 0.501961
37 c 820 685 55 0 0 0 0.501961
38 c 645 566 13 0.847059 1 1 0.501961
39 c 290 427 25 0.0745098 0 0 0.501961
40 c 621 430 41 0.639216 0.603922 0.611765 0.501961
41 c 344 44 25 0.337255 0.203922 0.0745098 0.501961
42 c 329 234 15 0.160784 0.0509804 0.0431373 0.501961
14 Appendix A: Source Code Listings 149

43 c 358 457 26 0.921569 0.937255 0.87451 0.501961


44 c 230 359 64 0.486275 0.501961 0.454902 0.501961
45 c 704 38 76 0.152941 0.113725 0.0470588 0.501961
46 c 691 535 46 0.0980392 0.00784314 0 0.501961
47 c 218 29 32 0.768627 0.803922 0.705882 0.501961
48 c 366 209 28 0.341176 0.266667 0.223529 0.501961
49 c 142 695 27 0 0 0 0.501961
50 c 317 669 23 0.8 1 1 0.501961
51 c 625 686 15 0.709804 0.909804 0.988235 0.501961
52 c 447 332 32 0.984314 1 1 0.501961
53 c 459 274 22 0.898039 0.956863 0.94902 0.501961
54 c 401 373 33 0.6 0.521569 0.498039 0.501961
55 c 239 684 39 0.235294 0.141176 0 0.501961
56 c 296 211 29 0.956863 0.937255 0.913725 0.501961
57 c 188 704 16 0.866667 0.776471 0.54902 0.501961
58 c 695 673 49 0.231373 0.141176 0.0352941 0.501961
59 c 282 379 16 0.223529 0.0980392 0 0.501961
60 c 744 613 16 0.490196 0.662745 0.764706 0.501961
61 c 271 90 21 0.32549 0.294118 0.196078 0.501961
62 c 406 686 41 0.447059 0.419608 0.388235 0.501961
63 c 274 538 46 0.215686 0.121569 0.0352941 0.501961
64 c 188 632 15 0.929412 0.964706 0.901961 0.501961
65 c 565 29 58 0.219608 0.133333 0.0470588 0.501961
66 c 753 677 24 0.435294 0.552941 0.611765 0.501961
67 c 688 465 40 0.156863 0.0666667 0 0.501961
68 c 681 611 41 0.168627 0.0627451 0 0.501961
69 c 658 185 45 0.537255 0.521569 0.533333 0.501961
70 c 399 130 62 0.827451 0.819608 0.811765 0.501961
71 c 254 464 18 0.811765 0.729412 0.54902 0.501961
72 c 212 617 20 0.364706 0.239216 0.0980392 0.501961
73 c 338 702 33 0.85098 1 1 0.501961
74 c 168 71 31 0.384314 0.431373 0.415686 0.501961
75 c 505 310 35 0.501961 0.411765 0.392157 0.501961
76 c 307 64 19 0.407843 0.278431 0.14902 0.501961
77 c 298 265 28 0.988235 0.988235 0.968627 0.501961
78 c 529 619 78 0.494118 0.466667 0.423529 0.501961
79 c 582 709 19 0.858824 1 1 0.501961
80 c 573 510 46 0.588235 0.588235 0.576471 0.501961
81 c 751 209 57 0.309804 0.27451 0.239216 0.501961
82 c 233 151 26 0.337255 0.27451 0.180392 0.501961
83 c 362 682 16 0.286275 0.258824 0.243137 0.501961
84 c 387 240 17 0 0.0784314 0.141176 0.501961
85 c 152 622 25 0.207843 0.321569 0.364706 0.501961
14 Appendix A: Source Code Listings 150

86 c 71 597 71 0 0.101961 0.168627 0.501961


87 c 212 574 17 0.819608 0.776471 0.627451 0.501961
88 c 364 280 16 0.403922 0.403922 0.423529 0.501961
89 c 874 142 85 0 0.0627451 0.137255 0.501961
90 c 210 312 35 0.596078 0.647059 0.603922 0.501961
91 c 186 605 12 0.996078 1 1 0.501961
92 c 181 553 25 0.164706 0.258824 0.309804 0.501961
93 c 614 635 32 0.207843 0.129412 0.0627451 0.501961
94 c 448 451 12 0.301961 0.0117647 0.0313726 0.501961
95 c 767 638 22 0.466667 0.611765 0.682353 0.501961
96 c 335 17 35 0.803922 0.717647 0.560784 0.501961
97 c 203 431 23 0.482353 0.564706 0.572549 0.501961
98 c 316 370 22 0.921569 0.890196 0.839216 0.501961
99 c 266 21 16 0.458824 0.313726 0.0901961 0.501961
100 c 333 143 39 0.952941 0.956863 0.945098 0.501961
101 c 314 534 27 0.34902 0.294118 0.215686 0.501961
102 c 341 644 18 0.396078 0.341176 0.282353 0.501961
103 c 632 336 52 0.623529 0.54902 0.545098 0.501961
104 c 351 246 10 0.768627 1 1 0.501961
105 c 221 73 29 0.745098 0.756863 0.619608 0.501961
106 c 251 202 24 0.533333 0.490196 0.392157 0.501961
107 c 433 64 20 0.717647 0.647059 0.564706 0.501961
108 c 641 667 14 0.533333 0.607843 0.619608 0.501961
109 c 297 465 34 0.203922 0.0980392 0 0.501961
110 c 443 473 18 0.839216 0.627451 0.682353 0.501961
111 c 398 586 67 0.72549 0.721569 0.666667 0.501961
112 c 190 244 29 0.25098 0.329412 0.341176 0.501961
113 c 482 88 44 0.6 0.521569 0.454902 0.501961
114 c 741 322 38 0.239216 0.254902 0.254902 0.501961
115 c 605 244 13 0.411765 0.690196 0.866667 0.501961
116 c 649 514 33 0.0588235 0.0745098 0.0745098 0.501961
117 c 256 354 34 0.415686 0.403922 0.341176 0.501961
118 c 703 400 33 0.188235 0.129412 0.0705882 0.501961
119 c 200 652 20 0.619608 0.533333 0.34902 0.501961
120 c 829 686 65 0 0 0 0.501961
121 c 339 436 19 0.894118 0.894118 0.85098 0.501961
122 c 592 225 18 0.0588235 0.0862745 0.141176 0.501961
123 c 646 125 51 0.47451 0.427451 0.4 0.501961
124 c 712 491 31 0.282353 0.266667 0.223529 0.501961
125 c 573 683 22 0.403922 0.34902 0.290196 0.501961
126 c 312 295 29 0.980392 0.992157 0.972549 0.501961
127 c 458 361 19 0.988235 0.996078 0.992157 0.501961
128 c 190 589 10 0.909804 1 1 0.501961
14 Appendix A: Source Code Listings 151

129 c 464 562 19 0.435294 0.431373 0.419608 0.501961


130 c 205 105 27 0.560784 0.54902 0.443137 0.501961
131 c 447 24 30 0.211765 0.133333 0.0627451 0.501961
132 c 451 495 17 0.47451 0.360784 0.337255 0.501961
133 c 356 492 17 0.901961 0.905882 0.839216 0.501961
134 c 492 395 19 0.423529 0.32549 0.341176 0.501961
135 c 285 40 23 0.823529 0.705882 0.490196 0.501961
136 c 538 698 28 0.470588 0.415686 0.356863 0.501961
137 c 51 694 38 0.00392157 0.0117647 0.0313726 0.501961
138 c 317 651 14 0.721569 0.839216 0.901961 0.501961
139 c 377 322 38 0.721569 0.721569 0.717647 0.501961
140 c 324 411 16 0.92549 0.921569 0.87451 0.501961
141 c 599 705 19 0.717647 0.917647 1 0.501961
142 c 163 585 18 0.239216 0.329412 0.356863 0.501961
143 c 238 491 11 0.901961 0.835294 0.658824 0.501961
144 c 415 453 7 0.180392 0 0.00784314 0.501961
145 c 672 262 37 0.580392 0.552941 0.54902 0.501961
146 c 695 355 16 0.0705882 0.027451 0 0.501961
147 c 731 598 10 0.458824 0.596078 0.682353 0.501961
148 c 171 305 26 0.341176 0.411765 0.407843 0.501961
149 c 71 340 71 0 0.101961 0.168627 0.501961
150 c 197 355 16 0.647059 0.678431 0.619608 0.501961
151 c 285 692 20 0.466667 0.435294 0.309804 0.501961
152 c 728 230 37 0.392157 0.333333 0.305882 0.501961
153 c 221 548 11 0.8 0.741176 0.607843 0.501961
154 c 473 527 16 0.772549 0.768627 0.772549 0.501961
155 c 314 242 11 0.505882 0.447059 0.407843 0.501961
156 c 345 197 21 0.658824 0.615686 0.576471 0.501961
157 c 344 75 18 0.682353 0.619608 0.552941 0.501961
158 c 785 342 82 0.184314 0.227451 0.247059 0.501961
159 c 534 455 12 0.258824 0.054902 0.0901961 0.501961
160 c 185 621 11 0.917647 1 1 0.501961
161 c 160 133 35 0.262745 0.337255 0.372549 0.501961
162 c 249 646 27 0.192157 0.121569 0.0431373 0.501961
163 c 643 709 20 0.25098 0.231373 0.180392 0.501961
164 c 359 39 19 0.337255 0.262745 0.176471 0.501961
165 c 260 267 12 0.568627 0.458824 0.321569 0.501961
166 c 348 665 10 0.282353 0.239216 0.211765 0.501961
167 c 287 400 16 0.301961 0.192157 0.0823529 0.501961
168 c 349 228 9 0.0117647 0.00784314 0.0470588 0.501961
169 c 247 398 18 0.619608 0.631373 0.588235 0.501961
170 c 490 165 51 0.592157 0.537255 0.509804 0.501961
171 c 516 224 36 0.454902 0.431373 0.45098 0.501961
14 Appendix A: Source Code Listings 152

172 c 492 7 11 0.768627 0.662745 0.486275 0.501961


173 c 387 654 33 0.631373 0.623529 0.568627 0.501961
174 c 150 189 43 0.145098 0.219608 0.258824 0.501961
175 c 149 629 27 0.227451 0.290196 0.321569 0.501961
176 c 406 266 25 0.392157 0.415686 0.439216 0.501961
177 c 751 106 60 0.294118 0.258824 0.196078 0.501961
178 c 212 408 11 0.705882 0.768627 0.729412 0.501961
179 c 215 445 31 0.34902 0.4 0.4 0.501961
180 c 333 698 24 0.847059 0.992157 1 0.501961
181 c 327 51 15 0.321569 0.215686 0.133333 0.501961
182 c 365 532 29 0.831373 0.831373 0.764706 0.501961
183 c 326 613 19 0.298039 0.247059 0.203922 0.501961
184 c 138 702 23 0 0 0 0.501961
185 c 230 366 26 0.298039 0.4 0.443137 0.501961
186 c 134 20 40 0.054902 0.137255 0.196078 0.501961
187 c 651 578 8 0.6 0.686275 0.72549 0.501961
188 c 556 270 25 0.364706 0.309804 0.305882 0.501961
189 c 288 157 25 0.819608 0.796078 0.745098 0.501961
190 c 462 678 26 0.494118 0.47451 0.435294 0.501961
191 c 271 316 15 0.654902 0.572549 0.439216 0.501961
192 c 379 703 11 0.258824 0.235294 0.219608 0.501961
193 c 376 203 20 0.462745 0.388235 0.337255 0.501961
194 c 297 439 22 0.145098 0.0588235 0 0.501961
195 c 283 245 16 0.976471 0.964706 0.937255 0.501961
196 c 88 493 88 0.0470588 0.145098 0.207843 0.501961
197 c 719 628 18 0.141176 0.0823529 0.0196078 0.501961
198 c 639 610 29 0.137255 0.0784314 0.0313726 0.501961
199 c 499 454 15 0.282353 0.121569 0.133333 0.501961
200 c 878 93 80 0.0352941 0.121569 0.172549 0.501961
201 c 427 418 30 0.788235 0.784314 0.776471 0.501961
202 c 367 239 5 0.729412 1 1 0.501961
203 c 727 703 20 0.0980392 0.0627451 0.0156863 0.501961
204 c 615 470 22 0.568627 0.54902 0.552941 0.501961
205 c 675 538 24 0.0509804 0 0 0.501961
206 c 426 471 13 0.847059 0.784314 0.807843 0.501961
207 c 192 517 24 0.333333 0.403922 0.427451 0.501961
208 c 627 229 14 0.168627 0.188235 0.254902 0.501961
209 c 645 561 12 0.572549 0.721569 0.807843 0.501961
210 c 432 452 7 0.356863 0.0509804 0.0627451 0.501961
211 c 205 603 12 0.380392 0.329412 0.215686 0.501961
212 c 199 157 20 0.423529 0.447059 0.423529 0.501961
213 c 683 430 18 0.0627451 0.00392157 0 0.501961
214 c 503 25 16 0.313726 0.2 0.0784314 0.501961
14 Appendix A: Source Code Listings 153

215 c 253 42 15 0.541176 0.466667 0.27451 0.501961


216 c 274 451 15 0.462745 0.32549 0.203922 0.501961
217 c 288 77 11 0.352941 0.278431 0.172549 0.501961
218 c 520 624 49 0.501961 0.486275 0.458824 0.501961
219 c 402 454 9 0.337255 0.247059 0.215686 0.501961
220 c 458 389 7 0.407843 0.176471 0.141176 0.501961
221 c 452 312 23 0.929412 0.956863 0.952941 0.501961
222 c 566 715 8 0.862745 1 1 0.501961
223 c 158 346 23 0.14902 0.235294 0.282353 0.501961
224 c 722 174 27 0.243137 0.235294 0.203922 0.501961
225 c 365 712 13 0.772549 0.952941 1 0.501961
226 c 261 64 12 0.843137 0.792157 0.619608 0.501961
227 c 594 675 16 0.286275 0.243137 0.196078 0.501961
228 c 267 611 12 0.498039 0.431373 0.317647 0.501961
229 c 881 580 78 0.027451 0.12549 0.180392 0.501961
230 c 284 363 10 0.27451 0.188235 0.0862745 0.501961
231 c 708 585 20 0.32549 0.266667 0.176471 0.501961
232 c 320 668 15 0.843137 0.972549 1 0.501961
233 c 463 473 10 0.764706 0.572549 0.627451 0.501961
234 c 321 82 14 0.694118 0.631373 0.556863 0.501961
235 c 612 239 9 0.556863 0.745098 0.854902 0.501961
236 c 558 454 9 0.258824 0.101961 0.133333 0.501961
237 c 657 657 20 0.34902 0.333333 0.27451 0.501961
238 c 403 28 16 0.270588 0.188235 0.109804 0.501961
239 c 438 189 22 0.701961 0.67451 0.658824 0.501961
240 c 226 506 12 0.733333 0.686275 0.545098 0.501961
241 c 583 244 7 0 0 0 0.501961
242 c 635 538 20 0.176471 0.223529 0.243137 0.501961
243 c 275 569 20 0.0901961 0.0431373 0.0196078 0.501961
244 c 522 494 25 0.470588 0.376471 0.388235 0.501961
245 c 653 399 21 0.54902 0.513726 0.52549 0.501961
246 c 257 370 18 0.6 0.580392 0.494118 0.501961
247 c 390 382 36 0.670588 0.596078 0.576471 0.501961
248 c 652 212 21 0.552941 0.533333 0.572549 0.501961
249 c 514 299 36 0.505882 0.447059 0.435294 0.501961
250 c 800 198 41 0.160784 0.2 0.223529 0.501961
251 c 206 705 14 0.403922 0.32549 0.207843 0.501961
252 c 736 31 62 0.172549 0.152941 0.121569 0.501961
253 c 238 569 19 0.380392 0.313726 0.215686 0.501961
254 c 362 12 22 0.647059 0.576471 0.458824 0.501961
255 c 261 502 15 0.168627 0.101961 0.0313726 0.501961
256 c 400 59 15 0.678431 0.631373 0.596078 0.501961
257 c 193 677 10 0.231373 0.164706 0.0235294 0.501961
14 Appendix A: Source Code Listings 154

258 c 417 247 18 0.356863 0.313726 0.301961 0.501961


259 c 619 175 14 0.337255 0.27451 0.247059 0.501961
260 c 314 172 16 0.988235 0.988235 0.980392 0.501961
261 c 612 668 11 0.180392 0.137255 0.0941176 0.501961
262 c 324 473 16 0.145098 0.121569 0.0862745 0.501961
263 c 673 490 21 0.0745098 0.0235294 0 0.501961
264 c 186 598 10 0.890196 1 1 0.501961
265 c 325 563 14 0.501961 0.423529 0.317647 0.501961
266 c 366 227 9 0.0470588 0.101961 0.160784 0.501961
267 c 744 287 36 0.329412 0.298039 0.27451 0.501961
268 c 616 690 12 0.654902 0.8 0.862745 0.501961
269 c 375 252 12 0.0392157 0.196078 0.290196 0.501961
270 c 247 240 12 0.870588 0.835294 0.780392 0.501961
271 c 583 327 43 0.529412 0.431373 0.403922 0.501961
272 c 895 707 23 0 0 0.00392157 0.501961
273 c 420 223 17 0.517647 0.443137 0.396078 0.501961
274 c 307 340 19 0.929412 0.898039 0.835294 0.501961
275 c 415 127 25 0.729412 0.701961 0.678431 0.501961
276 c 107 697 14 0.176471 0.305882 0.384314 0.501961
277 c 199 316 15 0.654902 0.67451 0.627451 0.501961
278 c 438 92 24 0.721569 0.690196 0.666667 0.501961
279 c 457 415 16 0.843137 0.827451 0.823529 0.501961
280 c 174 573 15 0.290196 0.337255 0.34902 0.501961
281 c 438 279 18 0.709804 0.760784 0.772549 0.501961
282 c 623 578 18 0.227451 0.180392 0.137255 0.501961
283 c 291 102 12 0.72549 0.72549 0.666667 0.501961
284 c 315 391 15 0.854902 0.85098 0.8 0.501961
285 c 308 22 24 0.768627 0.682353 0.521569 0.501961
286 c 344 255 15 0.701961 0.784314 0.847059 0.501961
287 c 228 68 13 0.823529 0.839216 0.733333 0.501961
288 c 232 154 16 0.290196 0.235294 0.164706 0.501961
289 c 678 581 21 0.101961 0.0470588 0 0.501961
290 c 226 404 6 0.65098 0.827451 0.870588 0.501961
291 c 260 122 19 0.454902 0.462745 0.419608 0.501961
292 c 387 523 38 0.796078 0.792157 0.745098 0.501961
293 c 228 220 19 0.552941 0.556863 0.509804 0.501961
294 c 465 275 10 0.945098 0.964706 0.960784 0.501961
295 c 491 561 14 0.376471 0.34902 0.352941 0.501961
296 c 900 304 59 0.0431373 0.137255 0.188235 0.501961
297 c 182 17 21 0.360784 0.447059 0.45098 0.501961
298 c 285 667 15 0.32549 0.27451 0.184314 0.501961
299 c 337 232 12 0.215686 0.168627 0.160784 0.501961
300 c 388 713 8 0.254902 0.207843 0.192157 0.501961
14 Appendix A: Source Code Listings 155

301 c 347 450 18 0.839216 0.827451 0.792157 0.501961


302 c 753 704 9 0.392157 0.454902 0.47451 0.501961
303 c 525 340 39 0.537255 0.466667 0.470588 0.501961
304 c 601 270 14 0.317647 0.32549 0.372549 0.501961
305 c 133 419 51 0.0784314 0.156863 0.207843 0.501961
306 c 442 373 11 0.913725 0.87451 0.831373 0.501961
307 c 700 298 18 0.501961 0.478431 0.447059 0.501961
308 c 690 382 15 0.113725 0.0745098 0.0352941 0.501961
309 c 609 21 37 0.258824 0.211765 0.152941 0.501961
310 c 284 519 18 0.368627 0.309804 0.223529 0.501961
311 c 213 565 13 0.733333 0.717647 0.623529 0.501961
312 c 554 102 60 0.462745 0.384314 0.337255 0.501961
313 c 619 413 48 0.552941 0.513726 0.517647 0.501961
314 c 347 269 8 0.501961 0.513726 0.533333 0.501961
315 c 255 448 9 0.709804 0.666667 0.545098 0.501961
316 c 568 692 17 0.407843 0.384314 0.34902 0.501961
317 c 231 443 14 0.243137 0.278431 0.27451 0.501961
318 c 199 279 18 0.45098 0.501961 0.482353 0.501961
319 c 184 701 8 0.803922 0.811765 0.705882 0.501961
320 c 331 639 9 0.34902 0.298039 0.239216 0.501961
321 c 323 220 12 0.654902 0.580392 0.556863 0.501961
322 c 448 454 7 0.219608 0.0627451 0.0588235 0.501961
323 c 545 257 11 0.235294 0.160784 0.14902 0.501961
324 c 421 348 16 0.74902 0.717647 0.682353 0.501961
325 c 513 385 5 0.247059 0.0431373 0.027451 0.501961
326 c 151 669 17 0.054902 0.0784314 0.0627451 0.501961
327 c 92 679 12 0 0 0 0.501961
328 c 298 423 14 0.105882 0.0509804 0.00784314 0.501961
329 c 256 88 16 0.423529 0.419608 0.34902 0.501961
330 c 613 222 10 0.141176 0.141176 0.188235 0.501961
331 c 751 625 18 0.423529 0.552941 0.627451 0.501961
332 c 262 19 7 0.219608 0.188235 0.121569 0.501961
333 c 358 348 33 0.780392 0.729412 0.694118 0.501961
334 c 762 596 17 0.0980392 0.168627 0.207843 0.501961
335 c 386 444 14 0.611765 0.607843 0.564706 0.501961
336 c 231 532 12 0.478431 0.380392 0.254902 0.501961
337 c 392 291 17 0.631373 0.623529 0.639216 0.501961
338 c 282 348 8 0.376471 0.25098 0.12549 0.501961
339 c 639 69 32 0.4 0.333333 0.298039 0.501961
340 c 670 454 16 0.0823529 0.027451 0 0.501961
341 c 664 316 22 0.580392 0.580392 0.580392 0.501961
342 c 259 251 8 0.584314 0.494118 0.380392 0.501961
343 c 364 62 12 0.686275 0.631373 0.564706 0.501961
14 Appendix A: Source Code Listings 156

344 c 580 625 24 0.415686 0.376471 0.341176 0.501961


345 c 801 664 19 0.0196078 0.0352941 0.054902 0.501961
346 c 307 632 12 0.470588 0.470588 0.427451 0.501961
347 c 265 411 14 0.498039 0.403922 0.270588 0.501961
348 c 268 683 20 0.439216 0.368627 0.25098 0.501961
349 c 661 134 22 0.498039 0.470588 0.458824 0.501961
350 c 251 593 15 0.129412 0.105882 0.0666667 0.501961
351 c 746 205 23 0.384314 0.333333 0.298039 0.501961
352 c 570 446 7 0.223529 0.180392 0.160784 0.501961
353 c 489 707 14 0.713726 0.721569 0.701961 0.501961
354 c 369 695 9 0.282353 0.25098 0.227451 0.501961
355 c 413 372 17 0.6 0.533333 0.501961 0.501961
356 c 261 298 20 0.690196 0.658824 0.568627 0.501961
357 c 449 47 13 0.470588 0.364706 0.25098 0.501961
358 c 619 260 12 0.305882 0.305882 0.364706 0.501961
359 c 380 245 7 0 0 0 0.501961
360 c 440 621 27 0.678431 0.686275 0.662745 0.501961
361 c 625 706 13 0.435294 0.54902 0.607843 0.501961
362 c 492 427 10 0.678431 0.658824 0.654902 0.501961
363 c 280 21 14 0.635294 0.501961 0.309804 0.501961
364 c 213 13 13 0.729412 0.752941 0.709804 0.501961
365 c 161 605 15 0.25098 0.317647 0.352941 0.501961
366 c 531 707 24 0.415686 0.368627 0.32549 0.501961
367 c 424 316 23 0.843137 0.87451 0.886275 0.501961
368 c 359 681 8 0.278431 0.231373 0.192157 0.501961
369 c 555 163 20 0.529412 0.462745 0.470588 0.501961
370 c 131 644 16 0.2 0.298039 0.360784 0.501961
371 c 692 679 38 0.227451 0.184314 0.121569 0.501961
372 c 761 685 9 0.454902 0.580392 0.647059 0.501961
373 c 709 492 18 0.32549 0.282353 0.223529 0.501961
374 c 258 160 14 0.568627 0.576471 0.517647 0.501961
375 c 372 241 4 0.564706 0.713726 0.811765 0.501961
376 c 517 457 6 0.105882 0.00392157 0 0.501961
377 c 92 706 18 0.133333 0.243137 0.305882 0.501961
378 c 573 186 12 0.278431 0.239216 0.211765 0.501961
379 c 232 385 16 0.294118 0.388235 0.423529 0.501961
380 c 753 501 36 0.121569 0.180392 0.215686 0.501961
381 c 182 633 8 0.796078 0.952941 1 0.501961
382 c 553 215 11 0.486275 0.439216 0.462745 0.501961
383 c 566 258 6 0.435294 0.572549 0.65098 0.501961
384 c 816 75 38 0.164706 0.192157 0.211765 0.501961
385 c 306 63 12 0.384314 0.298039 0.207843 0.501961
386 c 208 455 17 0.470588 0.52549 0.509804 0.501961
14 Appendix A: Source Code Listings 157

387 c 578 555 26 0.482353 0.466667 0.435294 0.501961


388 c 379 198 7 0.270588 0.196078 0.141176 0.501961
389 c 481 338 10 0.721569 0.631373 0.635294 0.501961
390 c 640 561 10 0.556863 0.670588 0.72549 0.501961
391 c 698 340 16 0.168627 0.129412 0.0784314 0.501961
392 c 78 228 45 0.054902 0.141176 0.196078 0.501961
393 c 771 98 21 0.337255 0.309804 0.247059 0.501961
394 c 215 128 14 0.529412 0.494118 0.376471 0.501961
395 c 338 43 11 0.290196 0.2 0.113725 0.501961
396 c 585 685 13 0.333333 0.309804 0.282353 0.501961
397 c 780 436 65 0.101961 0.168627 0.211765 0.501961
398 c 329 510 11 0.368627 0.384314 0.380392 0.501961
399 c 716 414 23 0.258824 0.227451 0.192157 0.501961
400 c 303 448 21 0.156863 0.0823529 0.0431373 0.501961
401 c 602 199 13 0.501961 0.454902 0.490196 0.501961
402 c 219 679 11 0.113725 0.0901961 0.0627451 0.501961
403 c 508 344 17 0.458824 0.368627 0.34902 0.501961
404 c 443 556 10 0.560784 0.552941 0.517647 0.501961
405 c 357 239 6 0.54902 0.764706 0.862745 0.501961
406 c 787 613 17 0.0784314 0.152941 0.2 0.501961
407 c 514 371 12 0.607843 0.564706 0.588235 0.501961
408 c 288 612 20 0.360784 0.286275 0.192157 0.501961
409 c 182 611 9 0.87451 1 1 0.501961
410 c 180 457 14 0.235294 0.294118 0.313726 0.501961
411 c 174 121 17 0.356863 0.415686 0.423529 0.501961
412 c 252 205 16 0.529412 0.505882 0.423529 0.501961
413 c 762 45 13 0.317647 0.294118 0.235294 0.501961
414 c 633 276 18 0.560784 0.52549 0.533333 0.501961
415 c 397 600 19 0.643137 0.643137 0.596078 0.501961
416 c 284 381 14 0.313726 0.247059 0.180392 0.501961
417 c 595 178 11 0.294118 0.239216 0.2 0.501961
418 c 248 460 9 0.752941 0.737255 0.635294 0.501961
419 c 244 480 9 0.811765 0.768627 0.635294 0.501961
420 c 198 622 7 0.713726 0.705882 0.635294 0.501961
421 c 632 674 9 0.576471 0.701961 0.741176 0.501961
422 c 274 643 20 0.180392 0.121569 0.0627451 0.501961
423 c 190 658 16 0.545098 0.482353 0.356863 0.501961
424 c 280 55 13 0.784314 0.745098 0.619608 0.501961
425 c 333 72 14 0.627451 0.564706 0.490196 0.501961
426 c 185 46 13 0.419608 0.47451 0.454902 0.501961
427 c 484 596 25 0.537255 0.552941 0.537255 0.501961
428 c 174 682 14 0.294118 0.270588 0.192157 0.501961
429 c 686 223 19 0.505882 0.47451 0.454902 0.501961
14 Appendix A: Source Code Listings 158

430 c 150 53 19 0.180392 0.25098 0.290196 0.501961


431 c 443 467 6 0.901961 0.831373 0.894118 0.501961
432 c 585 491 39 0.533333 0.521569 0.521569 0.501961
433 c 609 519 15 0.423529 0.396078 0.360784 0.501961
434 c 257 390 8 0.768627 0.713726 0.615686 0.501961
435 c 231 637 23 0.305882 0.25098 0.164706 0.501961
436 c 155 365 20 0.133333 0.211765 0.258824 0.501961
437 c 271 326 15 0.607843 0.52549 0.415686 0.501961
438 c 167 96 10 0.121569 0.176471 0.211765 0.501961
439 c 670 607 18 0.109804 0.0431373 0 0.501961
440 c 479 32 21 0.360784 0.282353 0.2 0.501961
441 c 508 439 13 0.478431 0.333333 0.364706 0.501961
442 c 327 240 7 0.2 0.156863 0.14902 0.501961
443 c 193 582 7 0.733333 0.882353 0.937255 0.501961
444 c 640 500 19 0.184314 0.215686 0.235294 0.501961
445 c 819 145 36 0.133333 0.184314 0.219608 0.501961
446 c 372 277 9 0.415686 0.376471 0.388235 0.501961
447 c 705 522 13 0.294118 0.262745 0.192157 0.501961
448 c 717 674 16 0.298039 0.27451 0.227451 0.501961
449 c 330 200 14 0.788235 0.788235 0.772549 0.501961
450 c 556 28 23 0.227451 0.168627 0.113725 0.501961
451 c 479 458 9 0.321569 0.141176 0.141176 0.501961
452 c 318 606 12 0.2 0.160784 0.121569 0.501961
453 c 455 253 13 0.694118 0.694118 0.65098 0.501961
454 c 295 203 25 0.886275 0.87451 0.847059 0.501961
455 c 560 668 27 0.462745 0.427451 0.380392 0.501961
456 c 356 476 16 0.835294 0.831373 0.784314 0.501961
457 c 739 229 13 0.462745 0.396078 0.392157 0.501961
458 c 371 213 12 0.509804 0.454902 0.443137 0.501961
459 c 454 340 14 1 1 1 0.501961
460 c 724 565 18 0.223529 0.172549 0.0941176 0.501961
461 c 74 659 10 0 0 0.0117647 0.501961
462 c 303 505 19 0.290196 0.235294 0.164706 0.501961
463 c 350 632 15 0.6 0.560784 0.501961 0.501961
464 c 428 394 16 0.74902 0.741176 0.74902 0.501961
465 c 228 458 8 0.235294 0.262745 0.27451 0.501961
466 c 599 584 16 0.388235 0.34902 0.301961 0.501961
467 c 216 485 17 0.419608 0.462745 0.45098 0.501961
468 c 814 350 19 0.223529 0.258824 0.278431 0.501961
469 c 679 70 21 0.282353 0.258824 0.223529 0.501961
470 c 360 196 7 0.368627 0.294118 0.231373 0.501961
471 c 212 242 14 0.431373 0.462745 0.447059 0.501961
472 c 498 291 11 0.458824 0.352941 0.286275 0.501961
14 Appendix A: Source Code Listings 159

473 c 323 582 11 0.4 0.345098 0.262745 0.501961


474 c 203 428 15 0.498039 0.541176 0.513726 0.501961
475 c 241 275 14 0.756863 0.729412 0.631373 0.501961
476 c 273 393 11 0.490196 0.403922 0.301961 0.501961
477 c 724 258 11 0.329412 0.196078 0.164706 0.501961
478 c 216 483 6 0.682353 0.698039 0.643137 0.501961
479 c 204 542 11 0.25098 0.313726 0.329412 0.501961
480 c 429 702 34 0.490196 0.47451 0.454902 0.501961
481 c 598 53 21 0.376471 0.321569 0.294118 0.501961
482 c 853 305 46 0.137255 0.188235 0.223529 0.501961
483 c 142 582 20 0.0705882 0.152941 0.203922 0.501961
484 c 123 134 25 0.14902 0.211765 0.25098 0.501961
485 c 387 259 8 0.156863 0.309804 0.407843 0.501961
486 c 488 525 20 0.654902 0.603922 0.580392 0.501961
487 c 356 259 8 0.662745 0.870588 0.976471 0.501961
488 c 155 186 11 0.0666667 0.133333 0.192157 0.501961
489 c 226 423 13 0.294118 0.352941 0.372549 0.501961
490 c 374 32 14 0.333333 0.258824 0.164706 0.501961
491 c 775 645 16 0.411765 0.529412 0.592157 0.501961
492 c 723 642 13 0.207843 0.168627 0.117647 0.501961
493 c 597 245 9 0.247059 0.411765 0.533333 0.501961
494 c 451 22 17 0.188235 0.12549 0.0862745 0.501961
495 c 481 417 10 0.498039 0.407843 0.388235 0.501961
496 c 552 436 13 0.52549 0.556863 0.568627 0.501961
497 c 452 441 7 0.647059 0.4 0.4 0.501961
498 c 349 568 16 0.760784 0.760784 0.682353 0.501961
499 c 341 430 22 0.831373 0.815686 0.772549 0.501961
500 c 407 183 15 0.733333 0.698039 0.678431 0.501961
501 c 399 203 9 0.392157 0.278431 0.176471 0.501961

12_wedge.cpp - 5661 bytes.

1 // Compile: clang++ -std=c++17 12_wedge.cpp -o 12_wedge


2 #define _USE_MATH_DEFINES
3
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10 #include <algorithm>
11
14 Appendix A: Source Code Listings 160

12 int get_index(int x, int y, int width)


13 {
14 return x+width*y;
15 }
16
17 int calc_size(int width, int height)
18 {
19 return width*height;
20 }
21
22 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
23 height)
24 {
25 for (int y=0;y<height;++y) {
26 for (int x=0;x<width;++x) {
27 image[get_index(x,y,width)]=std::make_tuple(1.0f, 1.0f, 1.0f);
28 }
29 }
30 }
31
32 void get_all_ys(std::vector<int> &ys,std::vector<std::tuple<int,int>> &coords)
33 {
34 for (auto& c : coords) {
35 ys.push_back(std::get<1>(c));
36 }
37
38 sort(ys.begin(), ys.end());
39 ys.erase( unique( ys.begin(), ys.end() ), ys.end() );
40 }
41
42 void draw_line_coords(int x1, int y1, int x2, int y2,std::vector<std::tuple<int,int>\
43 > &coords)
44 {
45 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
46 dx = x2 - x1; dy = y2 - y1;
47 if (dx == 0)
48 {
49 if (y2 < y1) std::swap(y1, y2);
50 for (y = y1; y <= y2; y++)
51 coords.push_back(std::make_tuple(x1,y));
52 return;
53 }
54 if (dy == 0)
14 Appendix A: Source Code Listings 161

55 {
56 if (x2 < x1) std::swap(x1, x2);
57 for (x = x1; x <= x2; x++)
58 coords.push_back(std::make_tuple(x,y1));
59 return;
60 }
61 dx1 = abs(dx); dy1 = abs(dy);
62 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
63 if (dy1 <= dx1)
64 {
65 if (dx >= 0)
66 {
67 x = x1; y = y1; xe = x2;
68 }
69 else
70 {
71 x = x2; y = y2; xe = x1;
72 }
73 coords.push_back(std::make_tuple(x,y));
74 for (i = 0; x<xe; i++)
75 {
76 x = x + 1;
77 if (px<0)
78 px = px + 2 * dy1;
79 else
80 {
81 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
82 px = px + 2 * (dy1 - dx1);
83 }
84 coords.push_back(std::make_tuple(x,y));
85 }
86 }
87 else
88 {
89 if (dy >= 0)
90 {
91 x = x1; y = y1; ye = y2;
92 }
93 else
94 {
95 x = x2; y = y2; ye = y1;
96 }
97 coords.push_back(std::make_tuple(x,y));
14 Appendix A: Source Code Listings 162

98 for (i = 0; y<ye; i++)


99 {
100 y = y + 1;
101 if (py <= 0)
102 py = py + 2 * dx1;
103 else
104 {
105 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
106 py = py + 2 * (dx1 - dy1);
107 }
108 coords.push_back(std::make_tuple(x,y));
109 }
110 }
111 }
112
113 void draw_wedge(int x_cen,int y_cen,int rad,int start_ang,int end_ang,std::vector<st\
114 d::tuple<float, float, float>> &image,std::tuple<float, float, float> &color, int wi
115 dth, int height)
116 {
117 std::vector<std::tuple<int,int>> coords;
118
119 float ang=(((start_ang<=end_ang)?start_ang:end_ang)*(M_PI/180));
120 float range=(((end_ang>start_ang)?end_ang:start_ang)*(M_PI/180));
121 float x=(rad*cos(ang));
122 float y=(rad*sin(ang));
123 do
124 {
125 coords.push_back(std::make_tuple((int)(x_cen+x+0.5),(int)(y_cen-y+0.5)));
126 ang+=0.001;
127 x=(rad*cos(ang));
128 y=(rad*sin(ang));
129 }
130 while(ang<=range);
131
132 std::tuple<int,int> co1=coords.front();
133 std::tuple<int,int> co2=coords.back();
134
135 draw_line_coords(x_cen,y_cen,std::get<0>(co1),std::get<1>(co1),coords);
136 draw_line_coords(x_cen,y_cen,std::get<0>(co2),std::get<1>(co2),coords);
137
138 for (auto & e : coords) {
139 image[get_index(std::get<0>(e),std::get<1>(e),width)]=color;
140 }
14 Appendix A: Source Code Listings 163

141 }
142
143 void draw_filled_wedge(int x_cen,int y_cen,int rad,int start_ang,int end_ang,std::ve\
144 ctor<std::tuple<float, float, float>> &image,std::tuple<float, float, float> &color,
145 int width, int height)
146 {
147 std::vector<std::tuple<int,int>> coords;
148
149 float ang=(((start_ang<=end_ang)?start_ang:end_ang)*(M_PI/180));
150 float range=(((end_ang>start_ang)?end_ang:start_ang)*(M_PI/180));
151 float x=(rad*cos(ang));
152 float y=(rad*sin(ang));
153 do
154 {
155 coords.push_back(std::make_tuple((int)(x_cen+x+0.5),(int)(y_cen-y+0.5)));
156 ang+=0.001;
157 x=(rad*cos(ang));
158 y=(rad*sin(ang));
159 }
160 while(ang<=range);
161
162 std::tuple<int,int> co1=coords.front();
163 std::tuple<int,int> co2=coords.back();
164
165 draw_line_coords(x_cen,y_cen,std::get<0>(co1),std::get<1>(co1),coords);
166 draw_line_coords(x_cen,y_cen,std::get<0>(co2),std::get<1>(co2),coords);
167
168 std::vector<int> ys;
169 std::vector<int> xs;
170 get_all_ys(ys,coords);
171 std::vector<std::tuple<int,int,int,int>> lines;
172
173 for (int search=0;search<=ys.size();++search)
174 {
175 for (auto& c : coords) {
176 if (std::get<1>(c) == ys[search]) {
177 xs.push_back(std::get<0>(c));
178 }
179 }
180 sort(xs.begin(), xs.end());
181 lines.push_back(std::make_tuple(xs.front(),ys[search],xs.back(),ys[search]));
182 xs.clear();
183 }
14 Appendix A: Source Code Listings 164

184
185 auto drawline = [&](int sx, int ex, int ny)
186 {
187 for (int i = sx; i <= ex; i++)
188 image[get_index(i, ny, width)]=color;
189 };
190
191 for (auto& l : lines) {
192 drawline(std::get<0>(l),std::get<2>(l),std::get<1>(l));
193 }
194 }
195
196 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
197 height, std::string filename)
198 {
199 std::tuple<float, float, float> color;
200 std::ofstream out(filename, std::ofstream::out);
201 out << "P3\n" << width << " " << height << "\n255\n";
202 for (int i=0;i<(width*height);++i)
203 {
204 color=image[i];
205 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
206 " " << int(std::get<2>(color)*255.0f) << '\n';
207 }
208 out.close();
209 }
210
211 int main()
212 {
213 int width=640;
214 int height=360;
215
216 std::vector<std::tuple<float, float, float>> image;
217 std::tuple<float,float,float> color=std::make_tuple(0.0f,0.0f,0.0f);
218
219 image.resize(calc_size(width, height));
220 clear_image(image,width,height);
221
222 int x_cen,y_cen,rad,start_ang,end_ang;
223 x_cen=width/2;
224 y_cen=height/2;
225 rad=y_cen*0.8;
226 start_ang=0;
14 Appendix A: Source Code Listings 165

227 end_ang=348;
228 image[get_index(x_cen,y_cen, width)]=color;
229 draw_filled_wedge(x_cen,y_cen,rad,start_ang,end_ang,image,color,width,height);
230 color=std::make_tuple(0.5f,0.5f,0.5f);
231 draw_filled_wedge(x_cen,y_cen,rad/2,start_ang,end_ang,image,color,width,height);
232 color=std::make_tuple(0.8f,0.0f,0.8f);
233 draw_wedge(x_cen,y_cen,rad,start_ang,end_ang,image,color,width,height);
234
235 save_image(image,width,height,"12_wedge.ppm");
236
237 return 0;
238 }

13_triangles.cpp - 6504 bytes.

1 // Compile: clang++ -std=c++17 13_triangles.cpp -o 13_triangles


2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <random>
8 #include <cmath>
9
10 int get_index(int x, int y, int width)
11 {
12 return x+width*y;
13 }
14
15 int calc_size(int width, int height)
16 {
17 return width*height;
18 }
19
20 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
21 at,float,float> &color, int width, int height)
22 {
23 for (int y=0;y<height;++y) {
24 for (int x=0;x<width;++x) {
25 image[get_index(x,y,width)]=color;
26 }
27 }
28 }
14 Appendix A: Source Code Listings 166

29
30 void draw_line(int x1, int y1, int x2, int y2, std::vector<std::tuple<float, float, \
31 float>> &image, std::tuple<float,float,float> &color, int width, int height)
32 {
33 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
34 dx = x2 - x1; dy = y2 - y1;
35 if (dx == 0)
36 {
37 if (y2 < y1) std::swap(y1, y2);
38 for (y = y1; y <= y2; y++)
39 image[get_index(x1,y,width)]=color;
40 return;
41 }
42 if (dy == 0)
43 {
44 if (x2 < x1) std::swap(x1, x2);
45 for (x = x1; x <= x2; x++)
46 image[get_index(x,y1,width)]=color;
47 return;
48 }
49 dx1 = abs(dx); dy1 = abs(dy);
50 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
51 if (dy1 <= dx1)
52 {
53 if (dx >= 0)
54 {
55 x = x1; y = y1; xe = x2;
56 }
57 else
58 {
59 x = x2; y = y2; xe = x1;
60 }
61 image[get_index(x,y,width)]=color;
62 for (i = 0; x<xe; i++)
63 {
64 x = x + 1;
65 if (px<0)
66 px = px + 2 * dy1;
67 else
68 {
69 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
70 px = px + 2 * (dy1 - dx1);
71 }
14 Appendix A: Source Code Listings 167

72 image[get_index(x,y,width)]=color;
73 }
74 }
75 else
76 {
77 if (dy >= 0)
78 {
79 x = x1; y = y1; ye = y2;
80 }
81 else
82 {
83 x = x2; y = y2; ye = y1;
84 }
85 image[get_index(x,y,width)]=color;
86 for (i = 0; y<ye; i++)
87 {
88 y = y + 1;
89 if (py <= 0)
90 py = py + 2 * dx1;
91 else
92 {
93 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
94 py = py + 2 * (dx1 - dy1);
95 }
96 image[get_index(x,y,width)]=color;
97 }
98 }
99 }
100
101 void draw_triangle(int x1, int y1, int x2, int y2, int x3, int y3, std::vector<std::\
102 tuple<float, float, float>> &image, std::tuple<float,float,float> &color, int width,
103 int height)
104 {
105 draw_line(x1, y1, x2, y2, image, color, width, height);
106 draw_line(x2, y2, x3, y3, image, color, width, height);
107 draw_line(x3, y3, x1, y1, image, color, width, height);
108 }
109
110 void draw_filled_triangle(int x1, int y1, int x2, int y2, int x3, int y3, std::vecto\
111 r<std::tuple<float, float, float>> &image, std::tuple<float,float,float> &color, int
112 width, int height)
113 {
114 auto SWAP = [](int &x, int &y) { int t = x; x = y; y = t; };
14 Appendix A: Source Code Listings 168

115 auto drawline = [&](int sx, int ex, int ny) { for (int i = sx; i <= ex; i++) image[\
116 get_index(i,ny,width)]=color;};
117
118 int t1x, t2x, y, minx, maxx, t1xp, t2xp;
119 bool changed1 = false;
120 bool changed2 = false;
121 int signx1, signx2, dx1, dy1, dx2, dy2;
122 int e1, e2;
123 if (y1>y2) { SWAP(y1, y2); SWAP(x1, x2); }
124 if (y1>y3) { SWAP(y1, y3); SWAP(x1, x3); }
125 if (y2>y3) { SWAP(y2, y3); SWAP(x2, x3); }
126
127 t1x = t2x = x1; y = y1;
128 dx1 = (int)(x2 - x1); if (dx1<0) { dx1 = -dx1; signx1 = -1; }
129 else signx1 = 1;
130 dy1 = (int)(y2 - y1);
131
132 dx2 = (int)(x3 - x1); if (dx2<0) { dx2 = -dx2; signx2 = -1; }
133 else signx2 = 1;
134 dy2 = (int)(y3 - y1);
135
136 if (dy1 > dx1) {
137 SWAP(dx1, dy1);
138 changed1 = true;
139 }
140 if (dy2 > dx2) {
141 SWAP(dy2, dx2);
142 changed2 = true;
143 }
144
145 e2 = (int)(dx2 >> 1);
146 if (y1 == y2) goto next;
147 e1 = (int)(dx1 >> 1);
148
149 for (int i = 0; i < dx1;) {
150 t1xp = 0; t2xp = 0;
151 if (t1x<t2x) { minx = t1x; maxx = t2x; }
152 else { minx = t2x; maxx = t1x; }
153 while (i<dx1) {
154 i++;
155 e1 += dy1;
156 while (e1 >= dx1) {
157 e1 -= dx1;
14 Appendix A: Source Code Listings 169

158 if (changed1) t1xp = signx1;


159 else goto next1;
160 }
161 if (changed1) break;
162 else t1x += signx1;
163 }
164 next1:
165 while (1) {
166 e2 += dy2;
167 while (e2 >= dx2) {
168 e2 -= dx2;
169 if (changed2) t2xp = signx2;
170 else goto next2;
171 }
172 if (changed2) break;
173 else t2x += signx2;
174 }
175 next2:
176 if (minx>t1x) minx = t1x;
177 if (minx>t2x) minx = t2x;
178 if (maxx<t1x) maxx = t1x;
179 if (maxx<t2x) maxx = t2x;
180 drawline(minx, maxx, y);
181 if (!changed1) t1x += signx1;
182 t1x += t1xp;
183 if (!changed2) t2x += signx2;
184 t2x += t2xp;
185 y += 1;
186 if (y == y2) break;
187
188 }
189 next:
190 dx1 = (int)(x3 - x2); if (dx1<0) { dx1 = -dx1; signx1 = -1; }
191 else signx1 = 1;
192 dy1 = (int)(y3 - y2);
193 t1x = x2;
194
195 if (dy1 > dx1) {
196 SWAP(dy1, dx1);
197 changed1 = true;
198 }
199 else changed1 = false;
200
14 Appendix A: Source Code Listings 170

201 e1 = (int)(dx1 >> 1);


202
203 for (int i = 0; i <= dx1; i++) {
204 t1xp = 0; t2xp = 0;
205 if (t1x<t2x) { minx = t1x; maxx = t2x; }
206 else { minx = t2x; maxx = t1x; }
207 while (i<dx1) {
208 e1 += dy1;
209 while (e1 >= dx1) {
210 e1 -= dx1;
211 if (changed1) { t1xp = signx1; break; }
212 else goto next3;
213 }
214 if (changed1) break;
215 else t1x += signx1;
216 if (i<dx1) i++;
217 }
218 next3:
219 while (t2x != x3) {
220 e2 += dy2;
221 while (e2 >= dx2) {
222 e2 -= dx2;
223 if (changed2) t2xp = signx2;
224 else goto next4;
225 }
226 if (changed2) break;
227 else t2x += signx2;
228 }
229 next4:
230
231 if (minx>t1x) minx = t1x;
232 if (minx>t2x) minx = t2x;
233 if (maxx<t1x) maxx = t1x;
234 if (maxx<t2x) maxx = t2x;
235 drawline(minx, maxx, y);
236 if (!changed1) t1x += signx1;
237 t1x += t1xp;
238 if (!changed2) t2x += signx2;
239 t2x += t2xp;
240 y += 1;
241 if (y>y3) return;
242 }
243 }
14 Appendix A: Source Code Listings 171

244
245 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
246 height, std::string filename)
247 {
248 std::tuple<float, float, float> color;
249 std::ofstream out(filename, std::ofstream::out);
250 out << "P3\n" << width << " " << height << "\n255\n";
251 for (int i=0;i<(width*height);++i)
252 {
253 color=image[i];
254 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
255 " " << int(std::get<2>(color)*255.0f) << '\n';
256 }
257 out.close();
258 }
259
260 int main()
261 {
262 int width=640;
263 int height=360;
264 int x11=0,x12=0,x13=0,x21=0,x22=0,x23=0,y1=0,y2=0;
265
266 x11=((width-(((height/2)*0.8)*3))/2)+(((height/2)*0.8)/2);
267 x12=x11+(((height/2)*0.8)/2);
268 x13=x11-(((height/2)*0.8)/2);
269 x21=width-x11;
270 x22=x21+(((height/2)*0.8)/2);
271 x23=x21-(((height/2)*0.8)/2);
272 y1=(height-((height/2)*0.8))/2;
273 y2=y1+((height/2)*0.8);
274
275 std::vector<std::tuple<float, float, float>> image;
276 std::tuple<float,float,float> color=std::make_tuple(1.0f,1.0f,1.0f);
277
278 image.resize(calc_size(width, height));
279 clear_image(image,color,width,height);
280
281 color=std::make_tuple(0.0f,0.0f,0.0f);
282 draw_triangle(x11,y1,x12,y2,x13,y2,image,color,width,height);
283 draw_filled_triangle(x21,y1,x22,y2,x23,y2,image,color,width,height);
284
285 save_image(image,width,height,"13_trangles.ppm");
286
14 Appendix A: Source Code Listings 172

287 return 0;
288 }

13_squint_with_your_eyes.txt - 25843 bytes.

1 b 576 720 0.694118 0.552941 0.509804


2 t 175 285 417 440 0.341176 0 0.0117647 0.501961
3 t 419 0 575 388 0.862745 0.980392 0.945098 0.501961
4 t 202 60 236 247 1 1 1 0.501961
5 t 372 110 391 427 0.258824 0 0 0.501961
6 t 0 0 92 558 0.937255 0.862745 0.784314 0.501961
7 t 130 585 518 719 0.482353 0.262745 0.235294 0.501961
8 t 76 36 202 415 0.898039 0.32549 0.231373 0.501961
9 t 233 177 339 221 0.376471 0.180392 0.0823529 0.501961
10 t 327 308 424 385 0.254902 0.00784314 0.113725 0.501961
11 t 52 409 132 538 0.905882 0.882353 0.862745 0.501961
12 t 210 118 258 177 1 1 0.996078 0.501961
13 t 232 36 277 113 0.780392 0.172549 0.0980392 0.501961
14 t 433 521 551 634 0.72549 0.203922 0.141176 0.501961
15 t 148 128 166 225 0.980392 0.956863 0.921569 0.501961
16 t 169 150 182 218 0 0 0.117647 0.501961
17 t 130 429 287 639 0.627451 0.690196 0.67451 0.501961
18 t 311 47 373 118 0.737255 0.219608 0.152941 0.501961
19 t 274 210 304 255 1 1 0.984314 0.501961
20 t 121 312 207 451 0.819608 0.290196 0.215686 0.501961
21 t 348 145 375 240 0.972549 0.901961 0.803922 0.501961
22 t 367 230 412 418 0.494118 0.129412 0.121569 0.501961
23 t 348 0 422 59 0.741176 0.854902 0.835294 0.501961
24 t 303 295 333 327 0.968627 0.8 0.682353 0.501961
25 t 283 381 348 541 0.392157 0.411765 0.368627 0.501961
26 t 187 246 208 288 0.235294 0 0.0431373 0.501961
27 t 406 390 487 535 0.470588 0.666667 0.694118 0.501961
28 t 191 64 240 109 1 0.905882 0.890196 0.501961
29 t 219 313 248 373 0.054902 0 0.101961 0.501961
30 t 358 272 376 340 0 0 0.180392 0.501961
31 t 316 126 356 166 0.882353 0.929412 0.882353 0.501961
32 t 544 187 575 388 0.572549 0.490196 0.47451 0.501961
33 t 0 459 32 557 0.588235 0.392157 0.364706 0.501961
34 t 412 144 515 326 0.858824 0.862745 0.811765 0.501961
35 t 178 114 206 151 0.482353 0.0235294 0.0745098 0.501961
36 t 318 377 373 447 0.501961 0.0705882 0.0588235 0.501961
14 Appendix A: Source Code Listings 173

37 t 58 70 152 190 0.847059 0.360784 0.247059 0.501961


38 t 213 246 261 297 0.972549 0.67451 0.505882 0.501961
39 t 199 143 225 243 1 1 0.941176 0.501961
40 t 322 317 357 374 0 0 0.235294 0.501961
41 t 240 391 307 439 0.529412 0.568627 0.537255 0.501961
42 t 406 256 421 416 0.709804 0.278431 0.254902 0.501961
43 t 219 195 272 205 0.231373 0.0470588 0 0.501961
44 t 325 275 352 300 0.968627 0.819608 0.698039 0.501961
45 t 388 0 437 149 0.709804 0.729412 0.717647 0.501961
46 t 518 447 575 555 0.721569 0.329412 0.286275 0.501961
47 t 0 268 102 397 0.792157 0.823529 0.768627 0.501961
48 t 290 52 306 94 1 0.905882 0.964706 0.501961
49 t 279 477 392 607 0.545098 0.607843 0.54902 0.501961
50 t 315 192 354 201 0 0 0 0.501961
51 t 350 597 452 686 0.666667 0.207843 0.14902 0.501961
52 t 264 67 288 109 0.439216 0.12549 0.0823529 0.501961
53 t 374 127 389 186 0.0823529 0 0.101961 0.501961
54 t 272 657 304 680 0.92549 0.890196 0.627451 0.501961
55 t 143 180 153 257 1 0.933333 0.831373 0.501961
56 t 369 438 448 557 0.623529 0.682353 0.662745 0.501961
57 t 0 0 31 241 0.866667 0.901961 0.858824 0.501961
58 t 162 105 173 156 0.917647 0.92549 0.823529 0.501961
59 t 275 281 311 293 0.286275 0 0 0.501961
60 t 267 238 277 283 1 1 0.917647 0.501961
61 t 243 259 309 269 0.611765 0.160784 0.0901961 0.501961
62 t 355 207 369 252 0.952941 1 0.929412 0.501961
63 t 274 100 305 213 0.529412 0.470588 0.447059 0.501961
64 t 30 0 137 43 0.92549 0.8 0.701961 0.501961
65 t 171 136 194 184 0.415686 0.00392157 0.235294 0.501961
66 t 460 350 553 426 0.741176 0.729412 0.686275 0.501961
67 t 240 296 304 325 0.803922 0.392157 0.298039 0.501961
68 t 167 231 182 300 0.847059 0.607843 0.756863 0.501961
69 t 24 513 126 593 0.721569 0.67451 0.686275 0.501961
70 t 389 205 412 303 0.709804 0.313726 0.282353 0.501961
71 t 215 679 342 719 0.490196 0.2 0.164706 0.501961
72 t 362 101 381 137 0.427451 0.054902 0.0627451 0.501961
73 t 81 622 246 719 0.458824 0.443137 0.45098 0.501961
74 t 49 419 146 503 0.866667 0.807843 0.764706 0.501961
75 t 0 0 574 18 0.819608 0.788235 0.737255 0.501961
76 t 347 294 364 354 0 0 0.152941 0.501961
77 t 274 35 291 54 1 0.882353 0.921569 0.501961
78 t 231 211 243 307 0.901961 0.615686 0.462745 0.501961
79 t 406 561 492 656 0.678431 0.266667 0.207843 0.501961
14 Appendix A: Source Code Listings 174

80 t 111 333 145 399 0.788235 0.223529 0.0392157 0.501961


81 t 314 195 335 210 0 0 0.0235294 0.501961
82 t 366 245 384 308 0.121569 0.0156863 0.176471 0.501961
83 t 343 239 361 281 0.988235 0.788235 0.658824 0.501961
84 t 235 117 266 147 1 0.988235 0.905882 0.501961
85 t 127 429 220 442 0.639216 0.239216 0.231373 0.501961
86 t 166 203 175 232 0.172549 0 0.184314 0.501961
87 t 201 647 267 719 0.396078 0.282353 0.266667 0.501961
88 t 416 359 441 456 0.458824 0.52549 0.541176 0.501961
89 t 215 346 226 430 0.207843 0.0156863 0.141176 0.501961
90 t 404 138 573 197 0.74902 0.752941 0.721569 0.501961
91 t 203 120 225 133 0.835294 0.45098 0.258824 0.501961
92 t 279 204 286 254 1 1 1 0.501961
93 t 49 28 86 264 0.878431 0.6 0.478431 0.501961
94 t 468 608 575 719 0.654902 0.529412 0.47451 0.501961
95 t 225 34 268 77 0.737255 0.282353 0.278431 0.501961
96 t 196 56 215 95 1 0.984314 0.952941 0.501961
97 t 166 488 255 565 0.733333 0.760784 0.733333 0.501961
98 t 180 203 188 262 0.890196 0.686275 0.729412 0.501961
99 t 348 367 409 426 0.592157 0.176471 0.117647 0.501961
100 t 250 161 276 228 0.560784 0.301961 0.211765 0.501961
101 t 113 84 155 144 0.776471 0.270588 0.184314 0.501961
102 t 222 299 233 337 0.0196078 0 0.0588235 0.501961
103 t 0 317 39 471 0.65098 0.686275 0.662745 0.501961
104 t 386 110 396 134 1 0.835294 0.803922 0.501961
105 t 239 197 261 210 0 0.0431373 0.054902 0.501961
106 t 299 37 357 59 0.745098 0.262745 0.34902 0.501961
107 t 294 321 314 380 0.65098 0.486275 0.494118 0.501961
108 t 303 644 385 695 0.541176 0.235294 0.203922 0.501961
109 t 303 440 338 510 0.407843 0.396078 0.345098 0.501961
110 t 380 126 388 276 0.227451 0.0156863 0.0901961 0.501961
111 t 267 297 283 302 1 0.937255 1 0.501961
112 t 403 672 518 719 0.709804 0.533333 0.462745 0.501961
113 t 86 247 154 301 0.882353 0.501961 0.352941 0.501961
114 t 123 599 366 654 0.501961 0.466667 0.462745 0.501961
115 t 411 331 427 393 0.662745 0.317647 0.301961 0.501961
116 t 280 487 311 534 0.733333 0.682353 0.584314 0.501961
117 t 151 146 159 200 0.976471 1 0.92549 0.501961
118 t 246 328 285 372 0.564706 0.152941 0.0509804 0.501961
119 t 204 278 219 345 0.772549 0.356863 0.368627 0.501961
120 t 253 276 269 287 1 1 0.87451 0.501961
121 t 117 141 145 213 0.803922 0.266667 0.192157 0.501961
122 t 217 205 229 291 0.968627 0.913725 0.807843 0.501961
14 Appendix A: Source Code Listings 175

123 t 456 503 536 620 0.72549 0.305882 0.25098 0.501961


124 t 52 391 81 432 0.807843 0.619608 0.509804 0.501961
125 t 351 38 396 88 0.627451 0.54902 0.521569 0.501961
126 t 344 55 366 130 0.882353 0.431373 0.270588 0.501961
127 t 226 114 239 121 0.788235 0.270588 0.0745098 0.501961
128 t 314 367 339 386 0.0509804 0.00784314 0.211765 0.501961
129 t 252 303 309 313 0.552941 0.137255 0.0235294 0.501961
130 t 185 177 204 239 0.8 0.505882 0.427451 0.501961
131 t 170 167 183 205 0.160784 0 0.129412 0.501961
132 t 226 233 267 275 0.772549 0.443137 0.411765 0.501961
133 t 218 128 246 173 0.988235 1 0.988235 0.501961
134 t 84 301 109 408 0.886275 0.607843 0.470588 0.501961
135 t 318 69 335 110 0.580392 0.192157 0.0784314 0.501961
136 t 440 409 473 484 0.419608 0.564706 0.588235 0.501961
137 t 266 272 284 281 1 1 1 0.501961
138 t 382 285 391 326 0.741176 0.352941 0.32549 0.501961
139 t 551 406 575 518 0.717647 0.380392 0.341176 0.501961
140 t 390 314 404 358 0.129412 0.0117647 0 0.501961
141 t 158 173 167 269 0.788235 0.376471 0.490196 0.501961
142 t 74 423 106 453 0.94902 0.968627 0.941176 0.501961
143 t 171 94 177 116 0.980392 1 0.823529 0.501961
144 t 92 13 236 59 0.835294 0.537255 0.435294 0.501961
145 t 21 452 45 495 0.705882 0.494118 0.447059 0.501961
146 t 179 102 200 156 0.603922 0.188235 0.192157 0.501961
147 t 324 274 341 311 0.803922 0.631373 0.52549 0.501961
148 t 300 272 317 282 1 0.87451 0.780392 0.501961
149 t 254 111 276 179 0.764706 0.662745 0.584314 0.501961
150 t 397 431 408 537 0.686275 0.729412 0.709804 0.501961
151 t 365 197 373 239 0.847059 0.968627 0.917647 0.501961
152 t 289 183 304 231 0.721569 0.498039 0.458824 0.501961
153 t 391 168 401 300 0.666667 0.333333 0.317647 0.501961
154 t 301 113 328 166 0.623529 0.65098 0.654902 0.501961
155 t 268 674 299 681 0.898039 0.831373 0.623529 0.501961
156 t 526 213 575 253 0.596078 0.564706 0.54902 0.501961
157 t 230 293 238 301 1 1 0.980392 0.501961
158 t 256 290 318 296 0.329412 0 0.0392157 0.501961
159 t 494 0 575 101 0.87451 0.870588 0.827451 0.501961
160 t 285 548 320 638 0.47451 0.494118 0.454902 0.501961
161 t 152 399 212 428 0.72549 0.376471 0.380392 0.501961
162 t 201 209 240 216 1 1 0.972549 0.501961
163 t 306 309 327 338 0.776471 0.619608 0.588235 0.501961
164 t 273 225 288 252 1 1 1 0.501961
165 t 279 420 320 461 0.447059 0.431373 0.352941 0.501961
14 Appendix A: Source Code Listings 176

166 t 256 99 333 108 0.568627 0.254902 0.152941 0.501961


167 t 531 574 575 719 0.619608 0.501961 0.454902 0.501961
168 t 236 320 256 381 0.313726 0.0980392 0.156863 0.501961
169 t 185 259 211 303 0.501961 0.156863 0.188235 0.501961
170 t 286 58 314 69 0.988235 0.772549 0.890196 0.501961
171 t 329 416 383 443 0.447059 0.141176 0.0862745 0.501961
172 t 438 359 542 402 0.760784 0.741176 0.686275 0.501961
173 t 203 643 275 667 0.376471 0.360784 0.380392 0.501961
174 t 161 386 172 410 0.92549 0.627451 0.584314 0.501961
175 t 312 172 342 177 0.411765 0.227451 0.12549 0.501961
176 t 384 77 426 116 0.592157 0.572549 0.580392 0.501961
177 t 431 467 443 512 0.760784 0.819608 0.815686 0.501961
178 t 361 202 367 261 0.901961 0.898039 0.807843 0.501961
179 t 335 177 375 190 0.94902 0.694118 0.529412 0.501961
180 t 139 218 148 274 0.956863 0.745098 0.65098 0.501961
181 t 239 71 248 107 0.988235 0.623529 0.454902 0.501961
182 t 204 141 223 198 0.976471 1 0.984314 0.501961
183 t 164 146 171 180 0.733333 0.443137 0.564706 0.501961
184 t 369 98 377 163 0.419608 0.180392 0.219608 0.501961
185 t 151 47 166 116 0.784314 0.317647 0.211765 0.501961
186 t 289 231 311 257 0.956863 0.682353 0.647059 0.501961
187 t 243 307 253 313 0.972549 0.886275 0.741176 0.501961
188 t 39 493 51 533 0.886275 0.890196 0.87451 0.501961
189 t 274 346 295 390 0.682353 0.403922 0.317647 0.501961
190 t 450 484 491 546 0.635294 0.513726 0.482353 0.501961
191 t 194 161 228 175 0.933333 0.94902 0.937255 0.501961
192 t 325 508 351 543 0.443137 0.415686 0.368627 0.501961
193 t 448 576 480 624 0.631373 0.184314 0.133333 0.501961
194 t 148 264 159 342 0.866667 0.313726 0.137255 0.501961
195 t 316 533 331 558 0.780392 0.764706 0.666667 0.501961
196 t 0 218 59 403 0.760784 0.784314 0.752941 0.501961
197 t 12 318 46 325 0.52549 0.505882 0.478431 0.501961
198 t 400 149 415 185 0.905882 0.792157 0.768627 0.501961
199 t 220 293 226 309 0.117647 0 0.054902 0.501961
200 t 486 415 547 481 0.647059 0.576471 0.564706 0.501961
201 t 229 357 232 403 0.803922 0.458824 0.47451 0.501961
202 t 318 215 341 230 0.529412 0.278431 0.211765 0.501961
203 t 372 324 383 351 0.678431 0.219608 0.141176 0.501961
204 t 309 329 323 407 0.352941 0.215686 0.384314 0.501961
205 t 339 305 374 335 0.117647 0.00784314 0.211765 0.501961
206 t 0 264 16 327 0.839216 0.890196 0.854902 0.501961
207 t 260 197 279 216 0.576471 0.192157 0.0745098 0.501961
208 t 280 280 306 285 0.537255 0.0235294 0.0196078 0.501961
14 Appendix A: Source Code Listings 177

209 t 207 205 224 252 0.956863 0.976471 0.929412 0.501961


210 t 181 75 233 87 0.92549 0.796078 0.807843 0.501961
211 t 341 285 355 290 1 0.85098 0.835294 0.501961
212 t 203 233 210 249 0.854902 0.556863 0.333333 0.501961
213 t 200 363 214 401 0.45098 0.0862745 0.196078 0.501961
214 t 416 192 433 266 0.898039 0.898039 0.847059 0.501961
215 t 279 469 294 497 0.784314 0.745098 0.607843 0.501961
216 t 234 312 245 337 0.137255 0 0.0588235 0.501961
217 t 246 80 268 109 0.843137 0.301961 0.101961 0.501961
218 t 277 659 288 666 1 1 0.941176 0.501961
219 t 237 302 245 308 0.988235 0.972549 0.905882 0.501961
220 t 391 126 400 148 1 0.803922 0.760784 0.501961
221 t 406 529 459 572 0.662745 0.509804 0.470588 0.501961
222 t 183 92 188 124 0.478431 0.0980392 0.0705882 0.501961
223 t 328 135 365 167 0.87451 0.819608 0.741176 0.501961
224 t 191 101 206 123 0.909804 0.560784 0.478431 0.501961
225 t 231 178 239 193 1 0.772549 0.501961 0.501961
226 t 339 200 350 298 0.796078 0.607843 0.552941 0.501961
227 t 442 655 521 671 0.733333 0.509804 0.439216 0.501961
228 t 10 336 41 357 0.639216 0.623529 0.580392 0.501961
229 t 168 402 192 456 0.741176 0.313726 0.282353 0.501961
230 t 10 574 163 668 0.647059 0.572549 0.537255 0.501961
231 t 274 677 283 691 0.388235 0.168627 0.184314 0.501961
232 t 81 178 139 229 0.835294 0.360784 0.27451 0.501961
233 t 310 694 436 719 0.694118 0.419608 0.34902 0.501961
234 t 180 286 222 304 0.623529 0.239216 0.235294 0.501961
235 t 178 86 183 96 0.929412 1 0.815686 0.501961
236 t 331 632 437 678 0.615686 0.25098 0.2 0.501961
237 t 286 250 296 276 0.701961 0.305882 0.239216 0.501961
238 t 240 37 269 51 0.529412 0.176471 0.184314 0.501961
239 t 206 53 220 121 0.984314 0.898039 0.823529 0.501961
240 t 544 526 575 606 0.721569 0.529412 0.458824 0.501961
241 t 291 0 349 32 0.647059 0.682353 0.658824 0.501961
242 t 364 266 383 299 0.2 0.0313726 0.180392 0.501961
243 t 155 138 161 180 0.980392 1 0.905882 0.501961
244 t 504 661 548 719 0.635294 0.592157 0.568627 0.501961
245 t 201 439 237 490 0.670588 0.678431 0.654902 0.501961
246 t 242 220 272 240 0.713726 0.305882 0.34902 0.501961
247 t 3 113 38 191 0.929412 0.858824 0.788235 0.501961
248 t 186 126 211 136 0.627451 0.192157 0.129412 0.501961
249 t 353 363 362 378 0.729412 0.352941 0.360784 0.501961
250 t 518 117 575 208 0.713726 0.698039 0.658824 0.501961
251 t 266 316 304 329 0.72549 0.498039 0.439216 0.501961
14 Appendix A: Source Code Listings 178

252 t 268 401 301 417 0.607843 0.580392 0.6 0.501961


253 t 235 423 273 502 0.627451 0.623529 0.533333 0.501961
254 t 0 701 8 719 0.972549 0.803922 0.741176 0.501961
255 t 294 653 299 658 1 1 0.890196 0.501961
256 t 167 208 170 250 0.411765 0.129412 0.219608 0.501961
257 t 267 250 272 261 1 1 1 0.501961
258 t 111 67 153 161 0.803922 0.345098 0.258824 0.501961
259 t 191 242 199 273 0.282353 0.0823529 0.156863 0.501961
260 t 301 471 324 497 0.403922 0.384314 0.321569 0.501961
261 t 232 357 258 411 0.458824 0.211765 0.258824 0.501961
262 t 18 52 103 79 0.886275 0.647059 0.529412 0.501961
263 t 448 97 481 172 0.831373 0.85098 0.815686 0.501961
264 t 265 136 309 183 0.498039 0.486275 0.47451 0.501961
265 t 277 61 285 103 0.419608 0.184314 0.192157 0.501961
266 t 215 261 241 281 0.87451 0.670588 0.478431 0.501961
267 t 270 626 341 654 0.458824 0.364706 0.345098 0.501961
268 t 225 306 238 316 0.129412 0 0.0431373 0.501961
269 t 4 0 98 10 0.858824 0.87451 0.862745 0.501961
270 t 299 659 308 669 0.968627 0.847059 0.462745 0.501961
271 t 351 189 362 201 0.870588 0.447059 0.32549 0.501961
272 t 165 114 171 128 0.996078 1 0.921569 0.501961
273 t 430 449 436 470 0.764706 0.890196 0.909804 0.501961
274 t 188 130 196 164 0.427451 0.0431373 0.109804 0.501961
275 t 329 554 341 573 0.780392 0.788235 0.733333 0.501961
276 t 28 520 120 568 0.756863 0.670588 0.670588 0.501961
277 t 58 301 88 343 0.901961 0.827451 0.756863 0.501961
278 t 12 200 37 284 0.721569 0.713726 0.670588 0.501961
279 t 406 18 495 78 0.780392 0.792157 0.756863 0.501961
280 t 384 101 390 116 1 0.729412 0.709804 0.501961
281 t 428 267 523 340 0.870588 0.886275 0.831373 0.501961
282 t 242 377 248 400 0.823529 0.45098 0.364706 0.501961
283 t 371 238 387 262 0.235294 0.0941176 0.0823529 0.501961
284 t 259 50 276 79 0.576471 0.313726 0.368627 0.501961
285 t 226 287 233 294 1 1 0.945098 0.501961
286 t 249 313 255 317 1 0.972549 0.862745 0.501961
287 t 347 449 373 529 0.568627 0.607843 0.564706 0.501961
288 t 93 413 124 422 0.945098 0.894118 0.831373 0.501961
289 t 489 442 509 456 0.803922 0.403922 0.341176 0.501961
290 t 247 293 263 309 0.615686 0.231373 0.0235294 0.501961
291 t 536 467 555 548 0.698039 0.341176 0.298039 0.501961
292 t 305 517 319 533 0.788235 0.756863 0.654902 0.501961
293 t 71 370 104 410 0.847059 0.572549 0.458824 0.501961
294 t 112 418 151 430 0.831373 0.631373 0.588235 0.501961
14 Appendix A: Source Code Listings 179

295 t 144 380 151 402 0.964706 0.596078 0.490196 0.501961


296 t 530 196 555 393 0.745098 0.709804 0.666667 0.501961
297 t 319 322 332 344 0.368627 0.254902 0.411765 0.501961
298 t 179 212 183 228 0.964706 0.858824 0.87451 0.501961
299 t 293 437 302 480 0.376471 0.372549 0.290196 0.501961
300 t 309 312 323 323 0.988235 0.796078 0.67451 0.501961
301 t 125 559 168 716 0.552941 0.47451 0.482353 0.501961
302 t 334 382 419 408 0.580392 0.188235 0.164706 0.501961
303 t 472 64 516 114 0.72549 0.733333 0.698039 0.501961
304 t 171 164 180 216 0.231373 0 0.152941 0.501961
305 t 355 289 368 348 0.113725 0.00392157 0.164706 0.501961
306 t 144 200 154 229 0.960784 0.905882 0.815686 0.501961
307 t 185 189 188 206 0.878431 0.835294 0.878431 0.501961
308 t 342 71 375 87 0.870588 0.54902 0.431373 0.501961
309 t 288 373 308 407 0.380392 0.380392 0.482353 0.501961
310 t 241 170 256 180 0.882353 0.576471 0.32549 0.501961
311 t 339 29 368 47 0.576471 0.607843 0.596078 0.501961
312 t 226 562 280 615 0.615686 0.623529 0.611765 0.501961
313 t 25 44 52 116 0.913725 0.72549 0.607843 0.501961
314 t 107 349 147 391 0.784314 0.278431 0.145098 0.501961
315 t 563 193 575 264 0.533333 0.505882 0.505882 0.501961
316 t 278 36 294 57 1 0.729412 0.745098 0.501961
317 t 407 423 439 451 0.415686 0.552941 0.568627 0.501961
318 t 56 284 65 304 0.635294 0.568627 0.529412 0.501961
319 t 488 594 502 621 0.792157 0.490196 0.427451 0.501961
320 t 349 580 392 613 0.627451 0.490196 0.45098 0.501961
321 t 317 201 334 207 0 0 0 0.501961
322 t 384 142 390 213 0.223529 0.0431373 0.133333 0.501961
323 t 268 287 321 293 0.270588 0.0313726 0.0235294 0.501961
324 t 131 271 148 347 0.87451 0.494118 0.345098 0.501961
325 t 302 189 318 218 0.431373 0.258824 0.309804 0.501961
326 t 151 407 163 420 0.866667 0.631373 0.580392 0.501961
327 t 409 167 416 208 0.898039 0.866667 0.831373 0.501961
328 t 118 432 169 438 0.682353 0.290196 0.227451 0.501961
329 t 174 227 190 253 0.862745 0.556863 0.611765 0.501961
330 t 443 463 481 489 0.454902 0.513726 0.521569 0.501961
331 t 232 120 272 129 0.933333 0.92549 0.87451 0.501961
332 t 81 308 112 344 0.866667 0.662745 0.564706 0.501961
333 t 210 703 319 719 0.580392 0.254902 0.211765 0.501961
334 t 309 276 323 285 0.960784 0.776471 0.678431 0.501961
335 t 79 464 160 515 0.792157 0.737255 0.698039 0.501961
336 t 283 293 300 303 0.796078 0.0392157 0.309804 0.501961
337 t 0 374 21 484 0.662745 0.631373 0.596078 0.501961
14 Appendix A: Source Code Listings 180

338 t 270 670 274 682 1 1 0.733333 0.501961


339 t 362 351 374 365 0.729412 0.231373 0.176471 0.501961
340 t 406 250 416 334 0.643137 0.294118 0.27451 0.501961
341 t 56 442 92 467 0.913725 0.909804 0.886275 0.501961
342 t 480 541 537 588 0.717647 0.258824 0.2 0.501961
343 t 361 45 387 66 0.529412 0.556863 0.576471 0.501961
344 t 350 203 358 285 0.882353 0.737255 0.662745 0.501961
345 t 219 45 237 65 0.913725 0.392157 0.301961 0.501961
346 t 312 245 332 276 0.670588 0.431373 0.403922 0.501961
347 t 176 108 183 129 0.729412 0.411765 0.360784 0.501961
348 t 147 0 299 28 0.74902 0.596078 0.529412 0.501961
349 t 201 408 210 423 0.705882 0.568627 0.556863 0.501961
350 t 153 216 162 274 0.894118 0.423529 0.415686 0.501961
351 t 287 670 295 674 0.384314 0.160784 0.113725 0.501961
352 t 0 499 20 560 0.67451 0.470588 0.423529 0.501961
353 t 159 418 174 435 0.65098 0.203922 0.141176 0.501961
354 t 291 36 329 47 0.858824 0.329412 0.313726 0.501961
355 t 338 535 356 559 0.47451 0.462745 0.411765 0.501961
356 t 292 493 305 515 0.776471 0.752941 0.65098 0.501961
357 t 270 268 279 280 0.972549 1 0.964706 0.501961
358 t 184 174 186 193 0.219608 0.0941176 0.27451 0.501961
359 t 294 678 297 685 1 1 0.87451 0.501961
360 t 386 75 401 102 0.501961 0.47451 0.498039 0.501961
361 t 361 278 365 288 0 0 0 0.501961
362 t 390 577 437 614 0.670588 0.341176 0.301961 0.501961
363 t 176 95 179 104 1 1 0.905882 0.501961
364 t 344 301 354 369 0.101961 0.0117647 0.152941 0.501961
365 t 69 110 100 246 0.847059 0.501961 0.411765 0.501961
366 t 108 443 125 473 0.894118 0.878431 0.839216 0.501961
367 t 333 87 378 106 0.827451 0.360784 0.227451 0.501961
368 t 163 268 171 328 0.839216 0.529412 0.568627 0.501961
369 t 253 332 301 349 0.596078 0.219608 0.117647 0.501961
370 t 380 343 397 373 0.282353 0.0627451 0.0196078 0.501961
371 t 332 284 344 305 0.854902 0.666667 0.6 0.501961
372 t 375 199 385 228 0.6 0.258824 0.184314 0.501961
373 t 561 373 575 447 0.745098 0.443137 0.403922 0.501961
374 t 17 360 73 375 0.87451 0.85098 0.792157 0.501961
375 t 267 300 277 305 0.917647 0.647059 0.643137 0.501961
376 t 332 208 344 235 0.607843 0.423529 0.388235 0.501961
377 t 2 286 51 314 0.839216 0.858824 0.819608 0.501961
378 t 170 369 178 391 0.913725 0.517647 0.482353 0.501961
379 t 115 323 134 404 0.792157 0.290196 0.145098 0.501961
380 t 34 128 72 193 0.890196 0.682353 0.572549 0.501961
14 Appendix A: Source Code Listings 181

381 t 278 214 287 248 1 1 0.960784 0.501961


382 t 276 260 285 268 0.545098 0.105882 0.0156863 0.501961
383 t 373 121 386 143 0.2 0.0509804 0.152941 0.501961
384 t 366 221 368 253 0.870588 0.941176 0.862745 0.501961
385 t 389 268 394 316 0.686275 0.439216 0.411765 0.501961
386 t 313 116 346 130 0.701961 0.682353 0.643137 0.501961
387 t 285 507 298 604 0.576471 0.568627 0.537255 0.501961
388 t 194 363 204 412 0.643137 0.196078 0.247059 0.501961
389 t 217 130 229 193 0.968627 0.984314 0.941176 0.501961
390 t 339 201 377 209 0.815686 0.772549 0.72549 0.501961
391 t 28 592 110 652 0.701961 0.607843 0.552941 0.501961
392 t 279 79 313 82 0.882353 0.65098 0.603922 0.501961
393 t 68 345 84 428 0.862745 0.670588 0.572549 0.501961
394 t 426 395 450 428 0.470588 0.639216 0.666667 0.501961
395 t 237 197 250 206 0 0.027451 0.0235294 0.501961
396 t 221 62 231 86 0.952941 0.65098 0.729412 0.501961
397 t 285 303 305 307 0.372549 0 0 0.501961
398 t 396 212 408 300 0.6 0.282353 0.25098 0.501961
399 t 130 34 197 67 0.780392 0.447059 0.360784 0.501961
400 t 221 295 228 384 0.2 0.0901961 0.152941 0.501961
401 t 248 178 285 198 0.603922 0.380392 0.254902 0.501961
402 t 217 198 230 204 0.819608 0.392157 0.192157 0.501961
403 t 302 296 311 298 0.992157 0.831373 0.909804 0.501961
404 t 318 506 329 523 0.384314 0.352941 0.294118 0.501961
405 t 180 133 185 170 0.741176 0.160784 0.360784 0.501961
406 t 299 267 309 280 0.92549 0.780392 0.705882 0.501961
407 t 442 62 460 88 0.866667 0.882353 0.847059 0.501961
408 t 271 657 278 661 0.266667 0.192157 0.219608 0.501961
409 t 245 281 258 290 0.94902 0.788235 0.588235 0.501961
410 t 309 652 364 673 0.498039 0.309804 0.298039 0.501961
411 t 268 34 308 38 0.913725 0.54902 0.552941 0.501961
412 t 455 214 460 238 0.615686 0.635294 0.592157 0.501961
413 t 16 317 32 322 0.447059 0.411765 0.392157 0.501961
414 t 451 370 482 394 0.843137 0.819608 0.752941 0.501961
415 t 392 153 394 184 0.670588 0.164706 0.219608 0.501961
416 t 148 366 155 387 0.960784 0.584314 0.466667 0.501961
417 t 357 236 362 275 0.886275 0.768627 0.65098 0.501961
418 t 465 407 516 437 0.592157 0.635294 0.631373 0.501961
419 t 310 51 319 115 0.65098 0.388235 0.443137 0.501961
420 t 279 198 298 208 0.831373 0.568627 0.407843 0.501961
421 t 472 22 533 53 0.862745 0.870588 0.823529 0.501961
422 t 296 242 309 253 0.960784 0.882353 0.839216 0.501961
423 t 194 120 204 144 0.631373 0.223529 0.141176 0.501961
14 Appendix A: Source Code Listings 182

424 t 532 149 562 165 0.843137 0.835294 0.788235 0.501961


425 t 209 415 226 435 0.494118 0.227451 0.270588 0.501961
426 t 396 299 403 318 0.152941 0.121569 0.160784 0.501961
427 t 271 239 287 256 0.992157 0.976471 0.917647 0.501961
428 t 217 434 244 458 0.678431 0.67451 0.639216 0.501961
429 t 464 620 502 657 0.729412 0.392157 0.329412 0.501961
430 t 247 264 268 272 0.670588 0.329412 0.2 0.501961
431 t 201 277 212 360 0.733333 0.32549 0.305882 0.501961
432 t 211 257 213 263 1 1 1 0.501961
433 t 194 66 211 96 0.960784 0.921569 0.913725 0.501961
434 t 31 401 57 443 0.764706 0.741176 0.690196 0.501961
435 t 346 373 352 384 0.611765 0.396078 0.458824 0.501961
436 t 236 283 246 297 0.847059 0.447059 0.188235 0.501961
437 t 252 452 285 479 0.717647 0.678431 0.552941 0.501961
438 t 504 197 530 258 0.737255 0.729412 0.686275 0.501961
439 t 367 257 370 273 0.0392157 0 0.0784314 0.501961
440 t 159 121 168 143 0.968627 0.952941 0.8 0.501961
441 t 201 680 212 704 0.576471 0.494118 0.439216 0.501961
442 t 294 81 304 88 1 0.988235 0.941176 0.501961
443 t 349 296 357 303 0 0 0.0823529 0.501961
444 t 332 314 348 377 0.141176 0.0392157 0.180392 0.501961
445 t 377 677 428 694 0.72549 0.368627 0.305882 0.501961
446 t 335 191 345 197 0.054902 0.0235294 0 0.501961
447 t 183 203 186 218 0.972549 0.890196 0.85098 0.501961
448 t 209 397 214 409 0.768627 0.572549 0.529412 0.501961
449 t 442 480 446 515 0.796078 0.803922 0.772549 0.501961
450 t 298 258 305 261 0.172549 0.0392157 0.0509804 0.501961
451 t 154 69 173 100 0.780392 0.337255 0.239216 0.501961
452 t 165 315 189 373 0.858824 0.329412 0.247059 0.501961
453 t 255 316 257 321 1 0.956863 0.815686 0.501961
454 t 394 133 401 161 0.992157 0.713726 0.686275 0.501961
455 t 406 76 430 158 0.658824 0.67451 0.647059 0.501961
456 t 422 427 428 473 0.396078 0.498039 0.517647 0.501961
457 t 283 249 299 260 0.92549 0.568627 0.482353 0.501961
458 t 244 695 245 703 1 0.937255 0.792157 0.501961
459 t 328 526 334 537 0.309804 0.290196 0.243137 0.501961
460 t 21 378 35 384 0.564706 0.533333 0.486275 0.501961
461 t 363 141 371 168 0.752941 0.588235 0.537255 0.501961
462 t 302 387 330 399 0.317647 0.152941 0.27451 0.501961
463 t 7 659 91 719 0.6 0.560784 0.490196 0.501961
464 t 295 524 308 584 0.521569 0.498039 0.443137 0.501961
465 t 523 595 563 645 0.654902 0.486275 0.419608 0.501961
466 t 315 175 332 193 0.533333 0.290196 0.168627 0.501961
14 Appendix A: Source Code Listings 183

467 t 312 448 356 474 0.482353 0.494118 0.458824 0.501961


468 t 430 10 454 34 0.701961 0.686275 0.662745 0.501961
469 t 415 612 458 649 0.580392 0.219608 0.172549 0.501961
470 t 486 502 521 527 0.772549 0.490196 0.435294 0.501961
471 t 141 448 203 457 0.678431 0.529412 0.52549 0.501961
472 t 130 104 147 188 0.784314 0.298039 0.219608 0.501961
473 t 146 334 151 367 0.721569 0.203922 0.109804 0.501961
474 t 13 549 73 582 0.733333 0.666667 0.631373 0.501961
475 t 295 663 299 667 0.329412 0.184314 0.160784 0.501961
476 t 380 306 392 324 0.635294 0.188235 0.160784 0.501961
477 t 155 380 162 399 0.666667 0.184314 0.188235 0.501961
478 t 288 645 293 660 0.427451 0.25098 0.239216 0.501961
479 t 208 206 228 237 0.956863 0.980392 0.956863 0.501961
480 t 60 38 113 68 0.847059 0.576471 0.470588 0.501961
481 t 170 176 176 228 0.266667 0.0470588 0.192157 0.501961
482 t 203 514 264 571 0.709804 0.717647 0.686275 0.501961
483 t 299 217 311 237 0.694118 0.513726 0.592157 0.501961
484 t 9 324 31 332 0.862745 0.882353 0.831373 0.501961
485 t 275 419 316 446 0.47451 0.447059 0.384314 0.501961
486 t 127 513 169 567 0.65098 0.611765 0.588235 0.501961
487 t 380 401 401 433 0.47451 0.160784 0.156863 0.501961
488 t 265 112 283 130 0.796078 0.666667 0.611765 0.501961
489 t 235 664 265 687 0.384314 0.254902 0.258824 0.501961
490 t 19 5 34 5 0.294118 0.309804 0.294118 0.501961
491 t 305 64 312 99 0.847059 0.576471 0.592157 0.501961
492 t 186 213 202 234 0.815686 0.423529 0.317647 0.501961
493 t 15 342 25 349 0.905882 0.929412 0.882353 0.501961
494 t 381 93 386 106 1 0.670588 0.666667 0.501961
495 t 29 267 34 280 0.541176 0.521569 0.47451 0.501961
496 t 387 112 395 129 0.976471 0.772549 0.72549 0.501961
497 t 126 293 131 374 0.827451 0.341176 0.172549 0.501961
498 t 188 83 192 96 0.619608 0.321569 0.321569 0.501961
499 t 0 598 21 652 0.627451 0.513726 0.431373 0.501961
500 t 171 125 175 150 0.737255 0.454902 0.478431 0.501961
501 t 224 117 229 123 0.772549 0.388235 0.203922 0.501961
14 Appendix A: Source Code Listings 184

14_animation05.cpp - 6656 bytes.


1 // Compile: clang++ -std=c++17 14_animation05.cpp -o 14_animation05
2
3 #include <algorithm>
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10 #include <sstream>
11 #include <iomanip>
12 #include <filesystem>
13 namespace fs = std::filesystem;
14
15 bool startsWithCaseInsensitive(std::string mainStr, std::string toMatch)
16 {
17 // Convert mainStr to lower case
18 std::transform(mainStr.begin(), mainStr.end(), mainStr.begin(), ::tolower);
19 // Convert toMatch to lower case
20 std::transform(toMatch.begin(), toMatch.end(), toMatch.begin(), ::tolower);
21 if(mainStr.find(toMatch) == 0)
22 return true;
23 else
24 return false;
25 }
26
27 int get_index(int x, int y, int width)
28 {
29 return x+width*y;
30 }
31
32 int calc_size(int width, int height)
33 {
34 return width*height;
35 }
36
37 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
38 at, float, float> &color, int width, int height)
39 {
40 for (int y=0;y<height;++y) {
41 for (int x=0;x<width;++x) {
42 image[get_index(x,y,width)]=color;
14 Appendix A: Source Code Listings 185

43 }
44 }
45 }
46
47 std::string get_filname(int ctr)
48 {
49 std::stringstream ss;
50 ss << "anim05/" << std::setfill ('0') << std::setw(4) << ctr << "-swye05.ppm";
51
52 return ss.str();
53 }
54
55 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
56 height, std::string filename)
57 {
58 std::tuple<float, float, float> color;
59 std::ofstream out(filename, std::ofstream::out);
60 out << "P3\n" << width << " " << height << "\n255\n";
61 for (int i=0;i<(width*height);++i)
62 {
63 color=image[i];
64 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
65 " " << int(std::get<2>(color)*255.0f) << '\n';
66 }
67 out.close();
68 }
69
70 std::tuple<int,int> get_width_and_height(const std::string str)
71 {
72 size_t start;
73 size_t end = 0;
74 std::vector<std::string> out;
75
76 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
77 {
78 end = str.find(' ', start);
79 out.push_back(str.substr(start, end - start));
80 }
81
82 int w=stoi(out[0]);
83 int h=stoi(out[1]);
84
85 return std::make_tuple(w,h);
14 Appendix A: Source Code Listings 186

86 }
87
88 std::tuple<int,int,int> get_color(const std::string str)
89 {
90 size_t start;
91 size_t end = 0;
92 std::vector<std::string> out;
93
94 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
95 {
96 end = str.find(' ', start);
97 out.push_back(str.substr(start, end - start));
98 }
99
100 int r=stoi(out[0]);
101 int g=stoi(out[1]);
102 int b=stoi(out[2]);
103
104 return std::make_tuple(r,g,b);
105 }
106
107 void read_image(std::vector<std::tuple<float, float, float>> &image, int &width, int\
108 &height, std::string filename)
109 {
110 std::ifstream infile(filename);
111 std::tuple<int, int, int> rcolor;
112 std::tuple<float, float, float> wcolor;
113 std::tuple<int,int> widthnheight;
114 std::string line;
115 int state=0;
116 bool done = false;
117
118 while (getline(infile, line))
119 {
120 if (startsWithCaseInsensitive(line,"P3") && state == 0) {
121 state=1;
122 }
123
124 if (!startsWithCaseInsensitive(line,"#") && !startsWithCaseInsensitive(line,"P3") \
125 && state == 1) {
126 widthnheight=get_width_and_height(line);
127 width=std::get<0>(widthnheight);
128 height=std::get<1>(widthnheight);
14 Appendix A: Source Code Listings 187

129 state=2;
130 }
131
132 if (startsWithCaseInsensitive(line,"255") && state == 2) {
133 state=3;
134 }
135
136 if (!(line.compare("255") == 0) && state == 3) {
137 rcolor=get_color(line);
138 wcolor=std::make_tuple(float(std::get<0>(rcolor)/255.0f), float(std::get<1>(
139 r)/255.0f), float(std::get<2>(rcolor)/255.0f));
140 image.push_back(wcolor);
141 done = true;
142 }
143 }
144 infile.close();
145 }
146
147 void update_x_and_y(int r, std::tuple<int,int> &walk1, std::tuple<int,int> &walk2, i\
148 nt width, int height)
149 {
150 int x1,y1,x2,y2;
151 std::tie(x1,y1) = walk1;
152 std::tie(x2,y2) = walk2;
153
154 switch(r) {
155 case 0:
156 x1+=1;
157 x2-=1;
158 break;
159 case 1:
160 x1-=1;
161 x2+=1;
162 break;
163 case 2:
164 y1+=1;
165 y2-=1;
166 break;
167 case 3:
168 y1-=1;
169 y2+=1;
170 break;
171 }
14 Appendix A: Source Code Listings 188

172
173 if (x1 < 0) {
174 x1 = 0;
175 } else if (x1 > width-1) {
176 x1=width-1;
177 }
178
179 if (x2 < 0) {
180 x2 = 0;
181 } else if (x2 > width-1) {
182 x2=width-1;
183 }
184
185 if (y1 < 0) {
186 y1 = 0;
187 } else if (y1 > height-1) {
188 y1 = height-1;
189 }
190
191 if (y2 < 0) {
192 y2 = 0;
193 } else if (y2 > height-1) {
194 y2 = height-1;
195 }
196
197 walk1=std::make_tuple(x1,y1);
198 walk2=std::make_tuple(x2,y2);
199 }
200
201 void blended_two_images(std::vector<std::tuple<float, float, float>> &blend1,std::ve\
202 ctor<std::tuple<float, float, float>> &blend2,int width,int height,float alpha)
203 {
204 std::tuple<float, float, float> color1=std::make_tuple(0.0f,0.0f,0.0f);
205 std::tuple<float, float, float> color2=std::make_tuple(0.0f,0.0f,0.0f);
206 float r=0.0f; float g=0.0f; float b=0.0f;
207
208 for (int y=0;y<height;++y) {
209 for (int x=0;x<width;++x) {
210 color1=blend1[get_index(x,y,width)];
211 color2=blend2[get_index(x,y,width)];
212 r = (std::get<0>(color2) * alpha) + (std::get<0>(color1) * (1.0f - alpha));
213 g = (std::get<1>(color2) * alpha) + (std::get<1>(color1) * (1.0f - alpha));
214 b = (std::get<2>(color2) * alpha) + (std::get<2>(color1) * (1.0f - alpha));
14 Appendix A: Source Code Listings 189

215 blend1[get_index(x,y,width)]=std::make_tuple(r, g, b);


216 }
217 }
218 }
219
220 void walker(std::vector<std::tuple<float, float, float>> &image1, std::vector<std::t\
221 uple<float, float, float>> &image2, int width, int height)
222 {
223 // Randomize and draw walkers
224 std::tuple<float, float, float> color;
225 int x1=width/2;
226 int y1=height/2;
227 int x2=width/2;
228 int y2=height/2;
229
230 std::random_device rd;
231 std::mt19937 mt(rd());
232 std::uniform_int_distribution<> dist(0, 3);
233
234 std::tuple<int,int> walk1=std::make_tuple(x1,y1);
235 std::tuple<int,int> walk2=std::make_tuple(x2,y2);
236
237 int ctr=0;
238 std::string fn="";
239 fn=get_filname(ctr++);
240 std::cout << fn << std::endl;
241 save_image(image2,width,height,fn);
242
243 int r=0;
244 for (int i=0;i<100000;++i) {
245 r=dist(mt);
246 update_x_and_y(r,walk1,walk2,width,height);
247 color=image1[get_index(std::get<0>(walk1), std::get<1>(walk1), width)];
248 image2[get_index(std::get<0>(walk1), std::get<1>(walk1), width)]=color;
249 color=image1[get_index(std::get<0>(walk2), std::get<1>(walk2), width)];
250 image2[get_index(std::get<0>(walk2), std::get<1>(walk2), width)]=color;
251 if (i%100 == 0) {
252 fn=get_filname(ctr++);
253 std::cout << fn << std::endl;
254 save_image(image2,width,height,fn);
255 }
256 }
257 }
14 Appendix A: Source Code Listings 190

258
259 int main()
260 {
261 fs::create_directory("anim05");
262 std::vector<std::tuple<float, float, float>> image1;
263 std::vector<std::tuple<float, float, float>> image2;
264 std::tuple<float, float, float> color=std::make_tuple(0.0f,0.0f,0.06666666667f);
265 int width=0;
266 int height=0;
267
268 read_image(image1, width, height, "ppm/04_helloworld.ppm");
269
270 image2.resize(calc_size(width, height));
271 clear_image(image2,color,width,height);
272 blended_two_images(image2,image1,width,height,0.2);
273 // Random Walker
274 walker(image1,image2,width,height);
275
276 // ffmpeg -framerate 15 -i %4d-swye05.ppm -c:v libx264 -r 30 swye05.mp4
277
278 return 0;
279 }

14_animation11.cpp - 4932 bytes.

1 // Compile: clang++ -std=c++17 14_animation11.cpp -o 14_animation11


2
3 #include <algorithm>
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10 #include <sstream>
11 #include <iomanip>
12 #include <filesystem>
13 namespace fs = std::filesystem;
14
15 bool startsWithCaseInsensitive(std::string mainStr, std::string toMatch)
16 {
17 // Convert mainStr to lower case
18 std::transform(mainStr.begin(), mainStr.end(), mainStr.begin(), ::tolower);
14 Appendix A: Source Code Listings 191

19 // Convert toMatch to lower case


20 std::transform(toMatch.begin(), toMatch.end(), toMatch.begin(), ::tolower);
21 if(mainStr.find(toMatch) == 0)
22 return true;
23 else
24 return false;
25 }
26
27 int get_index(int x, int y, int width)
28 {
29 return x+width*y;
30 }
31
32 int calc_size(int width, int height)
33 {
34 return width*height;
35 }
36
37 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
38 at,float,float> &colorRGB, int width, int height)
39 {
40 for (int y=0;y<height;++y) {
41 for (int x=0;x<width;++x) {
42 image[get_index(x,y,width)]=colorRGB;
43 }
44 }
45 }
46
47 std::tuple<int,int,float,float,float> parse_bginfo_line(const std::string str, int &\
48 width, int &height)
49 {
50 size_t start;
51 size_t end = 0;
52 std::vector<std::string> out;
53
54 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
55 {
56 end = str.find(' ', start);
57 out.push_back(str.substr(start, end - start));
58 }
59
60 width=stoi(out[1]);
61 height=stoi(out[2]);
14 Appendix A: Source Code Listings 192

62 float rf=stof(out[3]);
63 float gf=stof(out[4]);
64 float bf=stof(out[5]);
65
66 return std::make_tuple(width,height,rf,gf,bf);
67 }
68
69 std::tuple<int,int,int,int,float,float,float,float> parse_rect_line(const std::strin\
70 g str)
71 {
72 size_t start;
73 size_t end = 0;
74 std::vector<std::string> out;
75
76 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
77 {
78 end = str.find(' ', start);
79 out.push_back(str.substr(start, end - start));
80 }
81
82 int x1=stoi(out[1]);
83 int y1=stoi(out[2]);
84 int x2=stoi(out[3]);
85 int y2=stoi(out[4]);
86 float rf=stof(out[5]);
87 float gf=stof(out[6]);
88 float bf=stof(out[7]);
89 float af=stof(out[8]);
90
91 return std::make_tuple(x1,y1,x2,y2,rf,gf,bf,af);
92 }
93
94 std::tuple<float,float,float> blend_colors(std::tuple<float,float,float> &colorBGRGB\
95 , std::tuple<float,float,float,float> &colorRGBA)
96 {
97 float r=0.0f; float g=0.0f; float b=0.0f;
98 r = (std::get<0>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<0>(colorBGRGB) * \
99 (1.0 - std::get<3>(colorRGBA)));
100 g = (std::get<1>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<1>(colorBGRGB) * \
101 (1.0 - std::get<3>(colorRGBA)));
102 b = (std::get<2>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<2>(colorBGRGB) * \
103 (1.0 - std::get<3>(colorRGBA)));
104
14 Appendix A: Source Code Listings 193

105 return std::make_tuple(r,g,b);


106 }
107
108 void draw_filled_rect(int x1,int y1,int x2,int y2, std::vector<std::tuple<float, flo\
109 at, float>> &image, std::tuple<float,float,float,float> &colorRGBA, int width, int h
110 eight)
111 {
112 for (int i = y1; i < y2; i++) {
113 for (int j = x1; j < x2; j++) {
114 image[get_index(j,i,width)]=blend_colors(image[get_index(j,i,width)],colorRG
115 }
116 }
117 }
118
119 std::string get_filname(int ctr)
120 {
121 std::stringstream ss;
122 ss << "anim11/" << std::setfill ('0') << std::setw(3) << ctr << "-swye11.ppm";
123
124 return ss.str();
125 }
126
127 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
128 height, std::string filename)
129 {
130 std::tuple<float, float, float> color;
131 std::ofstream out(filename, std::ofstream::out);
132 out << "P3\n" << width << " " << height << "\n255\n";
133 for (int i=0;i<(width*height);++i)
134 {
135 color=image[i];
136 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
137 " " << int(std::get<2>(color)*255.0f) << '\n';
138 }
139 out.close();
140 }
141
142 int main()
143 {
144 fs::create_directory("anim11");
145 std::ifstream infile("11_squint_with_your_eyes.txt");
146 std::string line;
147 std::tuple<int,int,int,int,float,float,float,float> rect;
14 Appendix A: Source Code Listings 194

148 std::tuple<int,int,float,float,float> bginfo;


149 std::tuple<float,float,float> colorBGRGB;
150 std::tuple<float,float,float,float> colorRGBA;
151 int width,height,x1,y1,x2,y2;
152 float rf,gf,bf,af;
153 float bg_rf,bg_gf,bg_bf;
154 std::vector<std::tuple<float, float, float>> image;
155 int ctr=0;
156 std::string fn="";
157 while (getline(infile, line))
158 {
159 if (startsWithCaseInsensitive(line,"r")) {
160 rect=parse_rect_line(line);
161 std::tie(x1,y1,x2,y2,rf,gf,bf,af) = rect;
162 colorRGBA=std::make_tuple(rf,gf,bf,af);
163 draw_filled_rect(x1,y1,x2,y2,image,colorRGBA,width,height);
164 fn=get_filname(ctr++);
165 std::cout << fn << std::endl;
166 save_image(image,width,height,fn);
167 }
168
169 if (startsWithCaseInsensitive(line,"b")) {
170 bginfo=parse_bginfo_line(line,width,height);
171 std::tie(width,height,bg_rf,bg_gf,bg_bf) = bginfo;
172 image.resize(calc_size(width, height));
173 colorBGRGB=std::make_tuple(bg_rf,bg_gf,bg_bf);
174 clear_image(image,colorBGRGB,width,height);
175 fn=get_filname(ctr++);
176 std::cout << fn << std::endl;
177 save_image(image,width,height,fn);
178 }
179 }
180 infile.close();
181
182 // ffmpeg -framerate 15 -i %3d-swye11.ppm -c:v libx264 -r 30 swye11.mp4
183
184 return 0;
185 }
14 Appendix A: Source Code Listings 195

14_animation12.cpp - 7506 bytes.


1 // Compile: clang++ -std=c++17 14_animation12.cpp -o 14_animation12
2
3 #include <algorithm>
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10 #include <sstream>
11 #include <iomanip>
12 #include <filesystem>
13 namespace fs = std::filesystem;
14
15 bool startsWithCaseInsensitive(std::string mainStr, std::string toMatch)
16 {
17 // Convert mainStr to lower case
18 std::transform(mainStr.begin(), mainStr.end(), mainStr.begin(), ::tolower);
19 // Convert toMatch to lower case
20 std::transform(toMatch.begin(), toMatch.end(), toMatch.begin(), ::tolower);
21 if(mainStr.find(toMatch) == 0)
22 return true;
23 else
24 return false;
25 }
26
27 int get_index(int x, int y, int width)
28 {
29 return x+width*y;
30 }
31
32 int calc_size(int width, int height)
33 {
34 return width*height;
35 }
36
37 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
38 at,float,float> &color, int width, int height)
39 {
40 for (int y=0;y<height;++y) {
41 for (int x=0;x<width;++x) {
42 image[get_index(x,y,width)]=color;
14 Appendix A: Source Code Listings 196

43 }
44 }
45 }
46
47 std::tuple<int,int,int,float,float,float,float> parse_circle_line(const std::string \
48 str)
49 {
50 size_t start;
51 size_t end = 0;
52 std::vector<std::string> out;
53
54 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
55 {
56 end = str.find(' ', start);
57 out.push_back(str.substr(start, end - start));
58 }
59
60 int dx=stoi(out[1]);
61 int dy=stoi(out[2]);
62 int r=stoi(out[3]);
63 float rf=stof(out[4]);
64 float gf=stof(out[5]);
65 float bf=stof(out[6]);
66 float af=stof(out[7]);
67
68 return std::make_tuple(dx,dy,r,rf,gf,bf,af);
69 }
70
71 std::tuple<int,int,float,float,float> parse_bginfo_line(const std::string str, int &\
72 width, int &height)
73 {
74 size_t start;
75 size_t end = 0;
76 std::vector<std::string> out;
77
78 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
79 {
80 end = str.find(' ', start);
81 out.push_back(str.substr(start, end - start));
82 }
83
84 width=stoi(out[1]);
85 height=stoi(out[2]);
14 Appendix A: Source Code Listings 197

86 float rf=stof(out[3]);
87 float gf=stof(out[4]);
88 float bf=stof(out[5]);
89
90 return std::make_tuple(width,height,rf,gf,bf);
91 }
92
93 std::tuple<float,float,float> blend_colors(std::tuple<float,float,float> &colorBGRGB\
94 , std::tuple<float,float,float,float> &colorRGBA)
95 {
96 float r=0.0f; float g=0.0f; float b=0.0f;
97 r = (std::get<0>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<0>(colorBGRGB) * \
98 (1.0 - std::get<3>(colorRGBA)));
99 g = (std::get<1>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<1>(colorBGRGB) * \
100 (1.0 - std::get<3>(colorRGBA)));
101 b = (std::get<2>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<2>(colorBGRGB) * \
102 (1.0 - std::get<3>(colorRGBA)));
103
104 return std::make_tuple(r,g,b);
105 }
106
107 int find_region(int x, int y, int width, int height)
108 {
109 int code=0;
110 if(y >= height)
111 code |= 1; //top
112 else if(y < 0)
113 code |= 2; //bottom
114 if(x >= width)
115 code |= 4; //right
116 else if (x < 0)
117 code |= 8; //left
118 return(code);
119 }
120
121 bool clip_line(std::tuple<int, int, int, int> &coords1, std::tuple<int, int, int, in\
122 t> &coords2, int width, int height)
123 {
124 int x1=std::get<0>(coords1); int y1=std::get<1>(coords1); int x2=std::get<2>(coords\
125 1); int y2=std::get<3>(coords1);
126 int x3=0; int y3=0; int x4=0; int y4=0;
127 int code1=0, code2=0, codeout=0;
128 bool accept = 0, done=0;
14 Appendix A: Source Code Listings 198

129 code1 = find_region(x1, y1, width, height); //the region outcodes for the endpoints
130 code2 = find_region(x2, y2, width, height);
131 do //In theory, this can never end up in an infinite loop, it'll always come in one\
132 of the trivial cases eventually
133 {
134 if(!(code1 | code2)) accept = done = 1; //accept because both endpoints are in sc\
135 reen or on the border, trivial accept
136 else if(code1 & code2) done = 1; //the line isn't visible on screen, trivial reject
137 else //if no trivial reject or accept, continue the loop
138 {
139 int x, y;
140 codeout = code1 ? code1 : code2;
141 if(codeout & 1) //top
142 {
143 x = x1 + (x2 - x1) * (height - y1) / (y2 - y1);
144 y = height - 1;
145 }
146 else if(codeout & 2) //bottom
147 {
148 x = x1 + (x2 - x1) * -y1 / (y2 - y1);
149 y = 0;
150 }
151 else if(codeout & 4) //right
152 {
153 y = y1 + (y2 - y1) * (width - x1) / (x2 - x1);
154 x = width - 1;
155 }
156 else //left
157 {
158 y = y1 + (y2 - y1) * -x1 / (x2 - x1);
159 x = 0;
160 }
161 if(codeout == code1) //first endpoint was clipped
162 {
163 x1 = x; y1 = y;
164 code1 = find_region(x1, y1, width, height);
165 }
166 else //second endpoint was clipped
167 {
168 x2 = x; y2 = y;
169 code2 = find_region(x2, y2, width, height);
170 }
171 }
14 Appendix A: Source Code Listings 199

172 }
173 while(done == 0);
174 if(accept)
175 {
176 x3 = x1;
177 x4 = x2;
178 y3 = y1;
179 y4 = y2;
180 coords2=std::make_tuple(x3,y3,x4,y4);
181 return 1;
182 }
183 else
184 {
185 x3 = x4 = y3 = y4 = 0;
186 coords2=std::make_tuple(x3,y3,x4,y4);
187 return 0;
188 }
189 }
190
191 void draw_filled_circle(int x, int y, int radius, std::vector<std::tuple<float, floa\
192 t, float>> &image, std::tuple<float, float, float, float> &colorRGBA, int width, int
193 height)
194 {
195 int x0 = 0;
196 int y0 = radius;
197 int d = 3 - 2 * radius;
198 std::tuple<int, int, int, int> coords1;
199 std::tuple<int, int, int, int> coords2;
200 if (!radius) return;
201
202 auto drawline = [&](int sx, int ex, int ny)
203 {
204 coords1=std::make_tuple(sx,ny,ex,ny);
205 if (clip_line(coords1,coords2,width,height)) {
206 sx=std::get<0>(coords2);
207 ny=std::get<1>(coords2);
208 ex=std::get<2>(coords2);
209 for (int i = sx; i <= ex; i++) {
210 image[get_index(i, ny, width)]=blend_colors(image[get_index(i, ny, w
211 RGBA);
212 }
213 }
214 };
14 Appendix A: Source Code Listings 200

215
216 while (y0 >= x0)
217 {
218 drawline(x - x0, x + x0, y - y0);
219 drawline(x - y0, x + y0, y - x0);
220 drawline(x - x0, x + x0, y + y0);
221 drawline(x - y0, x + y0, y + x0);
222 if (d < 0) d += 4 * x0++ + 6;
223 else d += 4 * (x0++ - y0--) + 10;
224 }
225 }
226
227 std::string get_filname(int ctr)
228 {
229 std::stringstream ss;
230 ss << "anim12/" << std::setfill ('0') << std::setw(3) << ctr << "-swye12.ppm";
231
232 return ss.str();
233 }
234
235 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
236 height, std::string filename)
237 {
238 std::tuple<float, float, float> color;
239 std::ofstream out(filename, std::ofstream::out);
240 out << "P3\n" << width << " " << height << "\n255\n";
241 for (int i=0;i<(width*height);++i)
242 {
243 color=image[i];
244 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
245 " " << int(std::get<2>(color)*255.0f) << '\n';
246 }
247 out.close();
248 }
249
250 int main()
251 {
252 fs::create_directory("anim12");
253 std::ifstream infile("12_squint_with_your_eyes.txt");
254 std::string line;
255 std::tuple<int,int,int,float,float,float,float> circle;
256 std::tuple<int,int,float,float,float> bginfo;
257 std::tuple<float,float,float> colorBGRGB;
14 Appendix A: Source Code Listings 201

258 std::tuple<float,float,float,float> colorRGBA;


259 int width,height,xx,yy,r;
260 float rf,gf,bf,af;
261 float bg_rf,bg_gf,bg_bf;
262 std::vector<std::tuple<float, float, float>> image;
263 int ctr=0;
264 std::string fn="";
265 while (getline(infile, line))
266 {
267 if (startsWithCaseInsensitive(line,"c")) {
268 circle=parse_circle_line(line);
269 std::tie(xx,yy,r,rf,gf,bf,af) = circle;
270 colorRGBA=std::make_tuple(rf,gf,bf,af);
271 draw_filled_circle(xx,yy,r,image,colorRGBA,width,height);
272 fn=get_filname(ctr++);
273 std::cout << fn << std::endl;
274 save_image(image,width,height,fn);
275 }
276 if (startsWithCaseInsensitive(line,"b")) {
277 bginfo=parse_bginfo_line(line,width,height);
278 std::tie(width,height,bg_rf,bg_gf,bg_bf) = bginfo;
279 image.resize(calc_size(width, height));
280 colorBGRGB=std::make_tuple(bg_rf,bg_gf,bg_bf);
281 clear_image(image,colorBGRGB,width,height);
282 fn=get_filname(ctr++);
283 std::cout << fn << std::endl;
284 save_image(image,width,height,fn);
285 }
286 }
287 infile.close();
288
289 // ffmpeg -framerate 15 -i %3d-swye12.ppm -c:v libx264 -r 30 swye12.mp4
290
291 return 0;
292 }
14 Appendix A: Source Code Listings 202

14_animation13.cpp - 10112 bytes.


1 // Compile: clang++ -std=c++17 14_animation13.cpp -o 14_animation13
2
3 #include <algorithm>
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10 #include <sstream>
11 #include <iomanip>
12 #include <filesystem>
13 namespace fs = std::filesystem;
14
15 bool startsWithCaseInsensitive(std::string mainStr, std::string toMatch)
16 {
17 // Convert mainStr to lower case
18 std::transform(mainStr.begin(), mainStr.end(), mainStr.begin(), ::tolower);
19 // Convert toMatch to lower case
20 std::transform(toMatch.begin(), toMatch.end(), toMatch.begin(), ::tolower);
21 if(mainStr.find(toMatch) == 0)
22 return true;
23 else
24 return false;
25 }
26
27 int get_index(int x, int y, int width)
28 {
29 return x+width*y;
30 }
31
32 int calc_size(int width, int height)
33 {
34 return width*height;
35 }
36
37 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
38 at,float,float> &color, int width, int height)
39 {
40 for (int y=0;y<height;++y) {
41 for (int x=0;x<width;++x) {
42 image[get_index(x,y,width)]=color;
14 Appendix A: Source Code Listings 203

43 }
44 }
45 }
46
47 std::tuple<int,int,float,float,float> parse_bginfo_line(const std::string str, int w\
48 idth, int height)
49 {
50 size_t start;
51 size_t end = 0;
52 std::vector<std::string> out;
53
54 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
55 {
56 end = str.find(' ', start);
57 out.push_back(str.substr(start, end - start));
58 }
59
60 width=stoi(out[1]);
61 height=stoi(out[2]);
62 float rf=stof(out[3]);
63 float gf=stof(out[4]);
64 float bf=stof(out[5]);
65
66 return std::make_tuple(width,height,rf,gf,bf);
67 }
68
69 std::tuple<int,int,int,int,float,float,float,float> parse_triangle_line(const std::s\
70 tring str)
71 {
72 size_t start;
73 size_t end = 0;
74 std::vector<std::string> out;
75
76 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
77 {
78 end = str.find(' ', start);
79 out.push_back(str.substr(start, end - start));
80 }
81
82 int x1=stoi(out[1]);
83 int y1=stoi(out[2]);
84 int x2=stoi(out[3]);
85 int y2=stoi(out[4]);
14 Appendix A: Source Code Listings 204

86 float rf=stof(out[5]);
87 float gf=stof(out[6]);
88 float bf=stof(out[7]);
89 float af=stof(out[8]);
90
91 return std::make_tuple(x1,y1,x2,y2,rf,gf,bf,af);
92 }
93
94 std::tuple<float,float,float> blend_colors(std::tuple<float,float,float> &colorBGRGB\
95 , std::tuple<float,float,float,float> &colorRGBA)
96 {
97 float r=0.0f; float g=0.0f; float b=0.0f;
98 r = (std::get<0>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<0>(colorBGRGB) * \
99 (1.0 - std::get<3>(colorRGBA)));
100 g = (std::get<1>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<1>(colorBGRGB) * \
101 (1.0 - std::get<3>(colorRGBA)));
102 b = (std::get<2>(colorRGBA) * std::get<3>(colorRGBA)) + (std::get<2>(colorBGRGB) * \
103 (1.0 - std::get<3>(colorRGBA)));
104
105 return std::make_tuple(r,g,b);
106 }
107
108 int find_region(int x, int y, int width, int height)
109 {
110 int code=0;
111 if(y >= height)
112 code |= 1; //top
113 else if(y < 0)
114 code |= 2; //bottom
115 if(x >= width)
116 code |= 4; //right
117 else if (x < 0)
118 code |= 8; //left
119 return(code);
120 }
121
122 bool clip_line(std::tuple<int, int, int, int> &coords1, std::tuple<int, int, int, in\
123 t> &coords2, int width, int height)
124 {
125 int x1=std::get<0>(coords1); int y1=std::get<1>(coords1); int x2=std::get<2>(coords\
126 1); int y2=std::get<3>(coords1);
127 int x3=0; int y3=0; int x4=0; int y4=0;
128 int code1=0, code2=0, codeout=0;
14 Appendix A: Source Code Listings 205

129 bool accept = 0, done=0;


130 code1 = find_region(x1, y1, width, height); //the region outcodes for the endpoints
131 code2 = find_region(x2, y2, width, height);
132 do //In theory, this can never end up in an infinite loop, it'll always come in one\
133 of the trivial cases eventually
134 {
135 if(!(code1 | code2)) accept = done = 1; //accept because both endpoints are in sc\
136 reen or on the border, trivial accept
137 else if(code1 & code2) done = 1; //the line isn't visible on screen, trivial reject
138 else //if no trivial reject or accept, continue the loop
139 {
140 int x, y;
141 codeout = code1 ? code1 : code2;
142 if(codeout & 1) //top
143 {
144 x = x1 + (x2 - x1) * (height - y1) / (y2 - y1);
145 y = height - 1;
146 }
147 else if(codeout & 2) //bottom
148 {
149 x = x1 + (x2 - x1) * -y1 / (y2 - y1);
150 y = 0;
151 }
152 else if(codeout & 4) //right
153 {
154 y = y1 + (y2 - y1) * (width - x1) / (x2 - x1);
155 x = width - 1;
156 }
157 else //left
158 {
159 y = y1 + (y2 - y1) * -x1 / (x2 - x1);
160 x = 0;
161 }
162 if(codeout == code1) //first endpoint was clipped
163 {
164 x1 = x; y1 = y;
165 code1 = find_region(x1, y1, width, height);
166 }
167 else //second endpoint was clipped
168 {
169 x2 = x; y2 = y;
170 code2 = find_region(x2, y2, width, height);
171 }
14 Appendix A: Source Code Listings 206

172 }
173 }
174 while(done == 0);
175 if(accept)
176 {
177 x3 = x1;
178 x4 = x2;
179 y3 = y1;
180 y4 = y2;
181 coords2=std::make_tuple(x3,y3,x4,y4);
182 return 1;
183 }
184 else
185 {
186 x3 = x4 = y3 = y4 = 0;
187 coords2=std::make_tuple(x3,y3,x4,y4);
188 return 0;
189 }
190 }
191
192 void draw_filled_triangle(int x1, int y1, int x2, int y2, int x3, int y3, std::vecto\
193 r<std::tuple<float, float, float>> &image, std::tuple<float,float,float,float> &colo
194 rRGBA, int width, int height)
195 {
196 std::tuple<int, int, int, int> coords1;
197 std::tuple<int, int, int, int> coords2;
198 auto SWAP = [](int &x, int &y) { int t = x; x = y; y = t; };
199 auto drawline = [&](int sx, int ex, int ny)
200 {
201 coords1=std::make_tuple(sx,ny,ex,ny);
202 if (clip_line(coords1,coords2,width,height)) {
203 sx=std::get<0>(coords2);
204 ny=std::get<1>(coords2);
205 ex=std::get<2>(coords2);
206 for (int i = sx; i <= ex; i++) {
207 image[get_index(i, ny, width)]=blend_colors(image[get_index(i, ny, w
208 RGBA);
209 }
210 }
211 };
212
213 int t1x, t2x, y, minx, maxx, t1xp, t2xp;
214 bool changed1 = false;
14 Appendix A: Source Code Listings 207

215 bool changed2 = false;


216 int signx1, signx2, dx1, dy1, dx2, dy2;
217 int e1, e2;
218 if (y1>y2) { SWAP(y1, y2); SWAP(x1, x2); }
219 if (y1>y3) { SWAP(y1, y3); SWAP(x1, x3); }
220 if (y2>y3) { SWAP(y2, y3); SWAP(x2, x3); }
221
222 t1x = t2x = x1; y = y1;
223 dx1 = (int)(x2 - x1); if (dx1<0) { dx1 = -dx1; signx1 = -1; }
224 else signx1 = 1;
225 dy1 = (int)(y2 - y1);
226
227 dx2 = (int)(x3 - x1); if (dx2<0) { dx2 = -dx2; signx2 = -1; }
228 else signx2 = 1;
229 dy2 = (int)(y3 - y1);
230
231 if (dy1 > dx1) {
232 SWAP(dx1, dy1);
233 changed1 = true;
234 }
235 if (dy2 > dx2) {
236 SWAP(dy2, dx2);
237 changed2 = true;
238 }
239
240 e2 = (int)(dx2 >> 1);
241 if (y1 == y2) goto next;
242 e1 = (int)(dx1 >> 1);
243
244 for (int i = 0; i < dx1;) {
245 t1xp = 0; t2xp = 0;
246 if (t1x<t2x) { minx = t1x; maxx = t2x; }
247 else { minx = t2x; maxx = t1x; }
248 while (i<dx1) {
249 i++;
250 e1 += dy1;
251 while (e1 >= dx1) {
252 e1 -= dx1;
253 if (changed1) t1xp = signx1;
254 else goto next1;
255 }
256 if (changed1) break;
257 else t1x += signx1;
14 Appendix A: Source Code Listings 208

258 }
259 next1:
260 while (1) {
261 e2 += dy2;
262 while (e2 >= dx2) {
263 e2 -= dx2;
264 if (changed2) t2xp = signx2;
265 else goto next2;
266 }
267 if (changed2) break;
268 else t2x += signx2;
269 }
270 next2:
271 if (minx>t1x) minx = t1x;
272 if (minx>t2x) minx = t2x;
273 if (maxx<t1x) maxx = t1x;
274 if (maxx<t2x) maxx = t2x;
275 drawline(minx, maxx, y);
276 if (!changed1) t1x += signx1;
277 t1x += t1xp;
278 if (!changed2) t2x += signx2;
279 t2x += t2xp;
280 y += 1;
281 if (y == y2) break;
282
283 }
284 next:
285 dx1 = (int)(x3 - x2); if (dx1<0) { dx1 = -dx1; signx1 = -1; }
286 else signx1 = 1;
287 dy1 = (int)(y3 - y2);
288 t1x = x2;
289
290 if (dy1 > dx1) {
291 SWAP(dy1, dx1);
292 changed1 = true;
293 }
294 else changed1 = false;
295
296 e1 = (int)(dx1 >> 1);
297
298 for (int i = 0; i <= dx1; i++) {
299 t1xp = 0; t2xp = 0;
300 if (t1x<t2x) { minx = t1x; maxx = t2x; }
14 Appendix A: Source Code Listings 209

301 else { minx = t2x; maxx = t1x; }


302 while (i<dx1) {
303 e1 += dy1;
304 while (e1 >= dx1) {
305 e1 -= dx1;
306 if (changed1) { t1xp = signx1; break; }
307 else goto next3;
308 }
309 if (changed1) break;
310 else t1x += signx1;
311 if (i<dx1) i++;
312 }
313 next3:
314 while (t2x != x3) {
315 e2 += dy2;
316 while (e2 >= dx2) {
317 e2 -= dx2;
318 if (changed2) t2xp = signx2;
319 else goto next4;
320 }
321 if (changed2) break;
322 else t2x += signx2;
323 }
324 next4:
325
326 if (minx>t1x) minx = t1x;
327 if (minx>t2x) minx = t2x;
328 if (maxx<t1x) maxx = t1x;
329 if (maxx<t2x) maxx = t2x;
330 drawline(minx, maxx, y);
331 if (!changed1) t1x += signx1;
332 t1x += t1xp;
333 if (!changed2) t2x += signx2;
334 t2x += t2xp;
335 y += 1;
336 if (y>y3) return;
337 }
338 }
339
340 std::string get_filname(int ctr)
341 {
342 std::stringstream ss;
343 ss << "anim13/" << std::setfill ('0') << std::setw(4) << ctr << "-swye13.ppm";
14 Appendix A: Source Code Listings 210

344
345 return ss.str();
346 }
347
348 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
349 height, std::string filename)
350 {
351 std::tuple<float, float, float> color;
352 std::ofstream out(filename, std::ofstream::out);
353 out << "P3\n" << width << " " << height << "\n255\n";
354 for (int i=0;i<(width*height);++i)
355 {
356 color=image[i];
357 out << int(std::get<0>(color)*255.0f) << " " << int(std::get<1>(color)*255.0f) << \
358 " " << int(std::get<2>(color)*255.0f) << '\n';
359 }
360 out.close();
361 }
362
363 int main()
364 {
365 fs::create_directory("anim13");
366 std::ifstream infile("13_squint_with_your_eyes.txt");
367 std::string line;
368 std::tuple<int,int,int,int,float,float,float,float> triangle;
369 std::tuple<int,int,float,float,float> bginfo;
370 std::tuple<float,float,float> colorBGRGB;
371 std::tuple<float,float,float,float> colorRGBA;
372 int width,height,x1,y1,x2,y2;
373 float rf,gf,bf,af;
374 float bg_rf,bg_gf,bg_bf;
375 std::vector<std::tuple<float, float, float>> image;
376 int ctr=0;
377 std::string fn="";
378 while (getline(infile, line))
379 {
380 if (startsWithCaseInsensitive(line,"t")) {
381 triangle=parse_triangle_line(line);
382 std::tie(x1,y1,x2,y2,rf,gf,bf,af) = triangle;
383 colorRGBA=std::make_tuple(rf,gf,bf,af);
384 draw_filled_triangle(x1,y2,x2,y1,x1,y1,image,colorRGBA,width,height);
385 fn=get_filname(ctr++);
386 std::cout << fn << std::endl;
14 Appendix A: Source Code Listings 211

387 save_image(image,width,height,fn);
388 draw_filled_triangle(x1,y2,x2,y1,x2,y2,image,colorRGBA,width,height);
389 fn=get_filname(ctr++);
390 std::cout << fn << std::endl;
391 save_image(image,width,height,fn);
392 }
393
394 if (startsWithCaseInsensitive(line,"b")) {
395 bginfo=parse_bginfo_line(line,width,height);
396 std::tie(width,height,bg_rf,bg_gf,bg_bf) = bginfo;
397 image.resize(calc_size(width, height));
398 colorBGRGB=std::make_tuple(bg_rf,bg_gf,bg_bf);
399 clear_image(image,colorBGRGB,width,height);
400 fn=get_filname(ctr++);
401 std::cout << fn << std::endl;
402 save_image(image,width,height,fn);
403 }
404 }
405 infile.close();
406
407 // ffmpeg -framerate 15 -i %4d-swye13.ppm -c:v libx264 -r 30 swye13.mp4
408
409 return 0;
410 }

15_radarchart.cpp - 13293 bytes.

1 // Compile: clang++ -std=c++17 15_radarchart.cpp -o 15_radarchart


2 #define _USE_MATH_DEFINES
3
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10 #include <algorithm>
11
12 int get_index(int x, int y, int width)
13 {
14 return x+width*y;
15 }
16
14 Appendix A: Source Code Listings 212

17 int calc_size(int width, int height)


18 {
19 return width*height;
20 }
21
22 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
23 height)
24 {
25 for (int y=0;y<height;++y) {
26 for (int x=0;x<width;++x) {
27 image[get_index(x,y,width)]=std::make_tuple(1.0f, 1.0f, 1.0f);
28 }
29 }
30 }
31
32 void draw_circle(int x, int y, int radius, std::vector<std::tuple<float, float, floa\
33 t>> &image, std::tuple<float, float, float> &color, int width, int height)
34 {
35 int x0 = 0;
36 int y0 = radius;
37 int d = 3 - 2 * radius;
38 int xx=0;
39 int yy=0;
40 unsigned char mask=255;
41 if (!radius) return;
42
43 while (y0 >= x0)
44 {
45 if (mask & 0x01) {xx=x + x0;yy=y - y0;image[get_index(xx, yy, width)]=color;}
46 if (mask & 0x02) {xx=x + y0;yy=y - x0;image[get_index(xx, yy, width)]=color;}
47 if (mask & 0x04) {xx=x + y0;yy=y + x0;image[get_index(xx, yy, width)]=color;}
48 if (mask & 0x08) {xx=x + x0;yy=y + y0;image[get_index(xx, yy, width)]=color;}
49 if (mask & 0x10) {xx=x - x0;yy=y + y0;image[get_index(xx, yy, width)]=color;}
50 if (mask & 0x20) {xx=x - y0;yy=y + x0;image[get_index(xx, yy, width)]=color;}
51 if (mask & 0x40) {xx=x - y0;yy=y - x0;image[get_index(xx, yy, width)]=color;}
52 if (mask & 0x80) {xx=x - x0;yy=y - y0;image[get_index(xx, yy, width)]=color;}
53 if (d < 0) d += 4 * x0++ + 6;
54 else d += 4 * (x0++ - y0--) + 10;
55 }
56 }
57
58 void draw_filled_circle(int x, int y, int radius, std::vector<std::tuple<float, floa\
59 t, float>> &image, std::tuple<float, float, float> &color, int width, int height)
14 Appendix A: Source Code Listings 213

60 {
61 int x0 = 0;
62 int y0 = radius;
63 int d = 3 - 2 * radius;
64 if (!radius) return;
65
66 auto drawline = [&](int sx, int ex, int ny)
67 {
68 for (int i = sx; i <= ex; i++)
69 image[get_index(i, ny, width)]=color;
70 };
71
72 while (y0 >= x0)
73 {
74 drawline(x - x0, x + x0, y - y0);
75 drawline(x - y0, x + y0, y - x0);
76 drawline(x - x0, x + x0, y + y0);
77 drawline(x - y0, x + y0, y + x0);
78 if (d < 0) d += 4 * x0++ + 6;
79 else d += 4 * (x0++ - y0--) + 10;
80 }
81 }
82
83 void floodfill_algorithm(int x, int y, std::vector<std::tuple<float, float, float>> \
84 &image, std::tuple<float, float, float> &ocolor, std::tuple<float, float, float> &nc
85 olor, int &width, int &height)
86 {
87 if ((x > 0) && (x < width) && (y > 0) && (y < height)) {
88 if (image[get_index(x,y,width)] == ocolor)
89 {
90 image[get_index(x,y,width)]=ncolor;
91 floodfill_algorithm(x+1,y,image,ocolor,ncolor,width,height);
92 floodfill_algorithm(x-1,y,image,ocolor,ncolor,width,height);
93 floodfill_algorithm(x,y+1,image,ocolor,ncolor,width,height);
94 floodfill_algorithm(x,y-1,image,ocolor,ncolor,width,height);
95 }
96 else return;
97 }
98 }
99
100 void get_all_ys(std::vector<int> &ys,std::vector<std::tuple<int,int>> &coords)
101 {
102 for (auto& c : coords) {
14 Appendix A: Source Code Listings 214

103 ys.push_back(std::get<1>(c));
104 }
105
106 sort(ys.begin(), ys.end());
107 ys.erase( unique( ys.begin(), ys.end() ), ys.end() );
108 }
109
110 void draw_line_coords(int x1, int y1, int x2, int y2,std::vector<std::tuple<int,int>\
111 > &coords)
112 {
113 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
114 dx = x2 - x1; dy = y2 - y1;
115 if (dx == 0)
116 {
117 if (y2 < y1) std::swap(y1, y2);
118 for (y = y1; y <= y2; y++)
119 coords.push_back(std::make_tuple(x1,y));
120 return;
121 }
122 if (dy == 0)
123 {
124 if (x2 < x1) std::swap(x1, x2);
125 for (x = x1; x <= x2; x++)
126 coords.push_back(std::make_tuple(x,y1));
127 return;
128 }
129 dx1 = abs(dx); dy1 = abs(dy);
130 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
131 if (dy1 <= dx1)
132 {
133 if (dx >= 0)
134 {
135 x = x1; y = y1; xe = x2;
136 }
137 else
138 {
139 x = x2; y = y2; xe = x1;
140 }
141 coords.push_back(std::make_tuple(x,y));
142 for (i = 0; x<xe; i++)
143 {
144 x = x + 1;
145 if (px<0)
14 Appendix A: Source Code Listings 215

146 px = px + 2 * dy1;
147 else
148 {
149 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
150 px = px + 2 * (dy1 - dx1);
151 }
152 coords.push_back(std::make_tuple(x,y));
153 }
154 }
155 else
156 {
157 if (dy >= 0)
158 {
159 x = x1; y = y1; ye = y2;
160 }
161 else
162 {
163 x = x2; y = y2; ye = y1;
164 }
165 coords.push_back(std::make_tuple(x,y));
166 for (i = 0; y<ye; i++)
167 {
168 y = y + 1;
169 if (py <= 0)
170 py = py + 2 * dx1;
171 else
172 {
173 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
174 py = py + 2 * (dx1 - dy1);
175 }
176 coords.push_back(std::make_tuple(x,y));
177 }
178 }
179 }
180
181 void draw_polygon(std::vector<std::tuple<int, int, int, int>> &polygon,std::vector<s\
182 td::tuple<float, float, float>> &image,std::tuple<float, float, float> &color, int w
183 idth, int height)
184 {
185 std::vector<std::tuple<int,int>> coords;
186
187 for (auto& po : polygon) {
188 draw_line_coords(std::get<0>(po),std::get<1>(po),std::get<2>(po),std::get<3>(po),c\
14 Appendix A: Source Code Listings 216

189 oords);
190 }
191
192 for (auto & e : coords) {
193 image[get_index(std::get<0>(e),std::get<1>(e),width)]=color;
194 }
195 }
196
197 void draw_filled_polygon(std::vector<std::tuple<int, int, int, int>> &polygon,std::v\
198 ector<std::tuple<float, float, float>> &image,std::tuple<float, float, float> &color
199 , int width, int height)
200 {
201 std::vector<std::tuple<int,int>> coords;
202
203 for (auto& po : polygon) {
204 draw_line_coords(std::get<0>(po),std::get<1>(po),std::get<2>(po),std::get<3>(po),c\
205 oords);
206 }
207
208 std::vector<int> ys;
209 std::vector<int> xs;
210 get_all_ys(ys,coords);
211 std::vector<std::tuple<int,int,int,int>> lines;
212
213 for (int search=0;search<=ys.size();++search)
214 {
215 for (auto& c : coords) {
216 if (std::get<1>(c) == ys[search]) {
217 xs.push_back(std::get<0>(c));
218 }
219 }
220 sort(xs.begin(), xs.end());
221 lines.push_back(std::make_tuple(xs.front(),ys[search],xs.back(),ys[search]));
222 xs.clear();
223 }
224
225 auto drawline = [&](int sx, int ex, int ny)
226 {
227 for (int i = sx; i <= ex; i++)
228 image[get_index(i, ny, width)]=color;
229 };
230
231 for (auto& l : lines) {
14 Appendix A: Source Code Listings 217

232 drawline(std::get<0>(l),std::get<2>(l),std::get<1>(l));
233 }
234 }
235
236 void draw_line(std::vector<std::tuple<float, float, float>> &image, std::tuple<int, \
237 int, int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
238 {
239 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
240 int y2=std::get<3>(coords);
241 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
242 dx = x2 - x1; dy = y2 - y1;
243 if (dx == 0)
244 {
245 if (y2 < y1) std::swap(y1, y2);
246 for (y = y1; y <= y2; y++)
247 image[get_index(x1,y,width)]=color;
248 return;
249 }
250 if (dy == 0)
251 {
252 if (x2 < x1) std::swap(x1, x2);
253 for (x = x1; x <= x2; x++)
254 image[get_index(x,y1,width)]=color;
255 return;
256 }
257 dx1 = abs(dx); dy1 = abs(dy);
258 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
259 if (dy1 <= dx1)
260 {
261 if (dx >= 0)
262 {
263 x = x1; y = y1; xe = x2;
264 }
265 else
266 {
267 x = x2; y = y2; xe = x1;
268 }
269 image[get_index(x,y,width)]=color;
270 for (i = 0; x<xe; i++)
271 {
272 x = x + 1;
273 if (px<0)
274 px = px + 2 * dy1;
14 Appendix A: Source Code Listings 218

275 else
276 {
277 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
278 px = px + 2 * (dy1 - dx1);
279 }
280 image[get_index(x,y,width)]=color;
281 }
282 }
283 else
284 {
285 if (dy >= 0)
286 {
287 x = x1; y = y1; ye = y2;
288 }
289 else
290 {
291 x = x2; y = y2; ye = y1;
292 }
293 image[get_index(x,y,width)]=color;
294 for (i = 0; y<ye; i++)
295 {
296 y = y + 1;
297 if (py <= 0)
298 py = py + 2 * dx1;
299 else
300 {
301 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
302 py = py + 2 * (dx1 - dy1);
303 }
304 image[get_index(x,y,width)]=color;
305 }
306 }
307 }
308
309 int find_region(int x, int y, int width, int height)
310 {
311 int code=0;
312 if(y >= height)
313 code |= 1; //top
314 else if(y < 0)
315 code |= 2; //bottom
316 if(x >= width)
317 code |= 4; //right
14 Appendix A: Source Code Listings 219

318 else if (x < 0)


319 code |= 8; //left
320 return(code);
321 }
322
323 bool clip_line(std::tuple<int, int, int, int> &coords1, std::tuple<int, int, int, in\
324 t> &coords2, int width, int height)
325 {
326 int x1=std::get<0>(coords1); int y1=std::get<1>(coords1); int x2=std::get<2>(coords\
327 1); int y2=std::get<3>(coords1);
328 int x3=0; int y3=0; int x4=0; int y4=0;
329 int code1=0, code2=0, codeout=0;
330 bool accept = 0, done=0;
331 code1 = find_region(x1, y1, width, height); //the region outcodes for the endpoints
332 code2 = find_region(x2, y2, width, height);
333 do //In theory, this can never end up in an infinite loop, it'll always come in one\
334 of the trivial cases eventually
335 {
336 if(!(code1 | code2)) accept = done = 1; //accept because both endpoints are in sc\
337 reen or on the border, trivial accept
338 else if(code1 & code2) done = 1; //the line isn't visible on screen, trivial reject
339 else //if no trivial reject or accept, continue the loop
340 {
341 int x, y;
342 codeout = code1 ? code1 : code2;
343 if(codeout & 1) //top
344 {
345 x = x1 + (x2 - x1) * (height - y1) / (y2 - y1);
346 y = height - 1;
347 }
348 else if(codeout & 2) //bottom
349 {
350 x = x1 + (x2 - x1) * -y1 / (y2 - y1);
351 y = 0;
352 }
353 else if(codeout & 4) //right
354 {
355 y = y1 + (y2 - y1) * (width - x1) / (x2 - x1);
356 x = width - 1;
357 }
358 else //left
359 {
360 y = y1 + (y2 - y1) * -x1 / (x2 - x1);
14 Appendix A: Source Code Listings 220

361 x = 0;
362 }
363 if(codeout == code1) //first endpoint was clipped
364 {
365 x1 = x; y1 = y;
366 code1 = find_region(x1, y1, width, height);
367 }
368 else //second endpoint was clipped
369 {
370 x2 = x; y2 = y;
371 code2 = find_region(x2, y2, width, height);
372 }
373 }
374 }
375 while(done == 0);
376 if(accept)
377 {
378 x3 = x1;
379 x4 = x2;
380 y3 = y1;
381 y4 = y2;
382 coords2=std::make_tuple(x3,y3,x4,y4);
383 return 1;
384 }
385 else
386 {
387 x3 = x4 = y3 = y4 = 0;
388 coords2=std::make_tuple(x3,y3,x4,y4);
389 return 0;
390 }
391 }
392
393 void get_angle_line(std::tuple<int, int, int, int> &coords,int x_cen,int y_cen,doubl\
394 e degrees,int length)
395 {
396 double angle = degrees * (M_PI / 180);
397 coords=std::make_tuple(x_cen,y_cen,int(double(x_cen) + cos(angle)*double(length)),i\
398 nt(double(y_cen) + sin(angle)*double(length)));
399 }
400
401 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
402 height, std::string filename)
403 {
14 Appendix A: Source Code Listings 221

404 std::tuple<float, float, float> color;


405 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);
406 out << "P6" << std::endl << width << ' ' << height << std::endl << "255" << std::en\
407 dl;
408
409 for (int i=0;i<(width*height);++i)
410 {
411 color=image[i];
412 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*255.0f) << char(\
413 std::get<2>(color)*255.0f);
414 }
415 out.close();
416 }
417
418 int main()
419 {
420 // Draw random lines (with line clipping).
421 std::vector<std::tuple<float, float, float>> image;
422
423
424 std::tuple<float,float,float> color=std::make_tuple(0.8470588235,0.8509803922,0.913\
425 7254902);
426 std::tuple<int, int, int, int> coord;
427 std::vector<std::tuple<int, int, int, int>> polygon;
428
429 int width=1920;
430 int height=1080;
431
432 image.resize(calc_size(width, height));
433 clear_image(image,width,height);
434
435 int x_cen=width/2;
436 int y_cen=height/2;
437 int length=y_cen*0.8;
438 double degrees=0.0;
439
440 coord=std::make_tuple(1248,540,1113,693);
441 polygon.push_back(coord);
442 coord=std::make_tuple(1113,693,960,756);
443 polygon.push_back(coord);
444 coord=std::make_tuple(960,756,858,642);
445 polygon.push_back(coord);
446 coord=std::make_tuple(858,642,888,540);
14 Appendix A: Source Code Listings 222

447 polygon.push_back(coord);
448 coord=std::make_tuple(888,540,807,388);
449 polygon.push_back(coord);
450 coord=std::make_tuple(807,388,959,252);
451 polygon.push_back(coord);
452 coord=std::make_tuple(959,252,1214,285);
453 polygon.push_back(coord);
454 coord=std::make_tuple(1214,285,1248,540);
455 polygon.push_back(coord);
456
457 draw_filled_polygon(polygon,image,color,width,height);
458 color=std::make_tuple(1.0,0.0,1.0);
459 draw_polygon(polygon,image,color,width,height);
460
461 //
462
463 color=std::make_tuple(0.0,0.0,0.0);
464 get_angle_line(coord,x_cen,y_cen,degrees,length);
465 if (clip_line(coord,coord,width,height)) {
466 draw_line(image,coord,color,width,height);
467 }
468 degrees=45.0;
469 get_angle_line(coord,x_cen,y_cen,degrees,length);
470 if (clip_line(coord,coord,width,height)) {
471 draw_line(image,coord,color,width,height);
472 }
473 degrees=90.0;
474 get_angle_line(coord,x_cen,y_cen,degrees,length);
475 if (clip_line(coord,coord,width,height)) {
476 draw_line(image,coord,color,width,height);
477 }
478 degrees=135.0;
479 get_angle_line(coord,x_cen,y_cen,degrees,length);
480 if (clip_line(coord,coord,width,height)) {
481 draw_line(image,coord,color,width,height);
482 }
483 degrees=180.0;
484 get_angle_line(coord,x_cen,y_cen,degrees,length);
485 if (clip_line(coord,coord,width,height)) {
486 draw_line(image,coord,color,width,height);
487 }
488 degrees=225.0;
489 get_angle_line(coord,x_cen,y_cen,degrees,length);
14 Appendix A: Source Code Listings 223

490 if (clip_line(coord,coord,width,height)) {
491 draw_line(image,coord,color,width,height);
492 }
493 degrees=270.0;
494 get_angle_line(coord,x_cen,y_cen,degrees,length);
495 if (clip_line(coord,coord,width,height)) {
496 draw_line(image,coord,color,width,height);
497 }
498 degrees=315.0;
499 get_angle_line(coord,x_cen,y_cen,degrees,length);
500 if (clip_line(coord,coord,width,height)) {
501 draw_line(image,coord,color,width,height);
502 }
503
504 // 432;72
505 draw_circle((width/2),(height/2),72,image,color,width,height);
506 draw_circle((width/2),(height/2),72*2,image,color,width,height);
507 draw_circle((width/2),(height/2),72*3,image,color,width,height);
508 draw_circle((width/2),(height/2),72*4,image,color,width,height);
509 draw_circle((width/2),(height/2),72*5,image,color,width,height);
510 draw_circle((width/2),(height/2),72*6,image,color,width,height);
511
512 color=std::make_tuple(1.0,1.0,1.0);
513 draw_filled_circle(x_cen,y_cen,71,image,color,width,height);
514
515 //
516 std::tuple<float,float,float> ncolor=std::make_tuple(0.8470588235,0.8509803922,0.91\
517 37254902);
518 floodfill_algorithm(x_cen,y_cen,image,color,ncolor,width,height);
519
520 save_image(image,width,height,"15_radarchart.ppm");
521
522 return 0;
523 }
14 Appendix A: Source Code Listings 224

15_weekchart.cpp - 7689 bytes.


1 // Compile: clang++ -std=c++17 15_weekchart.cpp -o 15_weekchart
2 #define _USE_MATH_DEFINES
3
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10 #include <algorithm>
11
12 int get_index(int x, int y, int width)
13 {
14 return x+width*y;
15 }
16
17 int calc_size(int width, int height)
18 {
19 return width*height;
20 }
21
22 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
23 height)
24 {
25 for (int y=0;y<height;++y) {
26 for (int x=0;x<width;++x) {
27 image[get_index(x,y,width)]=std::make_tuple(0.1254901961, 0.1294117647, 0.14
28 706);
29 }
30 }
31 }
32
33 void draw_filled_circle(int x, int y, int radius, std::vector<std::tuple<float, floa\
34 t, float>> &image, std::tuple<float, float, float> &color, int width, int height)
35 {
36 int x0 = 0;
37 int y0 = radius;
38 int d = 3 - 2 * radius;
39 if (!radius) return;
40
41 auto drawline = [&](int sx, int ex, int ny)
42 {
14 Appendix A: Source Code Listings 225

43 for (int i = sx; i <= ex; i++)


44 image[get_index(i, ny, width)]=color;
45 };
46
47 while (y0 >= x0)
48 {
49 drawline(x - x0, x + x0, y - y0);
50 drawline(x - y0, x + y0, y - x0);
51 drawline(x - x0, x + x0, y + y0);
52 drawline(x - y0, x + y0, y + x0);
53 if (d < 0) d += 4 * x0++ + 6;
54 else d += 4 * (x0++ - y0--) + 10;
55 }
56 }
57
58 void get_all_ys(std::vector<int> &ys,std::vector<std::tuple<int,int>> &coords)
59 {
60 for (auto& c : coords) {
61 ys.push_back(std::get<1>(c));
62 }
63
64 sort(ys.begin(), ys.end());
65 ys.erase( unique( ys.begin(), ys.end() ), ys.end() );
66 }
67
68 void draw_line_coords(int x1, int y1, int x2, int y2,std::vector<std::tuple<int,int>\
69 > &coords)
70 {
71 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
72 dx = x2 - x1; dy = y2 - y1;
73 if (dx == 0)
74 {
75 if (y2 < y1) std::swap(y1, y2);
76 for (y = y1; y <= y2; y++)
77 coords.push_back(std::make_tuple(x1,y));
78 return;
79 }
80 if (dy == 0)
81 {
82 if (x2 < x1) std::swap(x1, x2);
83 for (x = x1; x <= x2; x++)
84 coords.push_back(std::make_tuple(x,y1));
85 return;
14 Appendix A: Source Code Listings 226

86 }
87 dx1 = abs(dx); dy1 = abs(dy);
88 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
89 if (dy1 <= dx1)
90 {
91 if (dx >= 0)
92 {
93 x = x1; y = y1; xe = x2;
94 }
95 else
96 {
97 x = x2; y = y2; xe = x1;
98 }
99 coords.push_back(std::make_tuple(x,y));
100 for (i = 0; x<xe; i++)
101 {
102 x = x + 1;
103 if (px<0)
104 px = px + 2 * dy1;
105 else
106 {
107 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
108 px = px + 2 * (dy1 - dx1);
109 }
110 coords.push_back(std::make_tuple(x,y));
111 }
112 }
113 else
114 {
115 if (dy >= 0)
116 {
117 x = x1; y = y1; ye = y2;
118 }
119 else
120 {
121 x = x2; y = y2; ye = y1;
122 }
123 coords.push_back(std::make_tuple(x,y));
124 for (i = 0; y<ye; i++)
125 {
126 y = y + 1;
127 if (py <= 0)
128 py = py + 2 * dx1;
14 Appendix A: Source Code Listings 227

129 else
130 {
131 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
132 py = py + 2 * (dx1 - dy1);
133 }
134 coords.push_back(std::make_tuple(x,y));
135 }
136 }
137 }
138
139 void draw_wedge(int x_cen,int y_cen,int rad,int start_ang,int end_ang,std::vector<st\
140 d::tuple<float, float, float>> &image,std::tuple<float, float, float> &color, int wi
141 dth, int height)
142 {
143 std::vector<std::tuple<int,int>> coords;
144
145 float ang=(((start_ang<=end_ang)?start_ang:end_ang)*(M_PI/180));
146 float range=(((end_ang>start_ang)?end_ang:start_ang)*(M_PI/180));
147 float x=(rad*cos(ang));
148 float y=(rad*sin(ang));
149 do
150 {
151 coords.push_back(std::make_tuple((int)(x_cen+x+0.5),(int)(y_cen-y+0.5)));
152 ang+=0.001;
153 x=(rad*cos(ang));
154 y=(rad*sin(ang));
155 }
156 while(ang<=range);
157
158 std::tuple<int,int> co1=coords.front();
159 std::tuple<int,int> co2=coords.back();
160
161 draw_line_coords(x_cen,y_cen,std::get<0>(co1),std::get<1>(co1),coords);
162 draw_line_coords(x_cen,y_cen,std::get<0>(co2),std::get<1>(co2),coords);
163
164 for (auto & e : coords) {
165 image[get_index(std::get<0>(e),std::get<1>(e),width)]=color;
166 }
167 }
168
169 void draw_filled_wedge(int x_cen,int y_cen,int rad,int start_ang,int end_ang,std::ve\
170 ctor<std::tuple<float, float, float>> &image,std::tuple<float, float, float> &color,
171 int width, int height)
14 Appendix A: Source Code Listings 228

172 {
173 std::vector<std::tuple<int,int>> coords;
174
175 float ang=(((start_ang<=end_ang)?start_ang:end_ang)*(M_PI/180));
176 float range=(((end_ang>start_ang)?end_ang:start_ang)*(M_PI/180));
177 float x=(rad*cos(ang));
178 float y=(rad*sin(ang));
179 do
180 {
181 coords.push_back(std::make_tuple((int)(x_cen+x+0.5),(int)(y_cen-y+0.5)));
182 ang+=0.001;
183 x=(rad*cos(ang));
184 y=(rad*sin(ang));
185 }
186 while(ang<=range);
187
188 std::tuple<int,int> co1=coords.front();
189 std::tuple<int,int> co2=coords.back();
190
191 draw_line_coords(x_cen,y_cen,std::get<0>(co1),std::get<1>(co1),coords);
192 draw_line_coords(x_cen,y_cen,std::get<0>(co2),std::get<1>(co2),coords);
193
194 std::vector<int> ys;
195 std::vector<int> xs;
196 get_all_ys(ys,coords);
197 std::vector<std::tuple<int,int,int,int>> lines;
198
199 for (int search=0;search<=ys.size();++search)
200 {
201 for (auto& c : coords) {
202 if (std::get<1>(c) == ys[search]) {
203 xs.push_back(std::get<0>(c));
204 }
205 }
206 sort(xs.begin(), xs.end());
207 lines.push_back(std::make_tuple(xs.front(),ys[search],xs.back(),ys[search]));
208 xs.clear();
209 }
210
211 auto drawline = [&](int sx, int ex, int ny)
212 {
213 for (int i = sx; i <= ex; i++)
214 image[get_index(i, ny, width)]=color;
14 Appendix A: Source Code Listings 229

215 };
216
217 for (auto& l : lines) {
218 drawline(std::get<0>(l),std::get<2>(l),std::get<1>(l));
219 }
220 }
221
222 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
223 height, std::string filename)
224 {
225 std::tuple<float, float, float> color;
226 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);
227 out << "P6" << std::endl << width << ' ' << height << std::endl << "255" << std::en\
228 dl;
229
230 for (int i=0;i<(width*height);++i)
231 {
232 color=image[i];
233 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*255.0f) << char(\
234 std::get<2>(color)*255.0f);
235 }
236 out.close();
237 }
238
239 int main()
240 {
241 int width=1920;
242 int height=1080;
243
244 float a1[] = {0.89,1.00,0.86,0.84,0.80,0.87,0.86,0.92,0.82,0.91,0.85,0.80,1.00,0.87\
245 ,0.85,0.93,0.97,0.94,1.00,0.91,0.85,0.92,0.96,0.82,0.94,0.83,0.93,0.95,1.00,0.98,0.9
246 6,0.97,0.80,1.00,0.93,0.86,0.90,0.93,0.92,0.90,0.92,0.98,0.84,1.00,0.92,0.92,0.83,0.
247 89,0.90,0.99,0.97,0.92};
248 float a2[] = {0.70,0.51,0.69,0.52,0.56,0.59,0.50,0.68,0.73,0.46,0.40,0.56,0.41,0.54\
249 ,0.64,0.45,0.56,0.45,0.41,0.60,0.68,0.45,0.65,0.60,0.65,0.66,0.57,0.47,0.47,0.58,0.5
250 7,0.48,0.41,0.62,0.50,0.46,0.75,0.50,0.71,0.56,0.57,0.53,0.75,0.45,0.51,0.47,0.71,0.
251 74,0.51,0.72,0.56,0.71};
252 float a3[] = {0.21,0.11,0.13,0.21,0.04,0.21,0.24,0.26,0.32,0.28,0.09,0.15,0.19,0.28\
253 ,0.22,0.25,0.03,0.22,0.18,0.15,0.31,0.08,0.27,0.07,0.08,0.10,0.08,0.23,0.17,0.11,0.3
254 4,0.29,0.10,0.09,0.06,0.31,0.32,0.22,0.26,0.21,0.14,0.13,0.08,0.15,0.27,0.04,0.06,0.
255 17,0.10,0.02,0.12,0.17};
256
257 std::vector<std::tuple<float, float, float>> image;
14 Appendix A: Source Code Listings 230

258 std::tuple<float,float,float> bg=std::make_tuple(0.3058823529,0.2509803922,0.227450\


259 9804);
260 std::tuple<float,float,float> color1=std::make_tuple(0.5254901961,0.4588235294,0.39\
261 60784314);
262 std::tuple<float,float,float> color2=std::make_tuple(0.6352941176,0.6196078431,0.6);
263 std::tuple<float,float,float> color3=std::make_tuple(0.8117647059,0.7607843137,0.70\
264 58823529);
265
266 image.resize(calc_size(width, height));
267 clear_image(image,width,height);
268
269 int x_cen,y_cen,rad;
270 double start_ang,end_ang,length,rad_size,color_size,color_num=0.0;
271 x_cen=width/2;
272 y_cen=height/2;
273 rad=y_cen*0.8;
274 start_ang=0;
275 end_ang=6.9230769231;
276 image[get_index(x_cen,y_cen, width)]=color1;
277 rad_size=rad/52;
278 length=rad;
279 color_size=1.0/52;
280
281 draw_filled_circle(x_cen,y_cen,y_cen*0.9,image,bg,width,height);
282
283 for (int i=0;i<52;++i) {
284 draw_filled_wedge(x_cen,y_cen,length*a1[i],start_ang,end_ang,image,color1,width,he\
285 ight);
286 draw_filled_wedge(x_cen,y_cen,length*a2[i],start_ang,end_ang,image,color2,width,he\
287 ight);
288 draw_filled_wedge(x_cen,y_cen,length*a3[i],start_ang,end_ang,image,color3,width,he\
289 ight);
290 start_ang=end_ang;end_ang+=6.9230769231;
291 }
292
293 save_image(image,width,height,"15_weekchart.ppm");
294
295 return 0;
296 }
14 Appendix A: Source Code Listings 231

15_read_p6_ppm.cpp - 2283 bytes.


1 // Pre: cp 15_weekchart.ppm 15_read_p6_ppm.ppm
2 // Compile: clang++ -std=c++17 15_read_p6_ppm.cpp -o 15_read_p6_ppm
3
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10
11 void load_image(std::vector<std::tuple<float, float, float>> &image, int &width, int\
12 &height, std::string filename)
13 {
14 std::string magic;
15 int max;
16 uint8_t buffer[3];
17 std::tuple<float,float,float> color;
18
19 std::ifstream in(filename, std::ifstream::binary);
20
21 if (!in.is_open())
22 {
23 std::cout << "Can't open " << filename << std::endl;
24 exit(1);
25 }
26
27 in >> magic;
28 in.seekg(1, in.cur);
29 char c;
30 in.get(c);
31 if (c == '#')
32 {
33 // We got comments in the PPM image and skip the comments
34 while (c != '\n')
35 {
36 in.get(c);
37 }
38 }
39 else
40 {
41 in.seekg(-1, in.cur);
42 }
14 Appendix A: Source Code Listings 232

43
44 in >> width >> height >> max;
45
46 if (max != 255) {
47 std::cout << "Not 8 bit per rgb color." << std::endl;
48 exit(1);
49 }
50
51 if (magic == "P6")
52 {
53 // Move curser once to skip '\n'
54 in.seekg(1, in.cur);
55
56 for (int i = 0; i < width * height; ++i)
57 {
58 in.read(reinterpret_cast<char *>(buffer), 3);
59 color=std::make_tuple(float(float(buffer[0])/255.0),float(float(buffer[1])/2
60 ,float(float(buffer[2])/255.0));
61 image.push_back(color);
62 }
63 } else {
64 std::cout << "Not a P6 file." << std::endl;
65 exit(1);
66 }
67
68 in.close();
69 }
70
71 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
72 height, std::string filename)
73 {
74 std::tuple<float, float, float> color;
75 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);
76 out << "P6" << std::endl << width << ' ' << height << std::endl << "255" << std::en\
77 dl;
78
79 for (int i=0;i<(width*height);++i)
80 {
81 color=image[i];
82 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*255.0f) << char(\
83 std::get<2>(color)*255.0f);
84 }
85 out.close();
14 Appendix A: Source Code Listings 233

86 }
87
88 int main()
89 {
90 std::vector<std::tuple<float, float, float>> image;
91 int width,height;
92
93 std::cout << "loading: 15_read_p6_ppm.ppm" << std::endl;
94 load_image(image,width,height,"15_read_p6_ppm.ppm");
95 std::cout << "15_read_p6_ppm.ppm - w: " << width << " " << "h: " << height << std::\
96 endl;
97
98 std::cout << "saving: 15_read_p6_ppm_.ppm." << std::endl;
99 save_image(image,width,height,"15_read_p6_ppm_.ppm");
100
101 return 0;
102 }

15_draw_font.cpp - 37008 bytes.

1 // Compile: clang++ -std=c++17 15_draw_font.cpp -o 15_draw_font


2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <random>
8 #include <cmath>
9
10 void get_width_from_height(int &width, int height)
11 {
12 int half = height / 2;
13 width = half * 3;
14 }
15
16 void get_margin_from_height(int &margin,int height)
17 {
18 margin = int(float(height) * 0.3);
19 }
20
21 int get_index(int x, int y, int width)
22 {
23 return x+width*y;
14 Appendix A: Source Code Listings 234

24 }
25
26 int calc_size(int width, int height, int margin)
27 {
28 return (width+margin)*(height+margin);
29 }
30
31 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
32 height, int margin)
33 {
34 for (int y=0;y<(height+margin);++y) {
35 for (int x=0;x<(width+margin);++x) {
36 image[get_index(x,y,(width+margin))]=std::make_tuple(1.0f, 1.0f, 1.0f);
37 }
38 }
39 }
40
41 void draw_filled_circle(int x, int y, int radius, std::vector<std::tuple<float, floa\
42 t, float>> &image, std::tuple<float, float, float> &color, int width, int height, in
43 t margin)
44 {
45 int x0 = 0;
46 int y0 = radius;
47 int d = 3 - 2 * radius;
48 if (!radius) return;
49
50 auto drawline = [&](int sx, int ex, int ny)
51 {
52 for (int i = sx; i <= ex; i++)
53 image[get_index(i, ny, width+margin)]=color;
54 };
55
56 while (y0 >= x0)
57 {
58 drawline(x - x0, x + x0, y - y0);
59 drawline(x - y0, x + y0, y - x0);
60 drawline(x - x0, x + x0, y + y0);
61 drawline(x - y0, x + y0, y + x0);
62 if (d < 0) d += 4 * x0++ + 6;
63 else d += 4 * (x0++ - y0--) + 10;
64 }
65 }
66
14 Appendix A: Source Code Listings 235

67 void get_line_points(std::vector<std::tuple<int,int>> &points, std::tuple<int, int, \


68 int, int> &coords, std::tuple<float,float,float> &color, int width, int height, int
69 margin)
70 {
71 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
72 int y2=std::get<3>(coords);
73 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
74 dx = x2 - x1; dy = y2 - y1;
75 if (dx == 0)
76 {
77 if (y2 < y1) std::swap(y1, y2);
78 for (y = y1; y <= y2; y++)
79 points.push_back(std::make_tuple(x1,y));
80 return;
81 }
82 if (dy == 0)
83 {
84 if (x2 < x1) std::swap(x1, x2);
85 for (x = x1; x <= x2; x++)
86 points.push_back(std::make_tuple(x,y1));
87 return;
88 }
89 dx1 = abs(dx); dy1 = abs(dy);
90 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
91 if (dy1 <= dx1)
92 {
93 if (dx >= 0)
94 {
95 x = x1; y = y1; xe = x2;
96 }
97 else
98 {
99 x = x2; y = y2; xe = x1;
100 }
101 points.push_back(std::make_tuple(x,y));
102 for (i = 0; x<xe; i++)
103 {
104 x = x + 1;
105 if (px<0)
106 px = px + 2 * dy1;
107 else
108 {
109 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
14 Appendix A: Source Code Listings 236

110 px = px + 2 * (dy1 - dx1);


111 }
112 points.push_back(std::make_tuple(x,y));
113 }
114 }
115 else
116 {
117 if (dy >= 0)
118 {
119 x = x1; y = y1; ye = y2;
120 }
121 else
122 {
123 x = x2; y = y2; ye = y1;
124 }
125 points.push_back(std::make_tuple(x,y));
126 for (i = 0; y<ye; i++)
127 {
128 y = y + 1;
129 if (py <= 0)
130 py = py + 2 * dx1;
131 else
132 {
133 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
134 py = py + 2 * (dx1 - dy1);
135 }
136 points.push_back(std::make_tuple(x,y));
137 }
138 }
139 }
140
141 void draw_font_A(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
142 oat> &color, int width, int height, int margin)
143 {
144 // A
145 //points
146 float arr[4][2] = {{0.0,1.0},{0.5,0.0},{1.0,1.0},{0.0,0.6}};
147 //lines
148 int arr2[3][2] = {{0,1},{1,2},{2,3}};
149 std::tuple<int, int, int, int> coords;
150 int halfmargin=margin/2;
151
152 for (int i=0;i<3;++i) {
14 Appendix A: Source Code Listings 237

153 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\


154 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0])+halfmargin, int(height*arr[a
155 rr2[i][1]][1])+halfmargin);
156 get_line_points(points,coords,color,width,height,margin);
157 }
158 }
159
160 void draw_font_B(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
161 oat> &color, int width, int height, int margin)
162 {
163 // B
164 //points
165 float arr[7][2] = {{0.0,0.0},{1.0,0.0},{1.0,0.4},{0.5,0.5},{1.0,0.6},{1.0,1.0},{0.0\
166 ,1.0}};
167 //lines
168 int arr2[7][2] = {{0,1},{1,2},{2,3},{3,4},{4,5},{5,6},{6,0}};
169 std::tuple<int, int, int, int> coords;
170 int halfmargin=margin/2;
171
172 for (int i=0;i<7;++i) {
173 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
174 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
175 rr2[i][1]][1])+halfmargin);
176 get_line_points(points,coords,color,width,height,margin);
177 }
178 }
179
180 void draw_font_C(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
181 oat> &color, int width, int height, int margin)
182 {
183 // C
184 //points
185 float arr[4][2] = {{0.5,0.0},{0.0,0.0},{0.0,1.0},{1.0,1.0}};
186 //lines
187 int arr2[3][2] = {{0,1},{1,2},{2,3}};
188 std::tuple<int, int, int, int> coords;
189 int halfmargin=margin/2;
190
191 for (int i=0;i<3;++i) {
192 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
193 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
194 rr2[i][1]][1])+halfmargin);
195 get_line_points(points,coords,color,width,height,margin);
14 Appendix A: Source Code Listings 238

196 }
197 }
198
199 void draw_font_D(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
200 oat> &color, int width, int height, int margin)
201 {
202 // D
203 //points
204 float arr[4][2] = {{0.0,0.0},{0.0,1.0},{1.0,1.0},{1.0,0.4}};
205 //lines
206 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,0}};
207 std::tuple<int, int, int, int> coords;
208 int halfmargin=margin/2;
209
210 for (int i=0;i<4;++i) {
211 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
212 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
213 rr2[i][1]][1])+halfmargin);
214 get_line_points(points,coords,color,width,height,margin);
215 }
216 }
217
218 void draw_font_E(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
219 oat> &color, int width, int height, int margin)
220 {
221 // E
222 //points
223 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.5},{0.5,0.5},{0.0,1.0},{1.0,1.0}};
224 //lines
225 int arr2[4][2] = {{0,1},{1,2},{2,3},{4,5}};
226 std::tuple<int, int, int, int> coords;
227 int halfmargin=margin/2;
228
229 for (int i=0;i<4;++i) {
230 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
231 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
232 rr2[i][1]][1])+halfmargin);
233 get_line_points(points,coords,color,width,height,margin);
234 }
235 }
236
237 void draw_font_F(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
238 oat> &color, int width, int height, int margin)
14 Appendix A: Source Code Listings 239

239 {
240 // F
241 //points
242 float arr[5][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.4},{0.5,0.4},{0.0,1.0}};
243 //lines
244 int arr2[4][2] = {{0,1},{1,2},{2,3},{2,4}};
245 std::tuple<int, int, int, int> coords;
246 int halfmargin=margin/2;
247
248 for (int i=0;i<4;++i) {
249 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
250 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
251 rr2[i][1]][1])+halfmargin);
252 get_line_points(points,coords,color,width,height,margin);
253 }
254 }
255
256 void draw_font_G(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
257 oat> &color, int width, int height, int margin)
258 {
259 // G
260 //points
261 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,1.0},{1.0,1.0},{1.0,0.6},{0.5,0.6}};
262 //lines
263 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
264 std::tuple<int, int, int, int> coords;
265 int halfmargin=margin/2;
266
267 for (int i=0;i<5;++i) {
268 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
269 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
270 rr2[i][1]][1])+halfmargin);
271 get_line_points(points,coords,color,width,height,margin);
272 }
273 }
274
275 void draw_font_H(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
276 oat> &color, int width, int height, int margin)
277 {
278 // H
279 //points
280 float arr[6][2] = {{0.0,0.0},{0.0,1.0},{1.0,0.0},{1.0,1.0},{0.0,0.6},{1.0,0.6}};
281 //lines
14 Appendix A: Source Code Listings 240

282 int arr2[3][2] = {{0,1},{2,3},{4,5}};


283 std::tuple<int, int, int, int> coords;
284 int halfmargin=margin/2;
285
286 for (int i=0;i<3;++i) {
287 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
288 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
289 rr2[i][1]][1])+halfmargin);
290 get_line_points(points,coords,color,width,height,margin);
291 }
292 }
293
294 void draw_font_I(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
295 oat> &color, int width, int height, int margin)
296 {
297 // I
298 //points
299 float arr[2][2] = {{0.5,0.0},{0.5,1.0}};
300 //lines
301 int arr2[1][2] = {{0,1}};
302 std::tuple<int, int, int, int> coords;
303 int halfmargin=margin/2;
304
305 for (int i=0;i<1;++i) {
306 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
307 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
308 rr2[i][1]][1])+halfmargin);
309 get_line_points(points,coords,color,width,height,margin);
310 }
311 }
312
313 void draw_font_J(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
314 oat> &color, int width, int height, int margin)
315 {
316 // J
317 //points
318 float arr[4][2] = {{0.5,0.0},{0.5,1.0},{0.25,1.0},{0.0,0.6}};
319 //lines
320 int arr2[3][2] = {{0,1},{1,2},{2,3}};
321 std::tuple<int, int, int, int> coords;
322 int halfmargin=margin/2;
323
324 for (int i=0;i<3;++i) {
14 Appendix A: Source Code Listings 241

325 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\


326 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
327 rr2[i][1]][1])+halfmargin);
328 get_line_points(points,coords,color,width,height,margin);
329 }
330 }
331
332 void draw_font_K(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
333 oat> &color, int width, int height, int margin)
334 {
335 // K
336 //points
337 float arr[5][2] = {{0.0,0.0},{0.0,0.4},{0.5,0.0},{1.0,1.0},{0.0,1.0}};
338 //lines
339 int arr2[4][2] = {{0,1},{1,2},{1,3},{1,4}};
340 std::tuple<int, int, int, int> coords;
341 int halfmargin=margin/2;
342
343 for (int i=0;i<4;++i) {
344 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
345 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
346 rr2[i][1]][1])+halfmargin);
347 get_line_points(points,coords,color,width,height,margin);
348 }
349 }
350
351 void draw_font_L(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
352 oat> &color, int width, int height, int margin)
353 {
354 // L
355 //points
356 float arr[3][2] = {{0.0,0.0},{0.0,1.0},{1.0,1.0}};
357 //lines
358 int arr2[2][2] = {{0,1},{1,2}};
359 std::tuple<int, int, int, int> coords;
360 int halfmargin=margin/2;
361
362 for (int i=0;i<2;++i) {
363 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
364 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
365 rr2[i][1]][1])+halfmargin);
366 get_line_points(points,coords,color,width,height,margin);
367 }
14 Appendix A: Source Code Listings 242

368 }
369
370 void draw_font_M(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
371 oat> &color, int width, int height, int margin)
372 {
373 // M
374 //points
375 float arr[5][2] = {{0.0,1.0},{0.0,0.0},{0.5,0.3},{1.0,0.0},{1.0,1.0}};
376 //lines
377 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,4}};
378 std::tuple<int, int, int, int> coords;
379 int halfmargin=margin/2;
380
381 for (int i=0;i<4;++i) {
382 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
383 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
384 rr2[i][1]][1])+halfmargin);
385 get_line_points(points,coords,color,width,height,margin);
386 }
387 }
388
389 void draw_font_N(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
390 oat> &color, int width, int height, int margin)
391 {
392 // N
393 //points
394 float arr[6][2] = {{0.0,0.0},{0.0,1.0},{1.0,0.0},{1.0,1.0},{0.0,0.0},{1.0,1.0}};
395 //lines
396 int arr2[3][2] = {{0,1},{2,3},{4,5}};
397 std::tuple<int, int, int, int> coords;
398 int halfmargin=margin/2;
399
400 for (int i=0;i<3;++i) {
401 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
402 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
403 rr2[i][1]][1])+halfmargin);
404 get_line_points(points,coords,color,width,height,margin);
405 }
406 }
407
408 void draw_font_O(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
409 oat> &color, int width, int height, int margin)
410 {
14 Appendix A: Source Code Listings 243

411 // O
412 //points
413 float arr[4][2] = {{1.0,0.0},{1.0,1.0},{0.0,1.0},{0.0,0.0}};
414 //lines
415 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,0}};
416 std::tuple<int, int, int, int> coords;
417 int halfmargin=margin/2;
418
419 for (int i=0;i<4;++i) {
420 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
421 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
422 rr2[i][1]][1])+halfmargin);
423 get_line_points(points,coords,color,width,height,margin);
424 }
425 }
426
427 void draw_font_P(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
428 oat> &color, int width, int height, int margin)
429 {
430 // P
431 //points
432 float arr[5][2] = {{0.0,1.0},{0.0,0.0},{1.0,0.0},{1.0,0.3},{0.0,0.6}};
433 //lines
434 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,4}};
435 std::tuple<int, int, int, int> coords;
436 int halfmargin=margin/2;
437
438 for (int i=0;i<4;++i) {
439 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
440 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
441 rr2[i][1]][1])+halfmargin);
442 get_line_points(points,coords,color,width,height,margin);
443 }
444 }
445
446 void draw_font_Q(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
447 oat> &color, int width, int height, int margin)
448 {
449 // Q
450 //points
451 float arr[7][2] = {{1.0,0.6},{1.0,0.0},{0.0,0.0},{0.0,1.0},{0.5,1.0},{0.5,0.6},{1.0\
452 ,1.0}};
453 //lines
14 Appendix A: Source Code Listings 244

454 int arr2[6][2] = {{0,1},{1,2},{2,3},{3,4},{4,0},{5,6}};


455 std::tuple<int, int, int, int> coords;
456 int halfmargin=margin/2;
457
458 for (int i=0;i<6;++i) {
459 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
460 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
461 rr2[i][1]][1])+halfmargin);
462 get_line_points(points,coords,color,width,height,margin);
463 }
464 }
465
466 void draw_font_R(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
467 oat> &color, int width, int height, int margin)
468 {
469 // R
470 //points
471 float arr[6][2] = {{0.0,1.0},{0.0,0.0},{1.0,0.0},{1.0,0.3},{0.0,0.6},{1.0,1.0}};
472 //lines
473 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
474 std::tuple<int, int, int, int> coords;
475 int halfmargin=margin/2;
476
477 for (int i=0;i<5;++i) {
478 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
479 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
480 rr2[i][1]][1])+halfmargin);
481 get_line_points(points,coords,color,width,height,margin);
482 }
483 }
484
485 void draw_font_S(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
486 oat> &color, int width, int height, int margin)
487 {
488 // S
489 //points
490 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.4},{1.0,0.6},{1.0,1.0},{0.0,1.0}};
491 //lines
492 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
493 std::tuple<int, int, int, int> coords;
494 int halfmargin=margin/2;
495
496 for (int i=0;i<5;++i) {
14 Appendix A: Source Code Listings 245

497 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\


498 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
499 rr2[i][1]][1])+halfmargin);
500 get_line_points(points,coords,color,width,height,margin);
501 }
502 }
503
504 void draw_font_T(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
505 oat> &color, int width, int height, int margin)
506 {
507 // T
508 //points
509 float arr[3][2] = {{0.0,0.0},{1.0,0.0},{1.0,1.0}};
510 //lines
511 int arr2[2][2] = {{0,1},{1,2}};
512 std::tuple<int, int, int, int> coords;
513 int halfmargin=margin/2;
514
515 for (int i=0;i<2;++i) {
516 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
517 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
518 rr2[i][1]][1])+halfmargin);
519 get_line_points(points,coords,color,width,height,margin);
520 }
521 }
522
523 void draw_font_U(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
524 oat> &color, int width, int height, int margin)
525 {
526 // U
527 //points
528 float arr[4][2] = {{0.0,0.0},{0.0,1.0},{1.0,1.0},{1.0,0.5}};
529 //lines
530 int arr2[3][2] = {{0,1},{1,2},{2,3}};
531 std::tuple<int, int, int, int> coords;
532 int halfmargin=margin/2;
533
534 for (int i=0;i<3;++i) {
535 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
536 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
537 rr2[i][1]][1])+halfmargin);
538 get_line_points(points,coords,color,width,height,margin);
539 }
14 Appendix A: Source Code Listings 246

540 }
541
542 void draw_font_V(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
543 oat> &color, int width, int height, int margin)
544 {
545 // V
546 //points
547 float arr[3][2] = {{0.0,0.0},{0.5,1.0},{1.0,0.0}};
548 //lines
549 int arr2[2][2] = {{0,1},{1,2}};
550 std::tuple<int, int, int, int> coords;
551 int halfmargin=margin/2;
552
553 for (int i=0;i<2;++i) {
554 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
555 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
556 rr2[i][1]][1])+halfmargin);
557 get_line_points(points,coords,color,width,height,margin);
558 }
559 }
560
561 void draw_font_W(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
562 oat> &color, int width, int height, int margin)
563 {
564 // W
565 //points
566 float arr[5][2] = {{0.0,0.0},{0.0,1.0},{0.5,0.7},{1.0,1.0},{1.0,0.0}};
567 //lines
568 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,4}};
569 std::tuple<int, int, int, int> coords;
570 int halfmargin=margin/2;
571
572 for (int i=0;i<4;++i) {
573 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
574 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
575 rr2[i][1]][1])+halfmargin);
576 get_line_points(points,coords,color,width,height,margin);
577 }
578 }
579
580 void draw_font_X(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
581 oat> &color, int width, int height, int margin)
582 {
14 Appendix A: Source Code Listings 247

583 // X
584 //points
585 float arr[5][2] = {{0.5,0.6},{0.0,0.0},{1.0,0.0},{1.0,1.0},{0.0,1.0}};
586 //lines
587 int arr2[4][2] = {{0,1},{0,2},{0,3},{0,4}};
588 std::tuple<int, int, int, int> coords;
589 int halfmargin=margin/2;
590
591 for (int i=0;i<4;++i) {
592 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
593 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
594 rr2[i][1]][1])+halfmargin);
595 get_line_points(points,coords,color,width,height,margin);
596 }
597 }
598
599 void draw_font_Y(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
600 oat> &color, int width, int height, int margin)
601 {
602 // Y
603 //points
604 float arr[4][2] = {{0.5,0.6},{0.0,0.0},{1.0,0.0},{0.5,1.0}};
605 //lines
606 int arr2[3][2] = {{0,1},{0,2},{0,3}};
607 std::tuple<int, int, int, int> coords;
608 int halfmargin=margin/2;
609
610 for (int i=0;i<3;++i) {
611 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
612 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
613 rr2[i][1]][1])+halfmargin);
614 get_line_points(points,coords,color,width,height,margin);
615 }
616 }
617
618 void draw_font_Z(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
619 oat> &color, int width, int height, int margin)
620 {
621 // Z
622 //points
623 float arr[4][2] = {{0.0,0.0},{1.0,0.0},{0.0,1.0},{1.0,1.0}};
624 //lines
625 int arr2[3][2] = {{0,1},{1,2},{2,3}};
14 Appendix A: Source Code Listings 248

626 std::tuple<int, int, int, int> coords;


627 int halfmargin=margin/2;
628
629 for (int i=0;i<3;++i) {
630 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
631 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
632 rr2[i][1]][1])+halfmargin);
633 get_line_points(points,coords,color,width,height,margin);
634 }
635 }
636
637 void draw_font_0(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
638 oat> &color, int width, int height, int margin)
639 {
640 // 0
641 //points
642 float arr[6][2] = {{0.0,0.0},{0.0,1.0},{1.0,1.0},{1.0,0.0},{0.0,1.0},{1.0,0.0}};
643 //lines
644 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,0},{4,5}};
645 std::tuple<int, int, int, int> coords;
646 int halfmargin=margin/2;
647
648 for (int i=0;i<5;++i) {
649 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
650 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
651 rr2[i][1]][1])+halfmargin);
652 get_line_points(points,coords,color,width,height,margin);
653 }
654 }
655
656 void draw_font_1(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
657 oat> &color, int width, int height, int margin)
658 {
659 // 1
660 //points
661 float arr[3][2] = {{0.0,0.0},{0.5,0.0},{0.5,1.0}};
662 //lines
663 int arr2[2][2] = {{0,1},{1,2}};
664 std::tuple<int, int, int, int> coords;
665 int halfmargin=margin/2;
666
667 for (int i=0;i<2;++i) {
668 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
14 Appendix A: Source Code Listings 249

669 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a


670 rr2[i][1]][1])+halfmargin);
671 get_line_points(points,coords,color,width,height,margin);
672 }
673 }
674
675 void draw_font_2(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
676 oat> &color, int width, int height, int margin)
677 {
678 // 2
679 //points
680 float arr[6][2] = {{0.0,0.0},{1.0,0.0},{1.0,0.4},{0.0,0.6},{0.0,1.0},{1.0,1.0}};
681 //lines
682 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
683 std::tuple<int, int, int, int> coords;
684 int halfmargin=margin/2;
685
686 for (int i=0;i<5;++i) {
687 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
688 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
689 rr2[i][1]][1])+halfmargin);
690 get_line_points(points,coords,color,width,height,margin);
691 }
692 }
693
694 void draw_font_3(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
695 oat> &color, int width, int height, int margin)
696 {
697 // 3
698 //points
699 float arr[6][2] = {{0.0,0.0},{1.0,0.0},{1.0,0.4},{0.5,0.4},{0.0,1.0},{1.0,1.0}};
700 //lines
701 int arr2[4][2] = {{0,1},{1,2},{2,3},{4,5}};
702 std::tuple<int, int, int, int> coords;
703 int halfmargin=margin/2;
704
705 for (int i=0;i<4;++i) {
706 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
707 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
708 rr2[i][1]][1])+halfmargin);
709 get_line_points(points,coords,color,width,height,margin);
710 }
711 }
14 Appendix A: Source Code Listings 250

712
713 void draw_font_4(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
714 oat> &color, int width, int height, int margin)
715 {
716 // 4
717 //points
718 float arr[5][2] = {{0.0,0.0},{0.0,0.4},{1.0,0.6},{1.0,0.0},{1.0,1.0}};
719 //lines
720 int arr2[3][2] = {{0,1},{1,2},{3,4}};
721 std::tuple<int, int, int, int> coords;
722 int halfmargin=margin/2;
723
724 for (int i=0;i<3;++i) {
725 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
726 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
727 rr2[i][1]][1])+halfmargin);
728 get_line_points(points,coords,color,width,height,margin);
729 }
730 }
731
732 void draw_font_5(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
733 oat> &color, int width, int height, int margin)
734 {
735 // 5
736 //points
737 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.5},{1.0,0.6},{1.0,1.0},{0.0,1.0}};
738 //lines
739 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
740 std::tuple<int, int, int, int> coords;
741 int halfmargin=margin/2;
742
743 for (int i=0;i<5;++i) {
744 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
745 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
746 rr2[i][1]][1])+halfmargin);
747 get_line_points(points,coords,color,width,height,margin);
748 }
749 }
750
751 void draw_font_6(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
752 oat> &color, int width, int height, int margin)
753 {
754 // 6
14 Appendix A: Source Code Listings 251

755 //points
756 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.4},{1.0,0.6},{1.0,1.0},{0.0,1.0}};
757 //lines
758 int arr2[5][2] = {{0,1},{1,5},{5,4},{3,4},{3,2}};
759 std::tuple<int, int, int, int> coords;
760 int halfmargin=margin/2;
761
762 for (int i=0;i<5;++i) {
763 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
764 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
765 rr2[i][1]][1])+halfmargin);
766 get_line_points(points,coords,color,width,height,margin);
767 }
768 }
769
770 void draw_font_7(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
771 oat> &color, int width, int height, int margin)
772 {
773 // 7
774 //points
775 float arr[3][2] = {{0.0,0.0},{1.0,0.0},{1.0,1.0}};
776 //lines
777 int arr2[2][2] = {{0,1},{1,2}};
778 std::tuple<int, int, int, int> coords;
779 int halfmargin=margin/2;
780
781 for (int i=0;i<2;++i) {
782 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
783 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
784 rr2[i][1]][1])+halfmargin);
785 get_line_points(points,coords,color,width,height,margin);
786 }
787 }
788
789 void draw_font_8(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
790 oat> &color, int width, int height, int margin)
791 {
792 // 8
793 //points
794 float arr[6][2] = {{0.1,0.4},{0.9,0.6},{1.0,0.0},{0.0,0.0},{0.0,1.0},{1.0,1.0}};
795 //lines
796 int arr2[7][2] = {{0,1},{1,2},{2,3},{3,0},{0,4},{4,5},{5,1}};
797 std::tuple<int, int, int, int> coords;
14 Appendix A: Source Code Listings 252

798 int halfmargin=margin/2;


799
800 for (int i=0;i<7;++i) {
801 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
802 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
803 rr2[i][1]][1])+halfmargin);
804 get_line_points(points,coords,color,width,height,margin);
805 }
806 }
807
808 void draw_font_9(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
809 oat> &color, int width, int height, int margin)
810 {
811 // 9
812 //points
813 float arr[5][2] = {{1.0,1.0},{1.0,0.0},{0.0,0.0},{0.0,0.6},{1.0,0.4}};
814 //lines
815 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,4}};
816 std::tuple<int, int, int, int> coords;
817 int halfmargin=margin/2;
818
819 for (int i=0;i<4;++i) {
820 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
821 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
822 rr2[i][1]][1])+halfmargin);
823 get_line_points(points,coords,color,width,height,margin);
824 }
825 }
826
827 void draw_font_QA(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,f\
828 loat> &color, int width, int height, int margin)
829 {
830 // ?
831 //points
832 float arr[6][2] = {{0.0,0.0},{1.0,0.0},{1.0,0.4},{0.5,0.4},{0.5,0.8},{0.5,1.0}};
833 //lines
834 int arr2[4][2] = {{0,1},{1,2},{2,3},{4,5}};
835 std::tuple<int, int, int, int> coords;
836 int halfmargin=margin/2;
837
838 for (int i=0;i<4;++i) {
839 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
840 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
14 Appendix A: Source Code Listings 253

841 rr2[i][1]][1])+halfmargin);
842 get_line_points(points,coords,color,width,height,margin);
843 }
844 }
845
846 void draw_font_PROCENT(std::vector<std::tuple<int,int>> &points, std::tuple<float,fl\
847 oat,float> &color, int width, int height, int margin)
848 {
849 // %
850 //points
851 float arr[10][2] = {{0.0,0.0},{0.3,0.0},{0.3,0.3},{0.0,0.3},{1.0,1.0},{0.7,1.0},{0.\
852 7,0.7},{1.0,0.7},{0.0,1.0},{1.0,0.0}};
853 //lines
854 int arr2[9][2] = {{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{8,9}};
855 std::tuple<int, int, int, int> coords;
856 int halfmargin=margin/2;
857
858 for (int i=0;i<9;++i) {
859 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
860 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
861 rr2[i][1]][1])+halfmargin);
862 get_line_points(points,coords,color,width,height,margin);
863 }
864 }
865
866 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
867 height, int margin, std::string filename)
868 {
869 std::tuple<float, float, float> color;
870 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);
871 out << "P6" << std::endl << (width+margin) << ' ' << (height+margin) << std::endl <\
872 < "255" << std::endl;
873
874 for (int i=0;i<((width+margin)*(height+margin));++i)
875 {
876 color=image[i];
877 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*255.0f) << char(\
878 std::get<2>(color)*255.0f);
879 }
880 out.close();
881 }
882
883 void draw(std::vector<std::tuple<int,int>> points,std::vector<std::tuple<float, floa\
14 Appendix A: Source Code Listings 254

884 t, float>> &image, std::tuple<float,float,float> color, int width, int height, int m
885 argin, int linesize)
886 {
887 for (auto& p : points) {
888 if (linesize == 1) {
889 image[get_index(std::get<0>(p),std::get<1>(p),width+margin)]=std::make_tuple
890 , 0.0f, 0.0f);
891 } else {
892 draw_filled_circle(std::get<0>(p),std::get<1>(p),linesize,image,color,width,
893 t,margin);
894 }
895 }
896 }
897
898 void draw_and_save_font(std::vector<std::tuple<float, float, float>> &image, std::tu\
899 ple<float,float,float> color, int width, int height, int margin, int linesize)
900 {
901 std::vector<std::tuple<int,int>> points;
902 draw_font_A(points,color,width,height,margin);
903 draw(points,image,color,width,height,margin,linesize);
904 save_image(image,width,height,margin,"15_draw_font_A.ppm");
905 points.clear();clear_image(image,width,height,margin);
906 draw_font_B(points,color,width,height,margin);
907 draw(points,image,color,width,height,margin,linesize);
908 save_image(image,width,height,margin,"15_draw_font_B.ppm");
909 points.clear();clear_image(image,width,height,margin);
910 draw_font_C(points,color,width,height,margin);
911 draw(points,image,color,width,height,margin,linesize);
912 save_image(image,width,height,margin,"15_draw_font_C.ppm");
913 points.clear();clear_image(image,width,height,margin);
914 draw_font_D(points,color,width,height,margin);
915 draw(points,image,color,width,height,margin,linesize);
916 save_image(image,width,height,margin,"15_draw_font_D.ppm");
917 points.clear();clear_image(image,width,height,margin);
918 draw_font_E(points,color,width,height,margin);
919 draw(points,image,color,width,height,margin,linesize);
920 save_image(image,width,height,margin,"15_draw_font_E.ppm");
921 points.clear();clear_image(image,width,height,margin);
922 draw_font_F(points,color,width,height,margin);
923 draw(points,image,color,width,height,margin,linesize);
924 save_image(image,width,height,margin,"15_draw_font_F.ppm");
925 points.clear();clear_image(image,width,height,margin);
926 draw_font_G(points,color,width,height,margin);
14 Appendix A: Source Code Listings 255

927 draw(points,image,color,width,height,margin,linesize);
928 save_image(image,width,height,margin,"15_draw_font_G.ppm");
929 points.clear();clear_image(image,width,height,margin);
930 draw_font_H(points,color,width,height,margin);
931 draw(points,image,color,width,height,margin,linesize);
932 save_image(image,width,height,margin,"15_draw_font_H.ppm");
933 points.clear();clear_image(image,width,height,margin);
934 draw_font_I(points,color,width,height,margin);
935 draw(points,image,color,width,height,margin,linesize);
936 save_image(image,width,height,margin,"15_draw_font_I.ppm");
937 points.clear();clear_image(image,width,height,margin);
938 draw_font_J(points,color,width,height,margin);
939 draw(points,image,color,width,height,margin,linesize);
940 save_image(image,width,height,margin,"15_draw_font_J.ppm");
941 points.clear();clear_image(image,width,height,margin);
942 draw_font_K(points,color,width,height,margin);
943 draw(points,image,color,width,height,margin,linesize);
944 save_image(image,width,height,margin,"15_draw_font_K.ppm");
945 points.clear();clear_image(image,width,height,margin);
946 draw_font_L(points,color,width,height,margin);
947 draw(points,image,color,width,height,margin,linesize);
948 save_image(image,width,height,margin,"15_draw_font_L.ppm");
949 points.clear();clear_image(image,width,height,margin);
950 draw_font_M(points,color,width,height,margin);
951 draw(points,image,color,width,height,margin,linesize);
952 save_image(image,width,height,margin,"15_draw_font_M.ppm");
953 points.clear();clear_image(image,width,height,margin);
954 draw_font_N(points,color,width,height,margin);
955 draw(points,image,color,width,height,margin,linesize);
956 save_image(image,width,height,margin,"15_draw_font_N.ppm");
957 points.clear();clear_image(image,width,height,margin);
958 draw_font_O(points,color,width,height,margin);
959 draw(points,image,color,width,height,margin,linesize);
960 save_image(image,width,height,margin,"15_draw_font_O.ppm");
961 points.clear();clear_image(image,width,height,margin);
962 draw_font_P(points,color,width,height,margin);
963 draw(points,image,color,width,height,margin,linesize);
964 save_image(image,width,height,margin,"15_draw_font_P.ppm");
965 points.clear();clear_image(image,width,height,margin);
966 draw_font_Q(points,color,width,height,margin);
967 draw(points,image,color,width,height,margin,linesize);
968 save_image(image,width,height,margin,"15_draw_font_Q.ppm");
969 points.clear();clear_image(image,width,height,margin);
14 Appendix A: Source Code Listings 256

970 draw_font_R(points,color,width,height,margin);
971 draw(points,image,color,width,height,margin,linesize);
972 save_image(image,width,height,margin,"15_draw_font_R.ppm");
973 points.clear();clear_image(image,width,height,margin);
974 draw_font_S(points,color,width,height,margin);
975 draw(points,image,color,width,height,margin,linesize);
976 save_image(image,width,height,margin,"15_draw_font_S.ppm");
977 points.clear();clear_image(image,width,height,margin);
978 draw_font_T(points,color,width,height,margin);
979 draw(points,image,color,width,height,margin,linesize);
980 save_image(image,width,height,margin,"15_draw_font_T.ppm");
981 points.clear();clear_image(image,width,height,margin);
982 draw_font_U(points,color,width,height,margin);
983 draw(points,image,color,width,height,margin,linesize);
984 save_image(image,width,height,margin,"15_draw_font_U.ppm");
985 points.clear();clear_image(image,width,height,margin);
986 draw_font_V(points,color,width,height,margin);
987 draw(points,image,color,width,height,margin,linesize);
988 save_image(image,width,height,margin,"15_draw_font_V.ppm");
989 points.clear();clear_image(image,width,height,margin);
990 draw_font_W(points,color,width,height,margin);
991 draw(points,image,color,width,height,margin,linesize);
992 save_image(image,width,height,margin,"15_draw_font_W.ppm");
993 points.clear();clear_image(image,width,height,margin);
994 draw_font_X(points,color,width,height,margin);
995 draw(points,image,color,width,height,margin,linesize);
996 save_image(image,width,height,margin,"15_draw_font_X.ppm");
997 points.clear();clear_image(image,width,height,margin);
998 draw_font_Y(points,color,width,height,margin);
999 draw(points,image,color,width,height,margin,linesize);
1000 save_image(image,width,height,margin,"15_draw_font_Y.ppm");
1001 points.clear();clear_image(image,width,height,margin);
1002 draw_font_Z(points,color,width,height,margin);
1003 draw(points,image,color,width,height,margin,linesize);
1004 save_image(image,width,height,margin,"15_draw_font_Z.ppm");
1005 points.clear();clear_image(image,width,height,margin);
1006 draw_font_0(points,color,width,height,margin);
1007 draw(points,image,color,width,height,margin,linesize);
1008 save_image(image,width,height,margin,"15_draw_font_0.ppm");
1009 points.clear();clear_image(image,width,height,margin);
1010 draw_font_1(points,color,width,height,margin);
1011 draw(points,image,color,width,height,margin,linesize);
1012 save_image(image,width,height,margin,"15_draw_font_1.ppm");
14 Appendix A: Source Code Listings 257

1013 points.clear();clear_image(image,width,height,margin);
1014 draw_font_2(points,color,width,height,margin);
1015 draw(points,image,color,width,height,margin,linesize);
1016 save_image(image,width,height,margin,"15_draw_font_2.ppm");
1017 points.clear();clear_image(image,width,height,margin);
1018 draw_font_3(points,color,width,height,margin);
1019 draw(points,image,color,width,height,margin,linesize);
1020 save_image(image,width,height,margin,"15_draw_font_3.ppm");
1021 points.clear();clear_image(image,width,height,margin);
1022 draw_font_4(points,color,width,height,margin);
1023 draw(points,image,color,width,height,margin,linesize);
1024 save_image(image,width,height,margin,"15_draw_font_4.ppm");
1025 points.clear();clear_image(image,width,height,margin);
1026 draw_font_5(points,color,width,height,margin);
1027 draw(points,image,color,width,height,margin,linesize);
1028 save_image(image,width,height,margin,"15_draw_font_5.ppm");
1029 points.clear();clear_image(image,width,height,margin);
1030 draw_font_6(points,color,width,height,margin);
1031 draw(points,image,color,width,height,margin,linesize);
1032 save_image(image,width,height,margin,"15_draw_font_6.ppm");
1033 points.clear();clear_image(image,width,height,margin);
1034 draw_font_7(points,color,width,height,margin);
1035 draw(points,image,color,width,height,margin,linesize);
1036 save_image(image,width,height,margin,"15_draw_font_7.ppm");
1037 points.clear();clear_image(image,width,height,margin);
1038 draw_font_8(points,color,width,height,margin);
1039 draw(points,image,color,width,height,margin,linesize);
1040 save_image(image,width,height,margin,"15_draw_font_8.ppm");
1041 points.clear();clear_image(image,width,height,margin);
1042 draw_font_9(points,color,width,height,margin);
1043 draw(points,image,color,width,height,margin,linesize);
1044 save_image(image,width,height,margin,"15_draw_font_9.ppm");
1045 points.clear();clear_image(image,width,height,margin);
1046 draw_font_QA(points,color,width,height,margin);
1047 draw(points,image,color,width,height,margin,linesize);
1048 save_image(image,width,height,margin,"15_draw_font_questionmark.ppm");
1049 points.clear();clear_image(image,width,height,margin);
1050 draw_font_PROCENT(points,color,width,height,margin);
1051 draw(points,image,color,width,height,margin,linesize);
1052 save_image(image,width,height,margin,"15_draw_font_procent.ppm");
1053 }
1054
1055 int main()
14 Appendix A: Source Code Listings 258

1056 {
1057 int width=0;int height=40;
1058 int margin=0;
1059 int linesize=3;
1060 std::vector<std::tuple<float, float, float>> image;
1061 std::tuple<float,float,float> color=std::make_tuple(0.0f,0.0f,0.0f);
1062
1063 get_width_from_height(width,height);
1064 get_margin_from_height(margin,height);
1065 std::cout << "w: " << width << " h: " << height << " m: " << margin << " ls: " << l\
1066 inesize << std::endl;
1067
1068 image.resize(calc_size(width, height, margin));
1069 clear_image(image,width,height,margin);
1070
1071 draw_and_save_font(image,color,width,height,margin,linesize);
1072
1073 return 0;
1074 }

16_draw_bar_chart.cpp - 15032 bytes.

1 // Compile: clang++ -std=c++17 16_draw_bar_chart.cpp -o 16_draw_bar_chart


2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <random>
8 #include <cmath>
9
10 int get_index(int x, int y, int width)
11 {
12 return x+width*y;
13 }
14
15 int calc_size(int width, int height, int margin)
16 {
17 return (width+margin)*(height+margin);
18 }
19
20 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
21 height, int margin)
14 Appendix A: Source Code Listings 259

22 {
23 for (int y=0;y<(height+margin);++y) {
24 for (int x=0;x<(width+margin);++x) {
25 image[get_index(x,y,(width+margin))]=std::make_tuple(0.262745098f, 0.2627450
26 0.262745098f);
27 }
28 }
29 }
30
31 void draw_filled_rect(int x, int y, int w, int h, std::vector<std::tuple<float, floa\
32 t, float>> &image, std::tuple<float,float,float> &color, int width, int height)
33 {
34 int x2 = x + w;
35 int y2 = y + h;
36
37 if (x < 0) {x = 0;}
38 if (x >= width) {x = width;}
39 if (y < 0) {y = 0;}
40 if (y >= height) {y = height;}
41
42 if (x2 < 0) {x2 = 0;}
43 if (x2 >= width) {x2 = width;}
44 if (y2 < 0) {y2 = 0;}
45 if (y2 >= height) {y2 = height;}
46
47 for (int i = y; i < y2; i++) {
48 for (int j = x; j < x2; j++) {
49 image[get_index(j,i,width)]=color;
50 }
51 }
52 }
53
54 void draw_line(std::vector<std::tuple<float, float, float>> &image, std::tuple<int, \
55 int, int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
56 {
57 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
58 int y2=std::get<3>(coords);
59 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
60 dx = x2 - x1; dy = y2 - y1;
61 if (dx == 0)
62 {
63 if (y2 < y1) std::swap(y1, y2);
64 for (y = y1; y <= y2; y++)
14 Appendix A: Source Code Listings 260

65 image[get_index(x1,y,width)]=color;
66 return;
67 }
68 if (dy == 0)
69 {
70 if (x2 < x1) std::swap(x1, x2);
71 for (x = x1; x <= x2; x++)
72 image[get_index(x,y1,width)]=color;
73 return;
74 }
75 dx1 = abs(dx); dy1 = abs(dy);
76 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
77 if (dy1 <= dx1)
78 {
79 if (dx >= 0)
80 {
81 x = x1; y = y1; xe = x2;
82 }
83 else
84 {
85 x = x2; y = y2; xe = x1;
86 }
87 image[get_index(x,y,width)]=color;
88 for (i = 0; x<xe; i++)
89 {
90 x = x + 1;
91 if (px<0)
92 px = px + 2 * dy1;
93 else
94 {
95 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
96 px = px + 2 * (dy1 - dx1);
97 }
98 image[get_index(x,y,width)]=color;
99 }
100 }
101 else
102 {
103 if (dy >= 0)
104 {
105 x = x1; y = y1; ye = y2;
106 }
107 else
14 Appendix A: Source Code Listings 261

108 {
109 x = x2; y = y2; ye = y1;
110 }
111 image[get_index(x,y,width)]=color;
112 for (i = 0; y<ye; i++)
113 {
114 y = y + 1;
115 if (py <= 0)
116 py = py + 2 * dx1;
117 else
118 {
119 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
120 py = py + 2 * (dx1 - dy1);
121 }
122 image[get_index(x,y,width)]=color;
123 }
124 }
125 }
126
127 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
128 height, std::string filename)
129 {
130 std::tuple<float, float, float> color;
131 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);
132 out << "P6" << std::endl << width << ' ' << height << std::endl << "255" << std::en\
133 dl;
134
135 for (int i=0;i<(width*height);++i)
136 {
137 color=image[i];
138 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*255.0f) << char(\
139 std::get<2>(color)*255.0f);
140 }
141 out.close();
142 }
143
144 int main()
145 {
146 std::vector<std::tuple<float, float, float>> image;
147 std::tuple<int, int, int, int> coords;
148 std::tuple<float,float,float> color=std::make_tuple(1.0f,0.7647058824f,0.6235294118\
149 f);
150 int width=1600,height=900;
14 Appendix A: Source Code Listings 262

151 int margin=0;


152 int linesize=3;
153
154 image.resize(calc_size(width, height, margin));
155 clear_image(image,width,height,margin);
156
157 draw_filled_rect(560,268,74,420,image,color,width,height);
158 draw_filled_rect(695,442,74,246,image,color,width,height);
159 draw_filled_rect(831,571,74,117,image,color,width,height);
160 draw_filled_rect(966,306,74,381,image,color,width,height);
161 draw_filled_rect(463,687,674,4,image,color,width,height);
162
163 // icon 1
164 draw_filled_rect(577,714,3,39,image,color,width,height);
165 draw_filled_rect(571,753,35,3,image,color,width,height);
166 draw_filled_rect(571,756,3,14,image,color,width,height);
167 draw_filled_rect(574,767,32,3,image,color,width,height);
168 draw_filled_rect(603,756,3,11,image,color,width,height);
169 draw_filled_rect(577,770,3,7,image,color,width,height);
170 draw_filled_rect(580,774,43,3,image,color,width,height);
171 draw_filled_rect(620,724,3,53,image,color,width,height);
172 draw_filled_rect(580,714,33,3,image,color,width,height);
173 draw_filled_rect(610,717,3,10,image,color,width,height);
174 draw_filled_rect(613,724,8,3,image,color,width,height);
175 draw_filled_rect(611,715,3,3,image,color,width,height);
176 draw_filled_rect(612,716,3,3,image,color,width,height);
177 draw_filled_rect(613,717,3,3,image,color,width,height);
178 draw_filled_rect(614,718,3,3,image,color,width,height);
179 draw_filled_rect(615,719,3,3,image,color,width,height);
180 draw_filled_rect(616,720,3,3,image,color,width,height);
181 draw_filled_rect(617,721,3,3,image,color,width,height);
182 draw_filled_rect(618,722,3,3,image,color,width,height);
183 draw_filled_rect(619,723,3,3,image,color,width,height);
184
185 // icon 2
186 draw_filled_rect(577+(1*136),714,3,39,image,color,width,height);
187 draw_filled_rect(571+(1*136),753,35,3,image,color,width,height);
188 draw_filled_rect(571+(1*136),756,3,14,image,color,width,height);
189 draw_filled_rect(574+(1*136),767,32,3,image,color,width,height);
190 draw_filled_rect(603+(1*136),756,3,11,image,color,width,height);
191 draw_filled_rect(577+(1*136),770,3,7,image,color,width,height);
192 draw_filled_rect(580+(1*136),774,43,3,image,color,width,height);
193 draw_filled_rect(620+(1*136),724,3,53,image,color,width,height);
14 Appendix A: Source Code Listings 263

194 draw_filled_rect(580+(1*136),714,33,3,image,color,width,height);
195 draw_filled_rect(610+(1*136),717,3,10,image,color,width,height);
196 draw_filled_rect(613+(1*136),724,8,3,image,color,width,height);
197 draw_filled_rect(611+(1*136),715,3,3,image,color,width,height);
198 draw_filled_rect(612+(1*136),716,3,3,image,color,width,height);
199 draw_filled_rect(613+(1*136),717,3,3,image,color,width,height);
200 draw_filled_rect(614+(1*136),718,3,3,image,color,width,height);
201 draw_filled_rect(615+(1*136),719,3,3,image,color,width,height);
202 draw_filled_rect(616+(1*136),720,3,3,image,color,width,height);
203 draw_filled_rect(617+(1*136),721,3,3,image,color,width,height);
204 draw_filled_rect(618+(1*136),722,3,3,image,color,width,height);
205 draw_filled_rect(619+(1*136),723,3,3,image,color,width,height);
206
207 // icon 3
208 draw_filled_rect(577+(2*136),714,3,39,image,color,width,height);
209 draw_filled_rect(571+(2*136),753,35,3,image,color,width,height);
210 draw_filled_rect(571+(2*136),756,3,14,image,color,width,height);
211 draw_filled_rect(574+(2*136),767,32,3,image,color,width,height);
212 draw_filled_rect(603+(2*136),756,3,11,image,color,width,height);
213 draw_filled_rect(577+(2*136),770,3,7,image,color,width,height);
214 draw_filled_rect(580+(2*136),774,43,3,image,color,width,height);
215 draw_filled_rect(620+(2*136),724,3,53,image,color,width,height);
216 draw_filled_rect(580+(2*136),714,33,3,image,color,width,height);
217 draw_filled_rect(610+(2*136),717,3,10,image,color,width,height);
218 draw_filled_rect(613+(2*136),724,8,3,image,color,width,height);
219 draw_filled_rect(611+(2*136),715,3,3,image,color,width,height);
220 draw_filled_rect(612+(2*136),716,3,3,image,color,width,height);
221 draw_filled_rect(613+(2*136),717,3,3,image,color,width,height);
222 draw_filled_rect(614+(2*136),718,3,3,image,color,width,height);
223 draw_filled_rect(615+(2*136),719,3,3,image,color,width,height);
224 draw_filled_rect(616+(2*136),720,3,3,image,color,width,height);
225 draw_filled_rect(617+(2*136),721,3,3,image,color,width,height);
226 draw_filled_rect(618+(2*136),722,3,3,image,color,width,height);
227 draw_filled_rect(619+(2*136),723,3,3,image,color,width,height);
228
229 // icon 4
230 draw_filled_rect(577+(3*136),714,3,39,image,color,width,height);
231 draw_filled_rect(571+(3*136),753,35,3,image,color,width,height);
232 draw_filled_rect(571+(3*136),756,3,14,image,color,width,height);
233 draw_filled_rect(574+(3*136),767,32,3,image,color,width,height);
234 draw_filled_rect(603+(3*136),756,3,11,image,color,width,height);
235 draw_filled_rect(577+(3*136),770,3,7,image,color,width,height);
236 draw_filled_rect(580+(3*136),774,43,3,image,color,width,height);
14 Appendix A: Source Code Listings 264

237 draw_filled_rect(620+(3*136),724,3,53,image,color,width,height);
238 draw_filled_rect(580+(3*136),714,33,3,image,color,width,height);
239 draw_filled_rect(610+(3*136),717,3,10,image,color,width,height);
240 draw_filled_rect(613+(3*136),724,8,3,image,color,width,height);
241 draw_filled_rect(611+(3*136),715,3,3,image,color,width,height);
242 draw_filled_rect(612+(3*136),716,3,3,image,color,width,height);
243 draw_filled_rect(613+(3*136),717,3,3,image,color,width,height);
244 draw_filled_rect(614+(3*136),718,3,3,image,color,width,height);
245 draw_filled_rect(615+(3*136),719,3,3,image,color,width,height);
246 draw_filled_rect(616+(3*136),720,3,3,image,color,width,height);
247 draw_filled_rect(617+(3*136),721,3,3,image,color,width,height);
248 draw_filled_rect(618+(3*136),722,3,3,image,color,width,height);
249 draw_filled_rect(619+(3*136),723,3,3,image,color,width,height);
250
251 // 35%
252 coords=std::make_tuple(579,234,586,234);
253 draw_line(image,coords,color,width,height);
254 coords=std::make_tuple(586,252,586,234);
255 draw_line(image,coords,color,width,height);
256 coords=std::make_tuple(586,252,579,252);
257 draw_line(image,coords,color,width,height);
258 coords=std::make_tuple(586,242,580,242);
259 draw_line(image,coords,color,width,height);
260 coords=std::make_tuple(591,234,598,234);
261 draw_line(image,coords,color,width,height);
262 coords=std::make_tuple(591,242,598,242);
263 draw_line(image,coords,color,width,height);
264 coords=std::make_tuple(591,242,598,242);
265 draw_line(image,coords,color,width,height);
266 coords=std::make_tuple(591,252,598,252);
267 draw_line(image,coords,color,width,height);
268 coords=std::make_tuple(591,234,591,242);
269 draw_line(image,coords,color,width,height);
270 coords=std::make_tuple(598,242,598,252);
271 draw_line(image,coords,color,width,height);
272 coords=std::make_tuple(602,251,617,233);
273 draw_line(image,coords,color,width,height);
274 coords=std::make_tuple(602,234,608,234);
275 draw_line(image,coords,color,width,height);
276 coords=std::make_tuple(602,234,602,239);
277 draw_line(image,coords,color,width,height);
278 coords=std::make_tuple(602,239,608,239);
279 draw_line(image,coords,color,width,height);
14 Appendix A: Source Code Listings 265

280 coords=std::make_tuple(608,239,608,234);
281 draw_line(image,coords,color,width,height);
282 coords=std::make_tuple(611,246,616,246);
283 draw_line(image,coords,color,width,height);
284 coords=std::make_tuple(611,251,616,251);
285 draw_line(image,coords,color,width,height);
286 coords=std::make_tuple(611,251,611,246);
287 draw_line(image,coords,color,width,height);
288 coords=std::make_tuple(616,251,616,246);
289 draw_line(image,coords,color,width,height);
290
291 // 23%
292 coords=std::make_tuple(715,409,722,409);
293 draw_line(image,coords,color,width,height);
294 coords=std::make_tuple(715,426,722,426);
295 draw_line(image,coords,color,width,height);
296 coords=std::make_tuple(722,409,722,417);
297 draw_line(image,coords,color,width,height);
298 coords=std::make_tuple(722,417,715,426);
299 draw_line(image,coords,color,width,height);
300 coords=std::make_tuple(726,409,733,409);
301 draw_line(image,coords,color,width,height);
302 coords=std::make_tuple(726,417,733,417);
303 draw_line(image,coords,color,width,height);
304 coords=std::make_tuple(726,426,733,426);
305 draw_line(image,coords,color,width,height);
306 coords=std::make_tuple(733,426,733,409);
307 draw_line(image,coords,color,width,height);
308 coords=std::make_tuple(737,409,737,414);
309 draw_line(image,coords,color,width,height);
310 coords=std::make_tuple(737,414,743,414);
311 draw_line(image,coords,color,width,height);
312 coords=std::make_tuple(743,414,743,409);
313 draw_line(image,coords,color,width,height);
314 coords=std::make_tuple(743,409,737,409);
315 draw_line(image,coords,color,width,height);
316 coords=std::make_tuple(746,421,746,426);
317 draw_line(image,coords,color,width,height);
318 coords=std::make_tuple(746,426,751,426);
319 draw_line(image,coords,color,width,height);
320 coords=std::make_tuple(751,426,751,421);
321 draw_line(image,coords,color,width,height);
322 coords=std::make_tuple(751,421,746,421);
14 Appendix A: Source Code Listings 266

323 draw_line(image,coords,color,width,height);
324 coords=std::make_tuple(737,426,751,409);
325 draw_line(image,coords,color,width,height);
326
327 // 10%
328 coords=std::make_tuple(853,537,853,555);
329 draw_line(image,coords,color,width,height);
330 coords=std::make_tuple(857,537,857,555);
331 draw_line(image,coords,color,width,height);
332 coords=std::make_tuple(857,555,867,555);
333 draw_line(image,coords,color,width,height);
334 coords=std::make_tuple(867,555,867,537);
335 draw_line(image,coords,color,width,height);
336 coords=std::make_tuple(867,537,857,537);
337 draw_line(image,coords,color,width,height);
338 coords=std::make_tuple(871,555,886,537);
339 draw_line(image,coords,color,width,height);
340 coords=std::make_tuple(871,537,871,543);
341 draw_line(image,coords,color,width,height);
342 coords=std::make_tuple(871,543,877,543);
343 draw_line(image,coords,color,width,height);
344 coords=std::make_tuple(877,543,877,537);
345 draw_line(image,coords,color,width,height);
346 coords=std::make_tuple(877,537,871,537);
347 draw_line(image,coords,color,width,height);
348 coords=std::make_tuple(880,549,880,555);
349 draw_line(image,coords,color,width,height);
350 coords=std::make_tuple(880,555,885,555);
351 draw_line(image,coords,color,width,height);
352 coords=std::make_tuple(885,555,885,549);
353 draw_line(image,coords,color,width,height);
354 coords=std::make_tuple(885,549,880,549);
355 draw_line(image,coords,color,width,height);
356
357 // 32%
358 coords=std::make_tuple(993,272,986,272);
359 draw_line(image,coords,color,width,height);
360 coords=std::make_tuple(993,280,986,280);
361 draw_line(image,coords,color,width,height);
362 coords=std::make_tuple(993,291,986,291);
363 draw_line(image,coords,color,width,height);
364 coords=std::make_tuple(993,291,993,272);
365 draw_line(image,coords,color,width,height);
14 Appendix A: Source Code Listings 267

366 coords=std::make_tuple(997,272,1005,272);
367 draw_line(image,coords,color,width,height);
368 coords=std::make_tuple(1005,272,1005,280);
369 draw_line(image,coords,color,width,height);
370 coords=std::make_tuple(1005,280,997,291);
371 draw_line(image,coords,color,width,height);
372 coords=std::make_tuple(997,291,1005,291);
373 draw_line(image,coords,color,width,height);
374 coords=std::make_tuple(1007,291,1023,272);
375 draw_line(image,coords,color,width,height);
376 coords=std::make_tuple(1008,272,1008,277);
377 draw_line(image,coords,color,width,height);
378 coords=std::make_tuple(1008,272,1008,277);
379 draw_line(image,coords,color,width,height);
380 coords=std::make_tuple(1008,277,1013,277);
381 draw_line(image,coords,color,width,height);
382 coords=std::make_tuple(1013,277,1013,272);
383 draw_line(image,coords,color,width,height);
384 coords=std::make_tuple(1013,272,1008,272);
385 draw_line(image,coords,color,width,height);
386 coords=std::make_tuple(1016,284,1016,289);
387 draw_line(image,coords,color,width,height);
388 coords=std::make_tuple(1016,289,1022,289);
389 draw_line(image,coords,color,width,height);
390 coords=std::make_tuple(1022,289,1022,284);
391 draw_line(image,coords,color,width,height);
392 coords=std::make_tuple(1022,284,1016,284);
393 draw_line(image,coords,color,width,height);
394
395 std::cout << "saving: 16_draw_bar_chart.ppm." << std::endl;
396 save_image(image,width,height,"16_draw_bar_chart.ppm");
397
398 return 0;
399 }
14 Appendix A: Source Code Listings 268

16_draw_pie_chart.cpp - 21225 bytes.


1 // Compile: clang++ -std=c++17 16_draw_pie_chart.cpp -o 16_draw_pie_chart
2 #define _USE_MATH_DEFINES
3
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10 #include <algorithm>
11
12 void get_width_from_height(int &width, int height)
13 {
14 int half = height / 2;
15 width = half * 3;
16 }
17
18 void get_margin_from_height(int &margin,int height)
19 {
20 margin = int(float(height) * 0.3);
21 }
22
23 int get_index(int x, int y, int width)
24 {
25 return x+width*y;
26 }
27
28 int calc_size(int width, int height, int margin)
29 {
30 return (width+margin)*(height+margin);
31 }
32
33 void stamp(std::vector<std::tuple<float, float, float>> &image, std::vector<std::tup\
34 le<float, float, float>> &letter, int offsetx, int offsety, int inputwidth, int inpu
35 theight, int width)
36 {
37 int inputx=0;
38 int inputy=0;
39 for (int y = offsety; y < offsety+inputheight; ++y)
40 {
41 for (int x = offsetx; x < offsetx+inputwidth; ++x)
42 {
14 Appendix A: Source Code Listings 269

43 image[get_index(x,y,width)]=letter[get_index(inputx,inputy,inputwidth)];
44 inputx++;
45 }
46 inputy++;
47 inputx=0;
48 }
49 }
50
51 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
52 height, int margin)
53 {
54 for (int y=0;y<(height+margin);++y) {
55 for (int x=0;x<(width+margin);++x) {
56 image[get_index(x,y,(width+margin))]=std::make_tuple(1.0f,0.7647058824f,0.62
57 118f);
58 }
59 }
60 }
61
62 void get_line_points(std::vector<std::tuple<int,int>> &points, std::tuple<int, int, \
63 int, int> &coords, std::tuple<float,float,float> &color, int width, int height, int
64 margin)
65 {
66 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
67 int y2=std::get<3>(coords);
68 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
69 dx = x2 - x1; dy = y2 - y1;
70 if (dx == 0)
71 {
72 if (y2 < y1) std::swap(y1, y2);
73 for (y = y1; y <= y2; y++)
74 points.push_back(std::make_tuple(x1,y));
75 return;
76 }
77 if (dy == 0)
78 {
79 if (x2 < x1) std::swap(x1, x2);
80 for (x = x1; x <= x2; x++)
81 points.push_back(std::make_tuple(x,y1));
82 return;
83 }
84 dx1 = abs(dx); dy1 = abs(dy);
85 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
14 Appendix A: Source Code Listings 270

86 if (dy1 <= dx1)


87 {
88 if (dx >= 0)
89 {
90 x = x1; y = y1; xe = x2;
91 }
92 else
93 {
94 x = x2; y = y2; xe = x1;
95 }
96 points.push_back(std::make_tuple(x,y));
97 for (i = 0; x<xe; i++)
98 {
99 x = x + 1;
100 if (px<0)
101 px = px + 2 * dy1;
102 else
103 {
104 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
105 px = px + 2 * (dy1 - dx1);
106 }
107 points.push_back(std::make_tuple(x,y));
108 }
109 }
110 else
111 {
112 if (dy >= 0)
113 {
114 x = x1; y = y1; ye = y2;
115 }
116 else
117 {
118 x = x2; y = y2; ye = y1;
119 }
120 points.push_back(std::make_tuple(x,y));
121 for (i = 0; y<ye; i++)
122 {
123 y = y + 1;
124 if (py <= 0)
125 py = py + 2 * dx1;
126 else
127 {
128 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
14 Appendix A: Source Code Listings 271

129 py = py + 2 * (dx1 - dy1);


130 }
131 points.push_back(std::make_tuple(x,y));
132 }
133 }
134 }
135
136 void draw_font_M(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
137 oat> &color, int width, int height, int margin)
138 {
139 // M
140 //points
141 float arr[5][2] = {{0.0,1.0},{0.0,0.0},{0.5,0.3},{1.0,0.0},{1.0,1.0}};
142 //lines
143 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,4}};
144 std::tuple<int, int, int, int> coords;
145 int halfmargin=margin/2;
146
147 for (int i=0;i<4;++i) {
148 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
149 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
150 rr2[i][1]][1])+halfmargin);
151 get_line_points(points,coords,color,width,height,margin);
152 }
153 }
154
155 void draw_font_A(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
156 oat> &color, int width, int height, int margin)
157 {
158 // A
159 //points
160 float arr[4][2] = {{0.0,1.0},{0.5,0.0},{1.0,1.0},{0.0,0.6}};
161 //lines
162 int arr2[3][2] = {{0,1},{1,2},{2,3}};
163 std::tuple<int, int, int, int> coords;
164 int halfmargin=margin/2;
165
166 for (int i=0;i<3;++i) {
167 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
168 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0])+halfmargin, int(height*arr[a
169 rr2[i][1]][1])+halfmargin);
170 get_line_points(points,coords,color,width,height,margin);
171 }
14 Appendix A: Source Code Listings 272

172 }
173
174 void draw_font_R(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
175 oat> &color, int width, int height, int margin)
176 {
177 // R
178 //points
179 float arr[6][2] = {{0.0,1.0},{0.0,0.0},{1.0,0.0},{1.0,0.3},{0.0,0.6},{1.0,1.0}};
180 //lines
181 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
182 std::tuple<int, int, int, int> coords;
183 int halfmargin=margin/2;
184
185 for (int i=0;i<5;++i) {
186 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
187 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
188 rr2[i][1]][1])+halfmargin);
189 get_line_points(points,coords,color,width,height,margin);
190 }
191 }
192
193 void draw_font_S(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
194 oat> &color, int width, int height, int margin)
195 {
196 // S
197 //points
198 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.4},{1.0,0.6},{1.0,1.0},{0.0,1.0}};
199 //lines
200 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
201 std::tuple<int, int, int, int> coords;
202 int halfmargin=margin/2;
203
204 for (int i=0;i<5;++i) {
205 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
206 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
207 rr2[i][1]][1])+halfmargin);
208 get_line_points(points,coords,color,width,height,margin);
209 }
210 }
211
212 void draw_font_V(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
213 oat> &color, int width, int height, int margin)
214 {
14 Appendix A: Source Code Listings 273

215 // V
216 //points
217 float arr[3][2] = {{0.0,0.0},{0.5,1.0},{1.0,0.0}};
218 //lines
219 int arr2[2][2] = {{0,1},{1,2}};
220 std::tuple<int, int, int, int> coords;
221 int halfmargin=margin/2;
222
223 for (int i=0;i<2;++i) {
224 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
225 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
226 rr2[i][1]][1])+halfmargin);
227 get_line_points(points,coords,color,width,height,margin);
228 }
229 }
230
231 void draw_font_E(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
232 oat> &color, int width, int height, int margin)
233 {
234 // E
235 //points
236 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.5},{0.5,0.5},{0.0,1.0},{1.0,1.0}};
237 //lines
238 int arr2[4][2] = {{0,1},{1,2},{2,3},{4,5}};
239 std::tuple<int, int, int, int> coords;
240 int halfmargin=margin/2;
241
242 for (int i=0;i<4;++i) {
243 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
244 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
245 rr2[i][1]][1])+halfmargin);
246 get_line_points(points,coords,color,width,height,margin);
247 }
248 }
249
250 void draw_font_N(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
251 oat> &color, int width, int height, int margin)
252 {
253 // N
254 //points
255 float arr[6][2] = {{0.0,0.0},{0.0,1.0},{1.0,0.0},{1.0,1.0},{0.0,0.0},{1.0,1.0}};
256 //lines
257 int arr2[3][2] = {{0,1},{2,3},{4,5}};
14 Appendix A: Source Code Listings 274

258 std::tuple<int, int, int, int> coords;


259 int halfmargin=margin/2;
260
261 for (int i=0;i<3;++i) {
262 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
263 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
264 rr2[i][1]][1])+halfmargin);
265 get_line_points(points,coords,color,width,height,margin);
266 }
267 }
268
269 void draw_font_U(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
270 oat> &color, int width, int height, int margin)
271 {
272 // U
273 //points
274 float arr[4][2] = {{0.0,0.0},{0.0,1.0},{1.0,1.0},{1.0,0.5}};
275 //lines
276 int arr2[3][2] = {{0,1},{1,2},{2,3}};
277 std::tuple<int, int, int, int> coords;
278 int halfmargin=margin/2;
279
280 for (int i=0;i<3;++i) {
281 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
282 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
283 rr2[i][1]][1])+halfmargin);
284 get_line_points(points,coords,color,width,height,margin);
285 }
286 }
287
288 void draw_font_C(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
289 oat> &color, int width, int height, int margin)
290 {
291 // C
292 //points
293 float arr[4][2] = {{0.5,0.0},{0.0,0.0},{0.0,1.0},{1.0,1.0}};
294 //lines
295 int arr2[3][2] = {{0,1},{1,2},{2,3}};
296 std::tuple<int, int, int, int> coords;
297 int halfmargin=margin/2;
298
299 for (int i=0;i<3;++i) {
300 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
14 Appendix A: Source Code Listings 275

301 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a


302 rr2[i][1]][1])+halfmargin);
303 get_line_points(points,coords,color,width,height,margin);
304 }
305 }
306
307 void draw_font_Y(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
308 oat> &color, int width, int height, int margin)
309 {
310 // Y
311 //points
312 float arr[4][2] = {{0.5,0.6},{0.0,0.0},{1.0,0.0},{0.5,1.0}};
313 //lines
314 int arr2[3][2] = {{0,1},{0,2},{0,3}};
315 std::tuple<int, int, int, int> coords;
316 int halfmargin=margin/2;
317
318 for (int i=0;i<3;++i) {
319 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
320 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
321 rr2[i][1]][1])+halfmargin);
322 get_line_points(points,coords,color,width,height,margin);
323 }
324 }
325
326 void draw_font_P(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
327 oat> &color, int width, int height, int margin)
328 {
329 // P
330 //points
331 float arr[5][2] = {{0.0,1.0},{0.0,0.0},{1.0,0.0},{1.0,0.3},{0.0,0.6}};
332 //lines
333 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,4}};
334 std::tuple<int, int, int, int> coords;
335 int halfmargin=margin/2;
336
337 for (int i=0;i<4;++i) {
338 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
339 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
340 rr2[i][1]][1])+halfmargin);
341 get_line_points(points,coords,color,width,height,margin);
342 }
343 }
14 Appendix A: Source Code Listings 276

344
345 void draw_font_T(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
346 oat> &color, int width, int height, int margin)
347 {
348 // T
349 //points
350 float arr[3][2] = {{0.0,0.0},{1.0,0.0},{1.0,1.0}};
351 //lines
352 int arr2[2][2] = {{0,1},{1,2}};
353 std::tuple<int, int, int, int> coords;
354 int halfmargin=margin/2;
355
356 for (int i=0;i<2;++i) {
357 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
358 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
359 rr2[i][1]][1])+halfmargin);
360 get_line_points(points,coords,color,width,height,margin);
361 }
362 }
363
364 void draw_filled_circle(int x, int y, int radius, std::vector<std::tuple<float, floa\
365 t, float>> &image, std::tuple<float, float, float> &color, int width, int height, in
366 t margin)
367 {
368 int x0 = 0;
369 int y0 = radius;
370 int d = 3 - 2 * radius;
371 if (!radius) return;
372
373 auto drawline = [&](int sx, int ex, int ny)
374 {
375 for (int i = sx; i <= ex; i++)
376 image[get_index(i, ny, width+margin)]=color;
377 };
378
379 while (y0 >= x0)
380 {
381 drawline(x - x0, x + x0, y - y0);
382 drawline(x - y0, x + y0, y - x0);
383 drawline(x - x0, x + x0, y + y0);
384 drawline(x - y0, x + y0, y + x0);
385 if (d < 0) d += 4 * x0++ + 6;
386 else d += 4 * (x0++ - y0--) + 10;
14 Appendix A: Source Code Listings 277

387 }
388 }
389
390 void get_all_ys(std::vector<int> &ys,std::vector<std::tuple<int,int>> &coords)
391 {
392 for (auto& c : coords) {
393 ys.push_back(std::get<1>(c));
394 }
395
396 sort(ys.begin(), ys.end());
397 ys.erase( unique( ys.begin(), ys.end() ), ys.end() );
398 }
399
400 void draw_line_coords(int x1, int y1, int x2, int y2,std::vector<std::tuple<int,int>\
401 > &coords)
402 {
403 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
404 dx = x2 - x1; dy = y2 - y1;
405 if (dx == 0)
406 {
407 if (y2 < y1) std::swap(y1, y2);
408 for (y = y1; y <= y2; y++)
409 coords.push_back(std::make_tuple(x1,y));
410 return;
411 }
412 if (dy == 0)
413 {
414 if (x2 < x1) std::swap(x1, x2);
415 for (x = x1; x <= x2; x++)
416 coords.push_back(std::make_tuple(x,y1));
417 return;
418 }
419 dx1 = abs(dx); dy1 = abs(dy);
420 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
421 if (dy1 <= dx1)
422 {
423 if (dx >= 0)
424 {
425 x = x1; y = y1; xe = x2;
426 }
427 else
428 {
429 x = x2; y = y2; xe = x1;
14 Appendix A: Source Code Listings 278

430 }
431 coords.push_back(std::make_tuple(x,y));
432 for (i = 0; x<xe; i++)
433 {
434 x = x + 1;
435 if (px<0)
436 px = px + 2 * dy1;
437 else
438 {
439 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
440 px = px + 2 * (dy1 - dx1);
441 }
442 coords.push_back(std::make_tuple(x,y));
443 }
444 }
445 else
446 {
447 if (dy >= 0)
448 {
449 x = x1; y = y1; ye = y2;
450 }
451 else
452 {
453 x = x2; y = y2; ye = y1;
454 }
455 coords.push_back(std::make_tuple(x,y));
456 for (i = 0; y<ye; i++)
457 {
458 y = y + 1;
459 if (py <= 0)
460 py = py + 2 * dx1;
461 else
462 {
463 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
464 py = py + 2 * (dx1 - dy1);
465 }
466 coords.push_back(std::make_tuple(x,y));
467 }
468 }
469 }
470
471 void draw_filled_wedge(int x_cen,int y_cen,int rad,int start_ang,int end_ang,std::ve\
472 ctor<std::tuple<float, float, float>> &image,std::tuple<float, float, float> &color,
14 Appendix A: Source Code Listings 279

473 int width, int height)


474 {
475 std::vector<std::tuple<int,int>> coords;
476
477 float ang=(((start_ang<=end_ang)?start_ang:end_ang)*(M_PI/180));
478 float range=(((end_ang>start_ang)?end_ang:start_ang)*(M_PI/180));
479 float x=(rad*cos(ang));
480 float y=(rad*sin(ang));
481 do
482 {
483 coords.push_back(std::make_tuple((int)(x_cen+x+0.5),(int)(y_cen-y+0.5)));
484 ang+=0.001;
485 x=(rad*cos(ang));
486 y=(rad*sin(ang));
487 }
488 while(ang<=range);
489
490 std::tuple<int,int> co1=coords.front();
491 std::tuple<int,int> co2=coords.back();
492
493 draw_line_coords(x_cen,y_cen,std::get<0>(co1),std::get<1>(co1),coords);
494 draw_line_coords(x_cen,y_cen,std::get<0>(co2),std::get<1>(co2),coords);
495
496 std::vector<int> ys;
497 std::vector<int> xs;
498 get_all_ys(ys,coords);
499 std::vector<std::tuple<int,int,int,int>> lines;
500
501 for (int search=0;search<=ys.size();++search)
502 {
503 for (auto& c : coords) {
504 if (std::get<1>(c) == ys[search]) {
505 xs.push_back(std::get<0>(c));
506 }
507 }
508 sort(xs.begin(), xs.end());
509 lines.push_back(std::make_tuple(xs.front(),ys[search],xs.back(),ys[search]));
510 xs.clear();
511 }
512
513 auto drawline = [&](int sx, int ex, int ny)
514 {
515 for (int i = sx; i <= ex; i++)
14 Appendix A: Source Code Listings 280

516 image[get_index(i, ny, width)]=color;


517 };
518
519 for (auto& l : lines) {
520 drawline(std::get<0>(l),std::get<2>(l),std::get<1>(l));
521 }
522 }
523
524 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
525 height, std::string filename)
526 {
527 std::tuple<float, float, float> color;
528 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);
529 out << "P6" << std::endl << width << ' ' << height << std::endl << "255" << std::en\
530 dl;
531
532 for (int i=0;i<(width*height);++i)
533 {
534 color=image[i];
535 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*255.0f) << char(\
536 std::get<2>(color)*255.0f);
537 }
538 out.close();
539 }
540
541 void draw(std::vector<std::tuple<int,int>> points,std::vector<std::tuple<float, floa\
542 t, float>> &image, std::tuple<float,float,float> color, int width, int height, int m
543 argin, int linesize)
544 {
545 for (auto& p : points) {
546 if (linesize == 1) {
547 image[get_index(std::get<0>(p),std::get<1>(p),width+margin)]=std::make_tuple
548 , 0.0f, 0.0f);
549 } else {
550 draw_filled_circle(std::get<0>(p),std::get<1>(p),linesize,image,color,width,
551 t,margin);
552 }
553 }
554 }
555
556 int main()
557 {
558 std::vector<std::tuple<float, float, float>> image;
14 Appendix A: Source Code Listings 281

559 std::vector<std::tuple<int,int>> points;


560 std::tuple<int, int, int, int> coords;
561 int width=1600,height=900;
562 int margin=0;
563 int linesize=2;
564 int fwidth=0;
565 int fheight=20;
566
567 get_width_from_height(fwidth,fheight);
568 get_margin_from_height(margin,fheight);
569
570 std::tuple<float,float,float> color1=std::make_tuple(1.0f,1.0f,1.0f);
571 std::tuple<float,float,float> color2=std::make_tuple(0.262745098f, 0.262745098f, 0.\
572 262745098f);
573 std::tuple<float,float,float> color3=std::make_tuple(0.6f,0.6f,0.6f);
574 std::tuple<float,float,float> color4=std::make_tuple(0.968627451f,0.5882352941f,0.3\
575 607843137f);
576
577 std::vector<std::tuple<float, float, float>> f_m;
578 f_m.resize(calc_size(fwidth, fheight, margin));
579 clear_image(f_m,fwidth,fheight,margin);
580 draw_font_M(points,color2,fwidth,fheight,margin);
581 draw(points,f_m,color2,fwidth,fheight,margin,linesize);
582 points.clear();
583 std::vector<std::tuple<float, float, float>> f_a;
584 f_a.resize(calc_size(fwidth, fheight, margin));
585 clear_image(f_a,fwidth,fheight,margin);
586 draw_font_A(points,color2,fwidth,fheight,margin);
587 draw(points,f_a,color2,fwidth,fheight,margin,linesize);
588 points.clear();
589 std::vector<std::tuple<float, float, float>> f_r;
590 f_r.resize(calc_size(fwidth, fheight, margin));
591 clear_image(f_r,fwidth,fheight,margin);
592 draw_font_R(points,color2,fwidth,fheight,margin);
593 draw(points,f_r,color2,fwidth,fheight,margin,linesize);
594 points.clear();
595 std::vector<std::tuple<float, float, float>> f_s;
596 f_s.resize(calc_size(fwidth, fheight, margin));
597 clear_image(f_s,fwidth,fheight,margin);
598 draw_font_S(points,color2,fwidth,fheight,margin);
599 draw(points,f_s,color2,fwidth,fheight,margin,linesize);
600 points.clear();
601 std::vector<std::tuple<float, float, float>> f_v;
14 Appendix A: Source Code Listings 282

602 f_v.resize(calc_size(fwidth, fheight, margin));


603 clear_image(f_v,fwidth,fheight,margin);
604 draw_font_V(points,color2,fwidth,fheight,margin);
605 draw(points,f_v,color2,fwidth,fheight,margin,linesize);
606 points.clear();
607 std::vector<std::tuple<float, float, float>> f_e;
608 f_e.resize(calc_size(fwidth, fheight, margin));
609 clear_image(f_e,fwidth,fheight,margin);
610 draw_font_E(points,color2,fwidth,fheight,margin);
611 draw(points,f_e,color2,fwidth,fheight,margin,linesize);
612 points.clear();
613 std::vector<std::tuple<float, float, float>> f_n;
614 f_n.resize(calc_size(fwidth, fheight, margin));
615 clear_image(f_n,fwidth,fheight,margin);
616 draw_font_N(points,color2,fwidth,fheight,margin);
617 draw(points,f_n,color2,fwidth,fheight,margin,linesize);
618 points.clear();
619 std::vector<std::tuple<float, float, float>> f_u;
620 f_u.resize(calc_size(fwidth, fheight, margin));
621 clear_image(f_u,fwidth,fheight,margin);
622 draw_font_U(points,color2,fwidth,fheight,margin);
623 draw(points,f_u,color2,fwidth,fheight,margin,linesize);
624 points.clear();
625 std::vector<std::tuple<float, float, float>> f_c;
626 f_c.resize(calc_size(fwidth, fheight, margin));
627 clear_image(f_c,fwidth,fheight,margin);
628 draw_font_C(points,color2,fwidth,fheight,margin);
629 draw(points,f_c,color2,fwidth,fheight,margin,linesize);
630 points.clear();
631 std::vector<std::tuple<float, float, float>> f_y;
632 f_y.resize(calc_size(fwidth, fheight, margin));
633 clear_image(f_y,fwidth,fheight,margin);
634 draw_font_Y(points,color2,fwidth,fheight,margin);
635 draw(points,f_y,color2,fwidth,fheight,margin,linesize);
636 points.clear();
637 std::vector<std::tuple<float, float, float>> f_p;
638 f_p.resize(calc_size(fwidth, fheight, margin));
639 clear_image(f_p,fwidth,fheight,margin);
640 draw_font_P(points,color2,fwidth,fheight,margin);
641 draw(points,f_p,color2,fwidth,fheight,margin,linesize);
642 points.clear();
643 std::vector<std::tuple<float, float, float>> f_t;
644 f_t.resize(calc_size(fwidth, fheight, margin));
14 Appendix A: Source Code Listings 283

645 clear_image(f_t,fwidth,fheight,margin);
646 draw_font_T(points,color2,fwidth,fheight,margin);
647 draw(points,f_t,color2,fwidth,fheight,margin,linesize);
648 points.clear();
649
650 image.resize(calc_size(width, height, margin));
651 clear_image(image,width,height,margin);
652
653 draw_filled_wedge(width/2,height/2,(height/2)*0.5,0,90,image,color1,width,height);
654 draw_filled_wedge(width/2,height/2,(height/2)*0.5,90,180,image,color2,width,height);
655 draw_filled_wedge(width/2,height/2,(height/2)*0.5,180,270,image,color3,width,height\
656 );
657 draw_filled_wedge(width/2,height/2,(height/2)*0.5,270,360,image,color4,width,height\
658 );
659
660 stamp(image,f_m,330,303,(fwidth+margin),(fheight+margin),width);
661 stamp(image,f_a,330+(1*(fwidth+margin)),303,(fwidth+margin),(fheight+margin),width);
662 stamp(image,f_r,330+(2*(fwidth+margin)),303,(fwidth+margin),(fheight+margin),width);
663 stamp(image,f_s,330+(3*(fwidth+margin)),303,(fwidth+margin),(fheight+margin),width);
664
665 stamp(image,f_v,330,554,(fwidth+margin),(fheight+margin),width);
666 stamp(image,f_e,330+(1*(fwidth+margin)),554,(fwidth+margin),(fheight+margin),width);
667 stamp(image,f_n,330+(2*(fwidth+margin)),554,(fwidth+margin),(fheight+margin),width);
668 stamp(image,f_u,330+(3*(fwidth+margin)),554,(fwidth+margin),(fheight+margin),width);
669 stamp(image,f_s,330+(4*(fwidth+margin)),554,(fwidth+margin),(fheight+margin),width);
670
671 stamp(image,f_m,1100,303,(fwidth+margin),(fheight+margin),width);
672 stamp(image,f_e,1100+(1*(fwidth+margin)),303,(fwidth+margin),(fheight+margin),width\
673 );
674 stamp(image,f_r,1100+(2*(fwidth+margin)),303,(fwidth+margin),(fheight+margin),width\
675 );
676 stamp(image,f_c,1100+(3*(fwidth+margin)),303,(fwidth+margin),(fheight+margin),width\
677 );
678 stamp(image,f_u,1100+(4*(fwidth+margin)),303,(fwidth+margin),(fheight+margin),width\
679 );
680 stamp(image,f_r,1100+(5*(fwidth+margin)),303,(fwidth+margin),(fheight+margin),width\
681 );
682 stamp(image,f_y,1100+(6*(fwidth+margin)),303,(fwidth+margin),(fheight+margin),width\
683 );
684
685 stamp(image,f_n,1100,554,(fwidth+margin),(fheight+margin),width);
686 stamp(image,f_e,1100+(1*(fwidth+margin)),554,(fwidth+margin),(fheight+margin),width\
687 );
14 Appendix A: Source Code Listings 284

688 stamp(image,f_p,1100+(2*(fwidth+margin)),554,(fwidth+margin),(fheight+margin),width\
689 );
690 stamp(image,f_t,1100+(3*(fwidth+margin)),554,(fwidth+margin),(fheight+margin),width\
691 );
692 stamp(image,f_u,1100+(4*(fwidth+margin)),554,(fwidth+margin),(fheight+margin),width\
693 );
694 stamp(image,f_n,1100+(5*(fwidth+margin)),554,(fwidth+margin),(fheight+margin),width\
695 );
696 stamp(image,f_e,1100+(6*(fwidth+margin)),554,(fwidth+margin),(fheight+margin),width\
697 );
698
699 std::cout << "saving: 16_draw_pie_chart.ppm." << std::endl;
700 save_image(image,width,height,"16_draw_pie_chart.ppm");
701
702 return 0;
703 }

16_draw_donut_chart.cpp - 24586 bytes.

1 // Compile: clang++ -std=c++17 16_draw_donut_chart.cpp -o 16_draw_donut_chart


2 #define _USE_MATH_DEFINES
3
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10 #include <algorithm>
11
12 void get_width_from_height(int &width, int height)
13 {
14 int half = height / 2;
15 width = half * 3;
16 }
17
18 void get_margin_from_height(int &margin,int height)
19 {
20 margin = int(float(height) * 0.3);
21 }
22
23 int get_index(int x, int y, int width)
24 {
14 Appendix A: Source Code Listings 285

25 return x+width*y;
26 }
27
28 int calc_size(int width, int height, int margin)
29 {
30 return (width+margin)*(height+margin);
31 }
32
33 void stamp(std::vector<std::tuple<float, float, float>> &image, std::vector<std::tup\
34 le<float, float, float>> &letter, int offsetx, int offsety, int inputwidth, int inpu
35 theight, int width)
36 {
37 int inputx=0;
38 int inputy=0;
39 for (int y = offsety; y < offsety+inputheight; ++y)
40 {
41 for (int x = offsetx; x < offsetx+inputwidth; ++x)
42 {
43 image[get_index(x,y,width)]=letter[get_index(inputx,inputy,inputwidth)];
44 inputx++;
45 }
46 inputy++;
47 inputx=0;
48 }
49 }
50
51 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
52 height, int margin)
53 {
54 for (int y=0;y<(height+margin);++y) {
55 for (int x=0;x<(width+margin);++x) {
56 image[get_index(x,y,(width+margin))]=std::make_tuple(1.0f,0.7647058824f,0.62
57 118f);
58 }
59 }
60 }
61
62 void get_line_points(std::vector<std::tuple<int,int>> &points, std::tuple<int, int, \
63 int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
64 {
65 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
66 int y2=std::get<3>(coords);
67 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
14 Appendix A: Source Code Listings 286

68 dx = x2 - x1; dy = y2 - y1;
69 if (dx == 0)
70 {
71 if (y2 < y1) std::swap(y1, y2);
72 for (y = y1; y <= y2; y++)
73 points.push_back(std::make_tuple(x1,y));
74 return;
75 }
76 if (dy == 0)
77 {
78 if (x2 < x1) std::swap(x1, x2);
79 for (x = x1; x <= x2; x++)
80 points.push_back(std::make_tuple(x,y1));
81 return;
82 }
83 dx1 = abs(dx); dy1 = abs(dy);
84 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
85 if (dy1 <= dx1)
86 {
87 if (dx >= 0)
88 {
89 x = x1; y = y1; xe = x2;
90 }
91 else
92 {
93 x = x2; y = y2; xe = x1;
94 }
95 points.push_back(std::make_tuple(x,y));
96 for (i = 0; x<xe; i++)
97 {
98 x = x + 1;
99 if (px<0)
100 px = px + 2 * dy1;
101 else
102 {
103 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
104 px = px + 2 * (dy1 - dx1);
105 }
106 points.push_back(std::make_tuple(x,y));
107 }
108 }
109 else
110 {
14 Appendix A: Source Code Listings 287

111 if (dy >= 0)


112 {
113 x = x1; y = y1; ye = y2;
114 }
115 else
116 {
117 x = x2; y = y2; ye = y1;
118 }
119 points.push_back(std::make_tuple(x,y));
120 for (i = 0; y<ye; i++)
121 {
122 y = y + 1;
123 if (py <= 0)
124 py = py + 2 * dx1;
125 else
126 {
127 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
128 py = py + 2 * (dx1 - dy1);
129 }
130 points.push_back(std::make_tuple(x,y));
131 }
132 }
133 }
134
135 void draw_font_M(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
136 oat> &color, int width, int height, int margin)
137 {
138 // M
139 //points
140 float arr[5][2] = {{0.0,1.0},{0.0,0.0},{0.5,0.3},{1.0,0.0},{1.0,1.0}};
141 //lines
142 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,4}};
143 std::tuple<int, int, int, int> coords;
144 int halfmargin=margin/2;
145
146 for (int i=0;i<4;++i) {
147 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
148 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
149 rr2[i][1]][1])+halfmargin);
150 get_line_points(points,coords,color,width,height);
151 }
152 }
153
14 Appendix A: Source Code Listings 288

154 void draw_font_A(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\


155 oat> &color, int width, int height, int margin)
156 {
157 // A
158 //points
159 float arr[4][2] = {{0.0,1.0},{0.5,0.0},{1.0,1.0},{0.0,0.6}};
160 //lines
161 int arr2[3][2] = {{0,1},{1,2},{2,3}};
162 std::tuple<int, int, int, int> coords;
163 int halfmargin=margin/2;
164
165 for (int i=0;i<3;++i) {
166 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
167 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0])+halfmargin, int(height*arr[a
168 rr2[i][1]][1])+halfmargin);
169 get_line_points(points,coords,color,width,height);
170 }
171 }
172
173 void draw_font_R(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
174 oat> &color, int width, int height, int margin)
175 {
176 // R
177 //points
178 float arr[6][2] = {{0.0,1.0},{0.0,0.0},{1.0,0.0},{1.0,0.3},{0.0,0.6},{1.0,1.0}};
179 //lines
180 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
181 std::tuple<int, int, int, int> coords;
182 int halfmargin=margin/2;
183
184 for (int i=0;i<5;++i) {
185 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
186 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
187 rr2[i][1]][1])+halfmargin);
188 get_line_points(points,coords,color,width,height);
189 }
190 }
191
192 void draw_font_S(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
193 oat> &color, int width, int height, int margin)
194 {
195 // S
196 //points
14 Appendix A: Source Code Listings 289

197 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.4},{1.0,0.6},{1.0,1.0},{0.0,1.0}};


198 //lines
199 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
200 std::tuple<int, int, int, int> coords;
201 int halfmargin=margin/2;
202
203 for (int i=0;i<5;++i) {
204 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
205 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
206 rr2[i][1]][1])+halfmargin);
207 get_line_points(points,coords,color,width,height);
208 }
209 }
210
211 void draw_font_V(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
212 oat> &color, int width, int height, int margin)
213 {
214 // V
215 //points
216 float arr[3][2] = {{0.0,0.0},{0.5,1.0},{1.0,0.0}};
217 //lines
218 int arr2[2][2] = {{0,1},{1,2}};
219 std::tuple<int, int, int, int> coords;
220 int halfmargin=margin/2;
221
222 for (int i=0;i<2;++i) {
223 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
224 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
225 rr2[i][1]][1])+halfmargin);
226 get_line_points(points,coords,color,width,height);
227 }
228 }
229
230 void draw_font_E(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
231 oat> &color, int width, int height, int margin)
232 {
233 // E
234 //points
235 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.5},{0.5,0.5},{0.0,1.0},{1.0,1.0}};
236 //lines
237 int arr2[4][2] = {{0,1},{1,2},{2,3},{4,5}};
238 std::tuple<int, int, int, int> coords;
239 int halfmargin=margin/2;
14 Appendix A: Source Code Listings 290

240
241 for (int i=0;i<4;++i) {
242 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
243 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
244 rr2[i][1]][1])+halfmargin);
245 get_line_points(points,coords,color,width,height);
246 }
247 }
248
249 void draw_font_N(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
250 oat> &color, int width, int height, int margin)
251 {
252 // N
253 //points
254 float arr[6][2] = {{0.0,0.0},{0.0,1.0},{1.0,0.0},{1.0,1.0},{0.0,0.0},{1.0,1.0}};
255 //lines
256 int arr2[3][2] = {{0,1},{2,3},{4,5}};
257 std::tuple<int, int, int, int> coords;
258 int halfmargin=margin/2;
259
260 for (int i=0;i<3;++i) {
261 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
262 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
263 rr2[i][1]][1])+halfmargin);
264 get_line_points(points,coords,color,width,height);
265 }
266 }
267
268 void draw_font_U(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
269 oat> &color, int width, int height, int margin)
270 {
271 // U
272 //points
273 float arr[4][2] = {{0.0,0.0},{0.0,1.0},{1.0,1.0},{1.0,0.5}};
274 //lines
275 int arr2[3][2] = {{0,1},{1,2},{2,3}};
276 std::tuple<int, int, int, int> coords;
277 int halfmargin=margin/2;
278
279 for (int i=0;i<3;++i) {
280 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
281 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
282 rr2[i][1]][1])+halfmargin);
14 Appendix A: Source Code Listings 291

283 get_line_points(points,coords,color,width,height);
284 }
285 }
286
287 void draw_font_C(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
288 oat> &color, int width, int height, int margin)
289 {
290 // C
291 //points
292 float arr[4][2] = {{0.5,0.0},{0.0,0.0},{0.0,1.0},{1.0,1.0}};
293 //lines
294 int arr2[3][2] = {{0,1},{1,2},{2,3}};
295 std::tuple<int, int, int, int> coords;
296 int halfmargin=margin/2;
297
298 for (int i=0;i<3;++i) {
299 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
300 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
301 rr2[i][1]][1])+halfmargin);
302 get_line_points(points,coords,color,width,height);
303 }
304 }
305
306 void draw_font_Y(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
307 oat> &color, int width, int height, int margin)
308 {
309 // Y
310 //points
311 float arr[4][2] = {{0.5,0.6},{0.0,0.0},{1.0,0.0},{0.5,1.0}};
312 //lines
313 int arr2[3][2] = {{0,1},{0,2},{0,3}};
314 std::tuple<int, int, int, int> coords;
315 int halfmargin=margin/2;
316
317 for (int i=0;i<3;++i) {
318 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
319 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
320 rr2[i][1]][1])+halfmargin);
321 get_line_points(points,coords,color,width,height);
322 }
323 }
324
325 void draw_font_P(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
14 Appendix A: Source Code Listings 292

326 oat> &color, int width, int height, int margin)


327 {
328 // P
329 //points
330 float arr[5][2] = {{0.0,1.0},{0.0,0.0},{1.0,0.0},{1.0,0.3},{0.0,0.6}};
331 //lines
332 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,4}};
333 std::tuple<int, int, int, int> coords;
334 int halfmargin=margin/2;
335
336 for (int i=0;i<4;++i) {
337 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
338 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
339 rr2[i][1]][1])+halfmargin);
340 get_line_points(points,coords,color,width,height);
341 }
342 }
343
344 void draw_font_T(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
345 oat> &color, int width, int height, int margin)
346 {
347 // T
348 //points
349 float arr[3][2] = {{0.0,0.0},{1.0,0.0},{1.0,1.0}};
350 //lines
351 int arr2[2][2] = {{0,1},{1,2}};
352 std::tuple<int, int, int, int> coords;
353 int halfmargin=margin/2;
354
355 for (int i=0;i<2;++i) {
356 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
357 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
358 rr2[i][1]][1])+halfmargin);
359 get_line_points(points,coords,color,width,height);
360 }
361 }
362
363 void draw_filled_circle(int x, int y, int radius, std::vector<std::tuple<float, floa\
364 t, float>> &image, std::tuple<float, float, float> &color, int width, int height, in
365 t margin)
366 {
367 int x0 = 0;
368 int y0 = radius;
14 Appendix A: Source Code Listings 293

369 int d = 3 - 2 * radius;


370 if (!radius) return;
371
372 auto drawline = [&](int sx, int ex, int ny)
373 {
374 for (int i = sx; i <= ex; i++)
375 image[get_index(i, ny, width+margin)]=color;
376 };
377
378 while (y0 >= x0)
379 {
380 drawline(x - x0, x + x0, y - y0);
381 drawline(x - y0, x + y0, y - x0);
382 drawline(x - x0, x + x0, y + y0);
383 drawline(x - y0, x + y0, y + x0);
384 if (d < 0) d += 4 * x0++ + 6;
385 else d += 4 * (x0++ - y0--) + 10;
386 }
387 }
388
389 void draw_filled_circle2(int x, int y, int radius, std::vector<std::tuple<float, flo\
390 at, float>> &image, std::tuple<float, float, float> &color, int width, int height)
391 {
392 int x0 = 0;
393 int y0 = radius;
394 int d = 3 - 2 * radius;
395 if (!radius) return;
396
397 auto drawline = [&](int sx, int ex, int ny)
398 {
399 for (int i = sx; i <= ex; i++)
400 image[get_index(i, ny, width)]=color;
401 };
402
403 while (y0 >= x0)
404 {
405 drawline(x - x0, x + x0, y - y0);
406 drawline(x - y0, x + y0, y - x0);
407 drawline(x - x0, x + x0, y + y0);
408 drawline(x - y0, x + y0, y + x0);
409 if (d < 0) d += 4 * x0++ + 6;
410 else d += 4 * (x0++ - y0--) + 10;
411 }
14 Appendix A: Source Code Listings 294

412 }
413
414 void get_all_ys(std::vector<int> &ys,std::vector<std::tuple<int,int>> &coords)
415 {
416 for (auto& c : coords) {
417 ys.push_back(std::get<1>(c));
418 }
419
420 sort(ys.begin(), ys.end());
421 ys.erase( unique( ys.begin(), ys.end() ), ys.end() );
422 }
423
424 void draw_line_coords(int x1, int y1, int x2, int y2,std::vector<std::tuple<int,int>\
425 > &coords)
426 {
427 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
428 dx = x2 - x1; dy = y2 - y1;
429 if (dx == 0)
430 {
431 if (y2 < y1) std::swap(y1, y2);
432 for (y = y1; y <= y2; y++)
433 coords.push_back(std::make_tuple(x1,y));
434 return;
435 }
436 if (dy == 0)
437 {
438 if (x2 < x1) std::swap(x1, x2);
439 for (x = x1; x <= x2; x++)
440 coords.push_back(std::make_tuple(x,y1));
441 return;
442 }
443 dx1 = abs(dx); dy1 = abs(dy);
444 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
445 if (dy1 <= dx1)
446 {
447 if (dx >= 0)
448 {
449 x = x1; y = y1; xe = x2;
450 }
451 else
452 {
453 x = x2; y = y2; xe = x1;
454 }
14 Appendix A: Source Code Listings 295

455 coords.push_back(std::make_tuple(x,y));
456 for (i = 0; x<xe; i++)
457 {
458 x = x + 1;
459 if (px<0)
460 px = px + 2 * dy1;
461 else
462 {
463 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
464 px = px + 2 * (dy1 - dx1);
465 }
466 coords.push_back(std::make_tuple(x,y));
467 }
468 }
469 else
470 {
471 if (dy >= 0)
472 {
473 x = x1; y = y1; ye = y2;
474 }
475 else
476 {
477 x = x2; y = y2; ye = y1;
478 }
479 coords.push_back(std::make_tuple(x,y));
480 for (i = 0; y<ye; i++)
481 {
482 y = y + 1;
483 if (py <= 0)
484 py = py + 2 * dx1;
485 else
486 {
487 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
488 py = py + 2 * (dx1 - dy1);
489 }
490 coords.push_back(std::make_tuple(x,y));
491 }
492 }
493 }
494
495 void draw_filled_wedge(int x_cen,int y_cen,int rad,int start_ang,int end_ang,std::ve\
496 ctor<std::tuple<float, float, float>> &image,std::tuple<float, float, float> &color,
497 int width, int height)
14 Appendix A: Source Code Listings 296

498 {
499 std::vector<std::tuple<int,int>> coords;
500
501 float ang=(((start_ang<=end_ang)?start_ang:end_ang)*(M_PI/180));
502 float range=(((end_ang>start_ang)?end_ang:start_ang)*(M_PI/180));
503 float x=(rad*cos(ang));
504 float y=(rad*sin(ang));
505 do
506 {
507 coords.push_back(std::make_tuple((int)(x_cen+x+0.5),(int)(y_cen-y+0.5)));
508 ang+=0.001;
509 x=(rad*cos(ang));
510 y=(rad*sin(ang));
511 }
512 while(ang<=range);
513
514 std::tuple<int,int> co1=coords.front();
515 std::tuple<int,int> co2=coords.back();
516
517 draw_line_coords(x_cen,y_cen,std::get<0>(co1),std::get<1>(co1),coords);
518 draw_line_coords(x_cen,y_cen,std::get<0>(co2),std::get<1>(co2),coords);
519
520 std::vector<int> ys;
521 std::vector<int> xs;
522 get_all_ys(ys,coords);
523 std::vector<std::tuple<int,int,int,int>> lines;
524
525 for (int search=0;search<=ys.size();++search)
526 {
527 for (auto& c : coords) {
528 if (std::get<1>(c) == ys[search]) {
529 xs.push_back(std::get<0>(c));
530 }
531 }
532 sort(xs.begin(), xs.end());
533 lines.push_back(std::make_tuple(xs.front(),ys[search],xs.back(),ys[search]));
534 xs.clear();
535 }
536
537 auto drawline = [&](int sx, int ex, int ny)
538 {
539 for (int i = sx; i <= ex; i++)
540 image[get_index(i, ny, width)]=color;
14 Appendix A: Source Code Listings 297

541 };
542
543 for (auto& l : lines) {
544 drawline(std::get<0>(l),std::get<2>(l),std::get<1>(l));
545 }
546 }
547
548 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
549 height, std::string filename)
550 {
551 std::tuple<float, float, float> color;
552 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);
553 out << "P6" << std::endl << width << ' ' << height << std::endl << "255" << std::en\
554 dl;
555
556 for (int i=0;i<(width*height);++i)
557 {
558 color=image[i];
559 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*255.0f) << char(\
560 std::get<2>(color)*255.0f);
561 }
562 out.close();
563 }
564
565 void draw(std::vector<std::tuple<int,int>> points,std::vector<std::tuple<float, floa\
566 t, float>> &image, std::tuple<float,float,float> color, int width, int height, int m
567 argin, int linesize)
568 {
569 for (auto& p : points) {
570 if (linesize == 1) {
571 image[get_index(std::get<0>(p),std::get<1>(p),width+margin)]=std::make_tuple
572 , 0.0f, 0.0f);
573 } else {
574 draw_filled_circle(std::get<0>(p),std::get<1>(p),linesize,image,color,width,
575 t,margin);
576 }
577 }
578 }
579
580 void draw2(std::vector<std::tuple<int,int>> points,std::vector<std::tuple<float, flo\
581 at, float>> &image, std::tuple<float,float,float> color, int width, int height, int
582 linesize)
583 {
14 Appendix A: Source Code Listings 298

584 for (auto& p : points) {


585 if (linesize == 1) {
586 image[get_index(std::get<0>(p),std::get<1>(p),width)]=std::make_tuple(0.0f,
587 0.0f);
588 } else {
589 draw_filled_circle2(std::get<0>(p),std::get<1>(p),linesize,image,color,width
590 ht);
591 }
592 }
593 }
594
595 int main()
596 {
597 std::vector<std::tuple<float, float, float>> image;
598 std::vector<std::tuple<int,int>> points;
599 std::tuple<int, int, int, int> coords;
600 int width=1600,height=900;
601 int margin=0;
602 int linesize=2;
603 int fwidth=0;
604 int fheight=20;
605 int label_x=0;
606
607 get_width_from_height(fwidth,fheight);
608 get_margin_from_height(margin,fheight);
609 label_x=(fwidth+margin)/2;
610
611 std::tuple<float,float,float> color0=std::make_tuple(1.0f,0.7647058824f,0.623529411\
612 8f);
613 std::tuple<float,float,float> color1=std::make_tuple(0.968627451f,0.5882352941f,0.3\
614 607843137f);
615 std::tuple<float,float,float> color2=std::make_tuple(0.262745098f, 0.262745098f, 0.\
616 262745098f);
617
618 std::vector<std::tuple<float, float, float>> f_m;
619 f_m.resize(calc_size(fwidth, fheight, margin));
620 clear_image(f_m,fwidth,fheight,margin);
621 draw_font_M(points,color2,fwidth,fheight,margin);
622 draw(points,f_m,color2,fwidth,fheight,margin,linesize);
623 points.clear();
624 std::vector<std::tuple<float, float, float>> f_a;
625 f_a.resize(calc_size(fwidth, fheight, margin));
626 clear_image(f_a,fwidth,fheight,margin);
14 Appendix A: Source Code Listings 299

627 draw_font_A(points,color2,fwidth,fheight,margin);
628 draw(points,f_a,color2,fwidth,fheight,margin,linesize);
629 points.clear();
630 std::vector<std::tuple<float, float, float>> f_r;
631 f_r.resize(calc_size(fwidth, fheight, margin));
632 clear_image(f_r,fwidth,fheight,margin);
633 draw_font_R(points,color2,fwidth,fheight,margin);
634 draw(points,f_r,color2,fwidth,fheight,margin,linesize);
635 points.clear();
636 std::vector<std::tuple<float, float, float>> f_s;
637 f_s.resize(calc_size(fwidth, fheight, margin));
638 clear_image(f_s,fwidth,fheight,margin);
639 draw_font_S(points,color2,fwidth,fheight,margin);
640 draw(points,f_s,color2,fwidth,fheight,margin,linesize);
641 points.clear();
642 std::vector<std::tuple<float, float, float>> f_v;
643 f_v.resize(calc_size(fwidth, fheight, margin));
644 clear_image(f_v,fwidth,fheight,margin);
645 draw_font_V(points,color2,fwidth,fheight,margin);
646 draw(points,f_v,color2,fwidth,fheight,margin,linesize);
647 points.clear();
648 std::vector<std::tuple<float, float, float>> f_e;
649 f_e.resize(calc_size(fwidth, fheight, margin));
650 clear_image(f_e,fwidth,fheight,margin);
651 draw_font_E(points,color2,fwidth,fheight,margin);
652 draw(points,f_e,color2,fwidth,fheight,margin,linesize);
653 points.clear();
654 std::vector<std::tuple<float, float, float>> f_n;
655 f_n.resize(calc_size(fwidth, fheight, margin));
656 clear_image(f_n,fwidth,fheight,margin);
657 draw_font_N(points,color2,fwidth,fheight,margin);
658 draw(points,f_n,color2,fwidth,fheight,margin,linesize);
659 points.clear();
660 std::vector<std::tuple<float, float, float>> f_u;
661 f_u.resize(calc_size(fwidth, fheight, margin));
662 clear_image(f_u,fwidth,fheight,margin);
663 draw_font_U(points,color2,fwidth,fheight,margin);
664 draw(points,f_u,color2,fwidth,fheight,margin,linesize);
665 points.clear();
666 std::vector<std::tuple<float, float, float>> f_c;
667 f_c.resize(calc_size(fwidth, fheight, margin));
668 clear_image(f_c,fwidth,fheight,margin);
669 draw_font_C(points,color2,fwidth,fheight,margin);
14 Appendix A: Source Code Listings 300

670 draw(points,f_c,color2,fwidth,fheight,margin,linesize);
671 points.clear();
672 std::vector<std::tuple<float, float, float>> f_y;
673 f_y.resize(calc_size(fwidth, fheight, margin));
674 clear_image(f_y,fwidth,fheight,margin);
675 draw_font_Y(points,color2,fwidth,fheight,margin);
676 draw(points,f_y,color2,fwidth,fheight,margin,linesize);
677 points.clear();
678 std::vector<std::tuple<float, float, float>> f_p;
679 f_p.resize(calc_size(fwidth, fheight, margin));
680 clear_image(f_p,fwidth,fheight,margin);
681 draw_font_P(points,color2,fwidth,fheight,margin);
682 draw(points,f_p,color2,fwidth,fheight,margin,linesize);
683 points.clear();
684 std::vector<std::tuple<float, float, float>> f_t;
685 f_t.resize(calc_size(fwidth, fheight, margin));
686 clear_image(f_t,fwidth,fheight,margin);
687 draw_font_T(points,color2,fwidth,fheight,margin);
688 draw(points,f_t,color2,fwidth,fheight,margin,linesize);
689 points.clear();
690
691 image.resize(calc_size(width, height, margin));
692 clear_image(image,width,height,margin);
693
694 // 320, 640, 960, 1280
695 draw_filled_circle2(320,height*0.4,92,image,color1,width,height);
696 draw_filled_circle2(320,height*0.4,78,image,color2,width,height);
697 draw_filled_circle2(320,height*0.4,72,image,color1,width,height);
698 draw_filled_wedge(320,height*0.4,62,0,360,image,color2,width,height);
699 draw_filled_circle2(320,height*0.4,31,image,color1,width,height);
700 coords=std::make_tuple(320,436,320,436+38);
701 get_line_points(points,coords,color2,width,height);
702 draw2(points,image,color2,width,height,3);
703 draw_filled_circle2(320,436+38+8,8,image,color2,width,height);
704 draw_filled_circle2(320,436+38+8,3,image,color0,width,height);
705
706 draw_filled_circle2(640,height*0.4,92,image,color1,width,height);
707 draw_filled_circle2(640,height*0.4,78,image,color2,width,height);
708 draw_filled_circle2(640,height*0.4,72,image,color1,width,height);
709 draw_filled_wedge(640,height*0.4,62,90,360,image,color2,width,height);
710 draw_filled_circle2(640,height*0.4,31,image,color1,width,height);
711 coords=std::make_tuple(640,436,640,436+38);
712 get_line_points(points,coords,color2,width,height);
14 Appendix A: Source Code Listings 301

713 draw2(points,image,color2,width,height,3);
714 draw_filled_circle2(640,436+38+8,8,image,color2,width,height);
715 draw_filled_circle2(640,436+38+8,3,image,color0,width,height);
716
717 draw_filled_circle2(960,height*0.4,92,image,color1,width,height);
718 draw_filled_circle2(960,height*0.4,78,image,color2,width,height);
719 draw_filled_circle2(960,height*0.4,72,image,color1,width,height);
720 draw_filled_wedge(960,height*0.4,62,180,360,image,color2,width,height);
721 draw_filled_circle2(960,height*0.4,31,image,color1,width,height);
722 coords=std::make_tuple(960,436,960,436+38);
723 get_line_points(points,coords,color2,width,height);
724 draw2(points,image,color2,width,height,3);
725 draw_filled_circle2(960,436+38+8,8,image,color2,width,height);
726 draw_filled_circle2(960,436+38+8,3,image,color0,width,height);
727
728 draw_filled_circle2(1280,height*0.4,92,image,color1,width,height);
729 draw_filled_circle2(1280,height*0.4,78,image,color2,width,height);
730 draw_filled_circle2(1280,height*0.4,72,image,color1,width,height);
731 draw_filled_wedge(1280,height*0.4,62,270,360,image,color2,width,height);
732 draw_filled_circle2(1280,height*0.4,31,image,color1,width,height);
733 coords=std::make_tuple(1280,436,1280,436+38);
734 get_line_points(points,coords,color2,width,height);
735 draw2(points,image,color2,width,height,3);
736 draw_filled_circle2(1280,436+38+8,8,image,color2,width,height);
737 draw_filled_circle2(1280,436+38+8,3,image,color0,width,height);
738
739 // Labels
740 stamp(image,f_m,320-(4*label_x),512,(fwidth+margin),(fheight+margin),width);
741 stamp(image,f_a,320-(4*label_x)+(1*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
742 rgin),width);
743 stamp(image,f_r,320-(4*label_x)+(2*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
744 rgin),width);
745 stamp(image,f_s,320-(4*label_x)+(3*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
746 rgin),width);
747
748 stamp(image,f_v,640-(5*label_x),512,(fwidth+margin),(fheight+margin),width);
749 stamp(image,f_e,640-(5*label_x)+(1*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
750 rgin),width);
751 stamp(image,f_n,640-(5*label_x)+(2*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
752 rgin),width);
753 stamp(image,f_u,640-(5*label_x)+(3*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
754 rgin),width);
755 stamp(image,f_s,640-(5*label_x)+(4*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
14 Appendix A: Source Code Listings 302

756 rgin),width);
757
758 stamp(image,f_n,960-(7*label_x),512,(fwidth+margin),(fheight+margin),width);
759 stamp(image,f_e,960-(7*label_x)+(1*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
760 rgin),width);
761 stamp(image,f_p,960-(7*label_x)+(2*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
762 rgin),width);
763 stamp(image,f_t,960-(7*label_x)+(3*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
764 rgin),width);
765 stamp(image,f_u,960-(7*label_x)+(4*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
766 rgin),width);
767 stamp(image,f_n,960-(7*label_x)+(5*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
768 rgin),width);
769 stamp(image,f_e,960-(7*label_x)+(6*(fwidth+margin)),512,(fwidth+margin),(fheight+ma\
770 rgin),width);
771
772 stamp(image,f_m,1280-(7*label_x),512,(fwidth+margin),(fheight+margin),width);
773 stamp(image,f_e,1280-(7*label_x)+(1*(fwidth+margin)),512,(fwidth+margin),(fheight+m\
774 argin),width);
775 stamp(image,f_r,1280-(7*label_x)+(2*(fwidth+margin)),512,(fwidth+margin),(fheight+m\
776 argin),width);
777 stamp(image,f_c,1280-(7*label_x)+(3*(fwidth+margin)),512,(fwidth+margin),(fheight+m\
778 argin),width);
779 stamp(image,f_u,1280-(7*label_x)+(4*(fwidth+margin)),512,(fwidth+margin),(fheight+m\
780 argin),width);
781 stamp(image,f_r,1280-(7*label_x)+(5*(fwidth+margin)),512,(fwidth+margin),(fheight+m\
782 argin),width);
783 stamp(image,f_y,1280-(7*label_x)+(6*(fwidth+margin)),512,(fwidth+margin),(fheight+m\
784 argin),width);
785
786 std::cout << "saving: 16_draw_donut_chart.ppm." << std::endl;
787 save_image(image,width,height,"16_draw_donut_chart.ppm");
788
789 return 0;
790 }
14 Appendix A: Source Code Listings 303

16_draw_table.cpp - 29528 bytes.


1 // Compile: clang++ -std=c++17 16_draw_table.cpp -o 16_draw_table
2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <random>
8 #include <cmath>
9
10 void get_width_from_height(int &width, int height)
11 {
12 int half = height / 2;
13 width = half * 3;
14 }
15
16 void get_margin_from_height(int &margin,int height)
17 {
18 margin = int(float(height) * 0.3);
19 }
20
21 int get_index(int x, int y, int width)
22 {
23 return x+width*y;
24 }
25
26 int calc_size(int width, int height, int margin)
27 {
28 return (width+margin)*(height+margin);
29 }
30
31 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
32 height, int margin)
33 {
34 for (int y=0;y<(height+margin);++y) {
35 for (int x=0;x<(width+margin);++x) {
36 image[get_index(x,y,(width+margin))]=std::make_tuple(1.0f,0.7647058824f,0.62
37 118f);
38 }
39 }
40 }
41
42 void stamp(std::vector<std::tuple<float, float, float>> &image, std::vector<std::tup\
14 Appendix A: Source Code Listings 304

43 le<float, float, float>> &letter, int offsetx, int offsety, int inputwidth, int inpu
44 theight, int width)
45 {
46 int inputx=0;
47 int inputy=0;
48 for (int y = offsety; y < offsety+inputheight; ++y)
49 {
50 for (int x = offsetx; x < offsetx+inputwidth; ++x)
51 {
52 image[get_index(x,y,width)]=letter[get_index(inputx,inputy,inputwidth)];
53 inputx++;
54 }
55 inputy++;
56 inputx=0;
57 }
58 }
59
60 void get_line_points(std::vector<std::tuple<int,int>> &points, std::tuple<int, int, \
61 int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
62 {
63 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
64 int y2=std::get<3>(coords);
65 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
66 dx = x2 - x1; dy = y2 - y1;
67 if (dx == 0)
68 {
69 if (y2 < y1) std::swap(y1, y2);
70 for (y = y1; y <= y2; y++)
71 points.push_back(std::make_tuple(x1,y));
72 return;
73 }
74 if (dy == 0)
75 {
76 if (x2 < x1) std::swap(x1, x2);
77 for (x = x1; x <= x2; x++)
78 points.push_back(std::make_tuple(x,y1));
79 return;
80 }
81 dx1 = abs(dx); dy1 = abs(dy);
82 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
83 if (dy1 <= dx1)
84 {
85 if (dx >= 0)
14 Appendix A: Source Code Listings 305

86 {
87 x = x1; y = y1; xe = x2;
88 }
89 else
90 {
91 x = x2; y = y2; xe = x1;
92 }
93 points.push_back(std::make_tuple(x,y));
94 for (i = 0; x<xe; i++)
95 {
96 x = x + 1;
97 if (px<0)
98 px = px + 2 * dy1;
99 else
100 {
101 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
102 px = px + 2 * (dy1 - dx1);
103 }
104 points.push_back(std::make_tuple(x,y));
105 }
106 }
107 else
108 {
109 if (dy >= 0)
110 {
111 x = x1; y = y1; ye = y2;
112 }
113 else
114 {
115 x = x2; y = y2; ye = y1;
116 }
117 points.push_back(std::make_tuple(x,y));
118 for (i = 0; y<ye; i++)
119 {
120 y = y + 1;
121 if (py <= 0)
122 py = py + 2 * dx1;
123 else
124 {
125 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
126 py = py + 2 * (dx1 - dy1);
127 }
128 points.push_back(std::make_tuple(x,y));
14 Appendix A: Source Code Listings 306

129 }
130 }
131 }
132
133 void draw_font_M(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
134 oat> &color, int width, int height, int margin)
135 {
136 // M
137 //points
138 float arr[5][2] = {{0.0,1.0},{0.0,0.0},{0.5,0.3},{1.0,0.0},{1.0,1.0}};
139 //lines
140 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,4}};
141 std::tuple<int, int, int, int> coords;
142 int halfmargin=margin/2;
143
144 for (int i=0;i<4;++i) {
145 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
146 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
147 rr2[i][1]][1])+halfmargin);
148 get_line_points(points,coords,color,width,height);
149 }
150 }
151
152 void draw_font_A(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
153 oat> &color, int width, int height, int margin)
154 {
155 // A
156 //points
157 float arr[4][2] = {{0.0,1.0},{0.5,0.0},{1.0,1.0},{0.0,0.6}};
158 //lines
159 int arr2[3][2] = {{0,1},{1,2},{2,3}};
160 std::tuple<int, int, int, int> coords;
161 int halfmargin=margin/2;
162
163 for (int i=0;i<3;++i) {
164 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
165 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0])+halfmargin, int(height*arr[a
166 rr2[i][1]][1])+halfmargin);
167 get_line_points(points,coords,color,width,height);
168 }
169 }
170
171 void draw_font_R(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
14 Appendix A: Source Code Listings 307

172 oat> &color, int width, int height, int margin)


173 {
174 // R
175 //points
176 float arr[6][2] = {{0.0,1.0},{0.0,0.0},{1.0,0.0},{1.0,0.3},{0.0,0.6},{1.0,1.0}};
177 //lines
178 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
179 std::tuple<int, int, int, int> coords;
180 int halfmargin=margin/2;
181
182 for (int i=0;i<5;++i) {
183 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
184 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
185 rr2[i][1]][1])+halfmargin);
186 get_line_points(points,coords,color,width,height);
187 }
188 }
189
190 void draw_font_S(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
191 oat> &color, int width, int height, int margin)
192 {
193 // S
194 //points
195 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.4},{1.0,0.6},{1.0,1.0},{0.0,1.0}};
196 //lines
197 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
198 std::tuple<int, int, int, int> coords;
199 int halfmargin=margin/2;
200
201 for (int i=0;i<5;++i) {
202 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
203 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
204 rr2[i][1]][1])+halfmargin);
205 get_line_points(points,coords,color,width,height);
206 }
207 }
208
209 void draw_font_E(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
210 oat> &color, int width, int height, int margin)
211 {
212 // E
213 //points
214 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.5},{0.5,0.5},{0.0,1.0},{1.0,1.0}};
14 Appendix A: Source Code Listings 308

215 //lines
216 int arr2[4][2] = {{0,1},{1,2},{2,3},{4,5}};
217 std::tuple<int, int, int, int> coords;
218 int halfmargin=margin/2;
219
220 for (int i=0;i<4;++i) {
221 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
222 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
223 rr2[i][1]][1])+halfmargin);
224 get_line_points(points,coords,color,width,height);
225 }
226 }
227
228 void draw_font_U(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
229 oat> &color, int width, int height, int margin)
230 {
231 // U
232 //points
233 float arr[4][2] = {{0.0,0.0},{0.0,1.0},{1.0,1.0},{1.0,0.5}};
234 //lines
235 int arr2[3][2] = {{0,1},{1,2},{2,3}};
236 std::tuple<int, int, int, int> coords;
237 int halfmargin=margin/2;
238
239 for (int i=0;i<3;++i) {
240 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
241 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
242 rr2[i][1]][1])+halfmargin);
243 get_line_points(points,coords,color,width,height);
244 }
245 }
246
247 void draw_font_C(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
248 oat> &color, int width, int height, int margin)
249 {
250 // C
251 //points
252 float arr[4][2] = {{0.5,0.0},{0.0,0.0},{0.0,1.0},{1.0,1.0}};
253 //lines
254 int arr2[3][2] = {{0,1},{1,2},{2,3}};
255 std::tuple<int, int, int, int> coords;
256 int halfmargin=margin/2;
257
14 Appendix A: Source Code Listings 309

258 for (int i=0;i<3;++i) {


259 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
260 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
261 rr2[i][1]][1])+halfmargin);
262 get_line_points(points,coords,color,width,height);
263 }
264 }
265
266 void draw_font_Y(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
267 oat> &color, int width, int height, int margin)
268 {
269 // Y
270 //points
271 float arr[4][2] = {{0.5,0.6},{0.0,0.0},{1.0,0.0},{0.5,1.0}};
272 //lines
273 int arr2[3][2] = {{0,1},{0,2},{0,3}};
274 std::tuple<int, int, int, int> coords;
275 int halfmargin=margin/2;
276
277 for (int i=0;i<3;++i) {
278 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
279 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
280 rr2[i][1]][1])+halfmargin);
281 get_line_points(points,coords,color,width,height);
282 }
283 }
284
285 void draw_font_T(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
286 oat> &color, int width, int height, int margin)
287 {
288 // T
289 //points
290 float arr[3][2] = {{0.0,0.0},{1.0,0.0},{1.0,1.0}};
291 //lines
292 int arr2[2][2] = {{0,1},{1,2}};
293 std::tuple<int, int, int, int> coords;
294 int halfmargin=margin/2;
295
296 for (int i=0;i<2;++i) {
297 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
298 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
299 rr2[i][1]][1])+halfmargin);
300 get_line_points(points,coords,color,width,height);
14 Appendix A: Source Code Listings 310

301 }
302 }
303
304 void draw_font_N(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
305 oat> &color, int width, int height, int margin)
306 {
307 // N
308 //points
309 float arr[6][2] = {{0.0,0.0},{0.0,1.0},{1.0,0.0},{1.0,1.0},{0.0,0.0},{1.0,1.0}};
310 //lines
311 int arr2[3][2] = {{0,1},{2,3},{4,5}};
312 std::tuple<int, int, int, int> coords;
313 int halfmargin=margin/2;
314
315 for (int i=0;i<3;++i) {
316 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
317 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
318 rr2[i][1]][1])+halfmargin);
319 get_line_points(points,coords,color,width,height);
320 }
321 }
322
323 void draw_font_0(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
324 oat> &color, int width, int height, int margin)
325 {
326 // 0
327 //points
328 float arr[6][2] = {{0.0,0.0},{0.0,1.0},{1.0,1.0},{1.0,0.0},{0.0,1.0},{1.0,0.0}};
329 //lines
330 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,0},{4,5}};
331 std::tuple<int, int, int, int> coords;
332 int halfmargin=margin/2;
333
334 for (int i=0;i<5;++i) {
335 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
336 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
337 rr2[i][1]][1])+halfmargin);
338 get_line_points(points,coords,color,width,height);
339 }
340 }
341
342 void draw_font_1(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
343 oat> &color, int width, int height, int margin)
14 Appendix A: Source Code Listings 311

344 {
345 // 1
346 //points
347 float arr[3][2] = {{0.0,0.0},{0.5,0.0},{0.5,1.0}};
348 //lines
349 int arr2[2][2] = {{0,1},{1,2}};
350 std::tuple<int, int, int, int> coords;
351 int halfmargin=margin/2;
352
353 for (int i=0;i<2;++i) {
354 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
355 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
356 rr2[i][1]][1])+halfmargin);
357 get_line_points(points,coords,color,width,height);
358 }
359 }
360
361 void draw_font_2(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
362 oat> &color, int width, int height, int margin)
363 {
364 // 2
365 //points
366 float arr[6][2] = {{0.0,0.0},{1.0,0.0},{1.0,0.4},{0.0,0.6},{0.0,1.0},{1.0,1.0}};
367 //lines
368 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
369 std::tuple<int, int, int, int> coords;
370 int halfmargin=margin/2;
371
372 for (int i=0;i<5;++i) {
373 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
374 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
375 rr2[i][1]][1])+halfmargin);
376 get_line_points(points,coords,color,width,height);
377 }
378 }
379
380 void draw_font_3(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
381 oat> &color, int width, int height, int margin)
382 {
383 // 3
384 //points
385 float arr[6][2] = {{0.0,0.0},{1.0,0.0},{1.0,0.4},{0.5,0.4},{0.0,1.0},{1.0,1.0}};
386 //lines
14 Appendix A: Source Code Listings 312

387 int arr2[4][2] = {{0,1},{1,2},{2,3},{4,5}};


388 std::tuple<int, int, int, int> coords;
389 int halfmargin=margin/2;
390
391 for (int i=0;i<4;++i) {
392 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
393 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
394 rr2[i][1]][1])+halfmargin);
395 get_line_points(points,coords,color,width,height);
396 }
397 }
398
399 void draw_font_4(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
400 oat> &color, int width, int height, int margin)
401 {
402 // 4
403 //points
404 float arr[5][2] = {{0.0,0.0},{0.0,0.4},{1.0,0.6},{1.0,0.0},{1.0,1.0}};
405 //lines
406 int arr2[3][2] = {{0,1},{1,2},{3,4}};
407 std::tuple<int, int, int, int> coords;
408 int halfmargin=margin/2;
409
410 for (int i=0;i<3;++i) {
411 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
412 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
413 rr2[i][1]][1])+halfmargin);
414 get_line_points(points,coords,color,width,height);
415 }
416 }
417
418 void draw_font_5(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
419 oat> &color, int width, int height, int margin)
420 {
421 // 5
422 //points
423 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.5},{1.0,0.6},{1.0,1.0},{0.0,1.0}};
424 //lines
425 int arr2[5][2] = {{0,1},{1,2},{2,3},{3,4},{4,5}};
426 std::tuple<int, int, int, int> coords;
427 int halfmargin=margin/2;
428
429 for (int i=0;i<5;++i) {
14 Appendix A: Source Code Listings 313

430 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\


431 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
432 rr2[i][1]][1])+halfmargin);
433 get_line_points(points,coords,color,width,height);
434 }
435 }
436
437 void draw_font_6(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
438 oat> &color, int width, int height, int margin)
439 {
440 // 6
441 //points
442 float arr[6][2] = {{1.0,0.0},{0.0,0.0},{0.0,0.4},{1.0,0.6},{1.0,1.0},{0.0,1.0}};
443 //lines
444 int arr2[5][2] = {{0,1},{1,5},{5,4},{3,4},{3,2}};
445 std::tuple<int, int, int, int> coords;
446 int halfmargin=margin/2;
447
448 for (int i=0;i<5;++i) {
449 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
450 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
451 rr2[i][1]][1])+halfmargin);
452 get_line_points(points,coords,color,width,height);
453 }
454 }
455
456 void draw_font_7(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
457 oat> &color, int width, int height, int margin)
458 {
459 // 7
460 //points
461 float arr[3][2] = {{0.0,0.0},{1.0,0.0},{1.0,1.0}};
462 //lines
463 int arr2[2][2] = {{0,1},{1,2}};
464 std::tuple<int, int, int, int> coords;
465 int halfmargin=margin/2;
466
467 for (int i=0;i<2;++i) {
468 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
469 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
470 rr2[i][1]][1])+halfmargin);
471 get_line_points(points,coords,color,width,height);
472 }
14 Appendix A: Source Code Listings 314

473 }
474
475 void draw_font_8(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
476 oat> &color, int width, int height, int margin)
477 {
478 // 8
479 //points
480 float arr[6][2] = {{0.1,0.4},{0.9,0.6},{1.0,0.0},{0.0,0.0},{0.0,1.0},{1.0,1.0}};
481 //lines
482 int arr2[7][2] = {{0,1},{1,2},{2,3},{3,0},{0,4},{4,5},{5,1}};
483 std::tuple<int, int, int, int> coords;
484 int halfmargin=margin/2;
485
486 for (int i=0;i<7;++i) {
487 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
488 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
489 rr2[i][1]][1])+halfmargin);
490 get_line_points(points,coords,color,width,height);
491 }
492 }
493
494 void draw_font_9(std::vector<std::tuple<int,int>> &points, std::tuple<float,float,fl\
495 oat> &color, int width, int height, int margin)
496 {
497 // 9
498 //points
499 float arr[5][2] = {{1.0,1.0},{1.0,0.0},{0.0,0.0},{0.0,0.6},{1.0,0.4}};
500 //lines
501 int arr2[4][2] = {{0,1},{1,2},{2,3},{3,4}};
502 std::tuple<int, int, int, int> coords;
503 int halfmargin=margin/2;
504
505 for (int i=0;i<4;++i) {
506 coords=std::make_tuple(int(width*arr[arr2[i][0]][0])+halfmargin, int(height*arr[ar\
507 r2[i][0]][1])+halfmargin, int(width*arr[arr2[i][1]][0]+halfmargin), int(height*arr[a
508 rr2[i][1]][1])+halfmargin);
509 get_line_points(points,coords,color,width,height);
510 }
511 }
512
513 void draw_filled_circle(int x, int y, int radius, std::vector<std::tuple<float, floa\
514 t, float>> &image, std::tuple<float, float, float> &color, int width, int height, in
515 t margin)
14 Appendix A: Source Code Listings 315

516 {
517 int x0 = 0;
518 int y0 = radius;
519 int d = 3 - 2 * radius;
520 if (!radius) return;
521
522 auto drawline = [&](int sx, int ex, int ny)
523 {
524 for (int i = sx; i <= ex; i++)
525 image[get_index(i, ny, width+margin)]=color;
526 };
527
528 while (y0 >= x0)
529 {
530 drawline(x - x0, x + x0, y - y0);
531 drawline(x - y0, x + y0, y - x0);
532 drawline(x - x0, x + x0, y + y0);
533 drawline(x - y0, x + y0, y + x0);
534 if (d < 0) d += 4 * x0++ + 6;
535 else d += 4 * (x0++ - y0--) + 10;
536 }
537 }
538
539 void draw_filled_rect(int x, int y, int w, int h, std::vector<std::tuple<float, floa\
540 t, float>> &image, std::tuple<float,float,float> &color, int width, int height)
541 {
542 int x2 = x + w;
543 int y2 = y + h;
544
545 if (x < 0) {x = 0;}
546 if (x >= width) {x = width;}
547 if (y < 0) {y = 0;}
548 if (y >= height) {y = height;}
549
550 if (x2 < 0) {x2 = 0;}
551 if (x2 >= width) {x2 = width;}
552 if (y2 < 0) {y2 = 0;}
553 if (y2 >= height) {y2 = height;}
554
555 for (int i = y; i < y2; i++) {
556 for (int j = x; j < x2; j++) {
557 image[get_index(j,i,width)]=color;
558 }
14 Appendix A: Source Code Listings 316

559 }
560 }
561
562 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
563 height, std::string filename)
564 {
565 std::tuple<float, float, float> color;
566 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);
567 out << "P6" << std::endl << width << ' ' << height << std::endl << "255" << std::en\
568 dl;
569
570 for (int i=0;i<(width*height);++i)
571 {
572 color=image[i];
573 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*255.0f) << char(\
574 std::get<2>(color)*255.0f);
575 }
576 out.close();
577 }
578
579 void draw(std::vector<std::tuple<int,int>> points,std::vector<std::tuple<float, floa\
580 t, float>> &image, std::tuple<float,float,float> color, int width, int height, int m
581 argin, int linesize)
582 {
583 for (auto& p : points) {
584 if (linesize == 1) {
585 image[get_index(std::get<0>(p),std::get<1>(p),width+margin)]=color;
586 } else {
587 draw_filled_circle(std::get<0>(p),std::get<1>(p),linesize,image,color,width,
588 t,margin);
589 }
590 }
591 }
592
593 int main()
594 {
595 std::vector<std::tuple<float, float, float>> image;
596 std::vector<std::tuple<int,int>> points;
597 std::tuple<float,float,float> color1=std::make_tuple(1.0f,1.0f,1.0f);
598 std::tuple<float,float,float> color2=std::make_tuple(0.262745098f,0.262745098f,0.26\
599 2745098f);
600 std::tuple<float,float,float> color3=std::make_tuple(0.0f,0.0f,0.0f);
601 int width=1600,height=900;
14 Appendix A: Source Code Listings 317

602 int margin=0;


603 int linesize=1;
604 int fwidth=0;
605 int fheight=10;
606
607 get_width_from_height(fwidth,fheight);
608 get_margin_from_height(margin,fheight);
609
610 image.resize(calc_size(width, height, margin));
611 clear_image(image,width,height,margin);
612
613 std::vector<std::tuple<float, float, float>> f_m;
614 f_m.resize(calc_size(fwidth, fheight, margin));
615 clear_image(f_m,fwidth,fheight,margin);
616 draw_font_M(points,color3,fwidth,fheight,margin);
617 draw(points,f_m,color3,fwidth,fheight,margin,linesize);
618 points.clear();
619 std::vector<std::tuple<float, float, float>> f_a;
620 f_a.resize(calc_size(fwidth, fheight, margin));
621 clear_image(f_a,fwidth,fheight,margin);
622 draw_font_A(points,color3,fwidth,fheight,margin);
623 draw(points,f_a,color3,fwidth,fheight,margin,linesize);
624 points.clear();
625 std::vector<std::tuple<float, float, float>> f_r;
626 f_r.resize(calc_size(fwidth, fheight, margin));
627 clear_image(f_r,fwidth,fheight,margin);
628 draw_font_R(points,color3,fwidth,fheight,margin);
629 draw(points,f_r,color3,fwidth,fheight,margin,linesize);
630 points.clear();
631 std::vector<std::tuple<float, float, float>> f_s;
632 f_s.resize(calc_size(fwidth, fheight, margin));
633 clear_image(f_s,fwidth,fheight,margin);
634 draw_font_S(points,color3,fwidth,fheight,margin);
635 draw(points,f_s,color3,fwidth,fheight,margin,linesize);
636 points.clear();
637 std::vector<std::tuple<float, float, float>> f_e;
638 f_e.resize(calc_size(fwidth, fheight, margin));
639 clear_image(f_e,fwidth,fheight,margin);
640 draw_font_E(points,color3,fwidth,fheight,margin);
641 draw(points,f_e,color3,fwidth,fheight,margin,linesize);
642 points.clear();
643 std::vector<std::tuple<float, float, float>> f_u;
644 f_u.resize(calc_size(fwidth, fheight, margin));
14 Appendix A: Source Code Listings 318

645 clear_image(f_u,fwidth,fheight,margin);
646 draw_font_U(points,color3,fwidth,fheight,margin);
647 draw(points,f_u,color3,fwidth,fheight,margin,linesize);
648 points.clear();
649 std::vector<std::tuple<float, float, float>> f_c;
650 f_c.resize(calc_size(fwidth, fheight, margin));
651 clear_image(f_c,fwidth,fheight,margin);
652 draw_font_C(points,color3,fwidth,fheight,margin);
653 draw(points,f_c,color3,fwidth,fheight,margin,linesize);
654 points.clear();
655 std::vector<std::tuple<float, float, float>> f_y;
656 f_y.resize(calc_size(fwidth, fheight, margin));
657 clear_image(f_y,fwidth,fheight,margin);
658 draw_font_Y(points,color3,fwidth,fheight,margin);
659 draw(points,f_y,color3,fwidth,fheight,margin,linesize);
660 points.clear();
661 std::vector<std::tuple<float, float, float>> f_t;
662 f_t.resize(calc_size(fwidth, fheight, margin));
663 clear_image(f_t,fwidth,fheight,margin);
664 draw_font_T(points,color3,fwidth,fheight,margin);
665 draw(points,f_t,color3,fwidth,fheight,margin,linesize);
666 points.clear();
667 std::vector<std::tuple<float, float, float>> f_n;
668 f_n.resize(calc_size(fwidth, fheight, margin));
669 clear_image(f_n,fwidth,fheight,margin);
670 draw_font_N(points,color3,fwidth,fheight,margin);
671 draw(points,f_n,color3,fwidth,fheight,margin,linesize);
672 points.clear();
673 std::vector<std::tuple<float, float, float>> f_1;
674 f_1.resize(calc_size(fwidth, fheight, margin));
675 clear_image(f_1,fwidth,fheight,margin);
676 draw_font_1(points,color3,fwidth,fheight,margin);
677 draw(points,f_1,color3,fwidth,fheight,margin,linesize);
678 points.clear();
679 std::vector<std::tuple<float, float, float>> f_2;
680 f_2.resize(calc_size(fwidth, fheight, margin));
681 clear_image(f_2,fwidth,fheight,margin);
682 draw_font_2(points,color3,fwidth,fheight,margin);
683 draw(points,f_2,color3,fwidth,fheight,margin,linesize);
684 points.clear();
685 std::vector<std::tuple<float, float, float>> f_3;
686 f_3.resize(calc_size(fwidth, fheight, margin));
687 clear_image(f_3,fwidth,fheight,margin);
14 Appendix A: Source Code Listings 319

688 draw_font_3(points,color3,fwidth,fheight,margin);
689 draw(points,f_3,color3,fwidth,fheight,margin,linesize);
690 points.clear();
691
692 std::vector<std::tuple<float, float, float>> f_w0;
693 f_w0.resize(calc_size(fwidth, fheight, margin));
694 clear_image(f_w0,fwidth,fheight,margin);
695 draw_font_0(points,color2,fwidth,fheight,margin);
696 draw(points,f_w0,color2,fwidth,fheight,margin,linesize);
697 points.clear();
698 std::vector<std::tuple<float, float, float>> f_w1;
699 f_w1.resize(calc_size(fwidth, fheight, margin));
700 clear_image(f_w1,fwidth,fheight,margin);
701 draw_font_1(points,color2,fwidth,fheight,margin);
702 draw(points,f_w1,color2,fwidth,fheight,margin,linesize);
703 points.clear();
704 std::vector<std::tuple<float, float, float>> f_w2;
705 f_w2.resize(calc_size(fwidth, fheight, margin));
706 clear_image(f_w2,fwidth,fheight,margin);
707 draw_font_2(points,color2,fwidth,fheight,margin);
708 draw(points,f_w2,color2,fwidth,fheight,margin,linesize);
709 points.clear();
710 std::vector<std::tuple<float, float, float>> f_w3;
711 f_w3.resize(calc_size(fwidth, fheight, margin));
712 clear_image(f_w3,fwidth,fheight,margin);
713 draw_font_3(points,color2,fwidth,fheight,margin);
714 draw(points,f_w3,color2,fwidth,fheight,margin,linesize);
715 points.clear();
716 std::vector<std::tuple<float, float, float>> f_w4;
717 f_w4.resize(calc_size(fwidth, fheight, margin));
718 clear_image(f_w4,fwidth,fheight,margin);
719 draw_font_4(points,color2,fwidth,fheight,margin);
720 draw(points,f_w4,color2,fwidth,fheight,margin,linesize);
721 points.clear();
722 std::vector<std::tuple<float, float, float>> f_w5;
723 f_w5.resize(calc_size(fwidth, fheight, margin));
724 clear_image(f_w5,fwidth,fheight,margin);
725 draw_font_5(points,color2,fwidth,fheight,margin);
726 draw(points,f_w5,color2,fwidth,fheight,margin,linesize);
727 points.clear();
728 std::vector<std::tuple<float, float, float>> f_w6;
729 f_w6.resize(calc_size(fwidth, fheight, margin));
730 clear_image(f_w6,fwidth,fheight,margin);
14 Appendix A: Source Code Listings 320

731 draw_font_6(points,color2,fwidth,fheight,margin);
732 draw(points,f_w6,color2,fwidth,fheight,margin,linesize);
733 points.clear();
734 std::vector<std::tuple<float, float, float>> f_w7;
735 f_w7.resize(calc_size(fwidth, fheight, margin));
736 clear_image(f_w7,fwidth,fheight,margin);
737 draw_font_7(points,color2,fwidth,fheight,margin);
738 draw(points,f_w7,color2,fwidth,fheight,margin,linesize);
739 points.clear();
740 std::vector<std::tuple<float, float, float>> f_w8;
741 f_w8.resize(calc_size(fwidth, fheight, margin));
742 clear_image(f_w8,fwidth,fheight,margin);
743 draw_font_8(points,color2,fwidth,fheight,margin);
744 draw(points,f_w8,color2,fwidth,fheight,margin,linesize);
745 points.clear();
746 std::vector<std::tuple<float, float, float>> f_w9;
747 f_w9.resize(calc_size(fwidth, fheight, margin));
748 clear_image(f_w9,fwidth,fheight,margin);
749 draw_font_9(points,color2,fwidth,fheight,margin);
750 draw(points,f_w9,color2,fwidth,fheight,margin,linesize);
751 points.clear();
752
753 draw_filled_rect(402,322,796,5,image,color1,width,height);
754 draw_filled_rect(402,418,796,5,image,color1,width,height);
755 draw_filled_rect(402,514,796,5,image,color1,width,height);
756 draw_filled_rect(402,611,796,5,image,color1,width,height);
757 draw_filled_rect(402,707,796,5,image,color1,width,height);
758 draw_filled_rect(402,322,5,390,image,color1,width,height);
759 draw_filled_rect(557,322,5,390,image,color1,width,height);
760 draw_filled_rect(769,322,5,390,image,color1,width,height);
761 draw_filled_rect(970,322,5,390,image,color1,width,height);
762 draw_filled_rect(1193,322,5,390,image,color1,width,height);
763
764 // Labels
765 stamp(image,f_m,420,460,(fwidth+margin),(fheight+margin),width);
766 stamp(image,f_e,420+(1*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width);
767 stamp(image,f_r,420+(2*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width);
768 stamp(image,f_c,420+(3*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width);
769 stamp(image,f_u,420+(4*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width);
770 stamp(image,f_r,420+(5*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width);
771 stamp(image,f_y,420+(6*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width);
772
773 stamp(image,f_m,446,560,(fwidth+margin),(fheight+margin),width);
14 Appendix A: Source Code Listings 321

774 stamp(image,f_a,446+(1*(fwidth+margin)),560,(fwidth+margin),(fheight+margin),width);
775 stamp(image,f_r,446+(2*(fwidth+margin)),560,(fwidth+margin),(fheight+margin),width);
776 stamp(image,f_s,446+(3*(fwidth+margin)),560,(fwidth+margin),(fheight+margin),width);
777
778 stamp(image,f_s,426,660,(fwidth+margin),(fheight+margin),width);
779 stamp(image,f_a,426+(1*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),width);
780 stamp(image,f_t,426+(2*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),width);
781 stamp(image,f_u,426+(3*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),width);
782 stamp(image,f_r,426+(4*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),width);
783 stamp(image,f_n,426+(5*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),width);
784
785 stamp(image,f_a,646,370,(fwidth+margin),(fheight+margin),width);
786 stamp(image,f_1,646+(1*(fwidth+margin)),370,(fwidth+margin),(fheight+margin),width);
787
788 stamp(image,f_a,846,370,(fwidth+margin),(fheight+margin),width);
789 stamp(image,f_2,846+(1*(fwidth+margin)),370,(fwidth+margin),(fheight+margin),width);
790
791 stamp(image,f_a,1056,370,(fwidth+margin),(fheight+margin),width);
792 stamp(image,f_3,1056+(1*(fwidth+margin)),370,(fwidth+margin),(fheight+margin),width\
793 );
794
795 stamp(image,f_w1,626,460,(fwidth+margin),(fheight+margin),width);
796 stamp(image,f_w0,626+(1*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width\
797 );
798 stamp(image,f_w8,626+(2*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width\
799 );
800 stamp(image,f_w4,626+(3*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width\
801 );
802
803 stamp(image,f_w6,836,460,(fwidth+margin),(fheight+margin),width);
804 stamp(image,f_w5,836+(1*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width\
805 );
806 stamp(image,f_w0,836+(2*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width\
807 );
808 stamp(image,f_w2,836+(3*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),width\
809 );
810
811 stamp(image,f_w6,1036,460,(fwidth+margin),(fheight+margin),width);
812 stamp(image,f_w8,1036+(1*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),widt\
813 h);
814 stamp(image,f_w0,1036+(2*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),widt\
815 h);
816 stamp(image,f_w0,1036+(3*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),widt\
14 Appendix A: Source Code Listings 322

817 h);
818 stamp(image,f_w0,1036+(4*(fwidth+margin)),460,(fwidth+margin),(fheight+margin),widt\
819 h);
820
821 stamp(image,f_w6,646,560,(fwidth+margin),(fheight+margin),width);
822 stamp(image,f_w4,646+(1*(fwidth+margin)),560,(fwidth+margin),(fheight+margin),width\
823 );
824
825 stamp(image,f_w5,846,560,(fwidth+margin),(fheight+margin),width);
826 stamp(image,f_w0,846+(1*(fwidth+margin)),560,(fwidth+margin),(fheight+margin),width\
827 );
828 stamp(image,f_w0,846+(2*(fwidth+margin)),560,(fwidth+margin),(fheight+margin),width\
829 );
830
831 stamp(image,f_w1,1046,560,(fwidth+margin),(fheight+margin),width);
832 stamp(image,f_w5,1046+(1*(fwidth+margin)),560,(fwidth+margin),(fheight+margin),widt\
833 h);
834 stamp(image,f_w4,1046+(2*(fwidth+margin)),560,(fwidth+margin),(fheight+margin),widt\
835 h);
836 stamp(image,f_w1,1046+(3*(fwidth+margin)),560,(fwidth+margin),(fheight+margin),widt\
837 h);
838
839 stamp(image,f_w1,626,660,(fwidth+margin),(fheight+margin),width);
840 stamp(image,f_w0,626+(1*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),width\
841 );
842 stamp(image,f_w2,626+(2*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),width\
843 );
844 stamp(image,f_w4,626+(3*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),width\
845 );
846
847 stamp(image,f_w4,836,660,(fwidth+margin),(fheight+margin),width);
848 stamp(image,f_w0,836+(1*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),width\
849 );
850 stamp(image,f_w9,836+(2*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),width\
851 );
852 stamp(image,f_w6,836+(3*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),width\
853 );
854
855 stamp(image,f_w8,1046,660,(fwidth+margin),(fheight+margin),width);
856 stamp(image,f_w1,1046+(1*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),widt\
857 h);
858 stamp(image,f_w9,1046+(2*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),widt\
859 h);
14 Appendix A: Source Code Listings 323

860 stamp(image,f_w2,1046+(3*(fwidth+margin)),660,(fwidth+margin),(fheight+margin),widt\
861 h);
862
863 std::cout << "saving: 16_draw_table.ppm." << std::endl;
864 save_image(image,width,height,"16_draw_table.ppm");
865
866 return 0;
867 }

16_draw_market_size.cpp - 104365 bytes.

1 // Compile: clang++ -std=c++17 16_draw_market_size.cpp -o 16_draw_market_size


2
3 #include <iostream>
4 #include <fstream>
5 #include <tuple>
6 #include <vector>
7 #include <random>
8 #include <cmath>
9 #include <algorithm>
10
11 int get_index(int x, int y, int width)
12 {
13 return x+width*y;
14 }
15
16 int calc_size(int width, int height)
17 {
18 return width*height;
19 }
20
21 void flood_fill(std::vector<std::tuple<float, float, float>> &image, int x, int y, s\
22 td::tuple<float,float,float> &oldcolor, std::tuple<float,float,float> &newcolor, int
23 width)
24 {
25 if(image[get_index(x,y,width)] == oldcolor)
26 {
27 image[get_index(x,y,width)]=newcolor;
28 flood_fill(image,x+1,y,oldcolor,newcolor,width);
29 flood_fill(image,x,y+1,oldcolor,newcolor,width);
30 flood_fill(image,x-1,y,oldcolor,newcolor,width);
31 flood_fill(image,x,y-1,oldcolor,newcolor,width);
32 }
14 Appendix A: Source Code Listings 324

33 }
34
35 void draw_line(std::vector<std::tuple<float, float, float>> &image, std::tuple<int, \
36 int, int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
37 {
38 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
39 int y2=std::get<3>(coords);
40 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
41 dx = x2 - x1; dy = y2 - y1;
42
43 if (dx == 0)
44 {
45 if (y2 < y1) std::swap(y1, y2);
46 for (y = y1; y <= y2; y++)
47 image[get_index(x1,y,width)]=color;
48 return;
49 }
50 if (dy == 0)
51 {
52 if (x2 < x1) std::swap(x1, x2);
53 for (x = x1; x <= x2; x++)
54 image[get_index(x,y1,width)]=color;
55 return;
56 }
57 dx1 = abs(dx); dy1 = abs(dy);
58 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
59 if (dy1 <= dx1)
60 {
61 if (dx >= 0)
62 {
63 x = x1; y = y1; xe = x2;
64 }
65 else
66 {
67 x = x2; y = y2; xe = x1;
68 }
69 image[get_index(x,y,width)]=color;
70 for (i = 0; x<xe; i++)
71 {
72 x = x + 1;
73 if (px<0)
74 px = px + 2 * dy1;
75 else
14 Appendix A: Source Code Listings 325

76 {
77 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
78 px = px + 2 * (dy1 - dx1);
79 }
80 image[get_index(x,y,width)]=color;
81 }
82 }
83 else
84 {
85 if (dy >= 0)
86 {
87 x = x1; y = y1; ye = y2;
88 }
89 else
90 {
91 x = x2; y = y2; ye = y1;
92 }
93 image[get_index(x,y,width)]=color;
94 for (i = 0; y<ye; i++)
95 {
96 y = y + 1;
97 if (py <= 0)
98 py = py + 2 * dx1;
99 else
100 {
101 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
102 py = py + 2 * (dx1 - dy1);
103 }
104 image[get_index(x,y,width)]=color;
105 }
106 }
107 }
108
109 void draw_filled_circle(int x, int y, int radius, std::vector<std::tuple<float, floa\
110 t, float>> &image, std::tuple<float, float, float> &color, int width, int height)
111 {
112 int x0 = 0;
113 int y0 = radius;
114 int d = 3 - 2 * radius;
115 if (!radius) return;
116
117 auto drawline = [&](int sx, int ex, int ny)
118 {
14 Appendix A: Source Code Listings 326

119 // uncomment if on windows


120 //if (((sx>=0)&&(sx<width)) && ((ex>=0)&&(ex<width)) && ((ny>=0)&&(ny<height))) {
121 for (int i = sx; i <= ex; i++) {
122 image[get_index(i, ny, width)]=color;
123 }
124 //}
125 };
126
127 while (y0 >= x0)
128 {
129 drawline(x - x0, x + x0, y - y0);
130 drawline(x - y0, x + y0, y - x0);
131 drawline(x - x0, x + x0, y + y0);
132 drawline(x - y0, x + y0, y + x0);
133 if (d < 0) d += 4 * x0++ + 6;
134 else d += 4 * (x0++ - y0--) + 10;
135 }
136 }
137
138 void get_line_points(std::vector<std::tuple<int,int>> &points, std::tuple<int, int, \
139 int, int> &coords)
140 {
141 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
142 int y2=std::get<3>(coords);
143 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
144 dx = x2 - x1; dy = y2 - y1;
145 if (dx == 0)
146 {
147 if (y2 < y1) std::swap(y1, y2);
148 for (y = y1; y <= y2; y++)
149 points.push_back(std::make_tuple(x1,y));
150 return;
151 }
152 if (dy == 0)
153 {
154 if (x2 < x1) std::swap(x1, x2);
155 for (x = x1; x <= x2; x++)
156 points.push_back(std::make_tuple(x,y1));
157 return;
158 }
159 dx1 = abs(dx); dy1 = abs(dy);
160 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
161 if (dy1 <= dx1)
14 Appendix A: Source Code Listings 327

162 {
163 if (dx >= 0)
164 {
165 x = x1; y = y1; xe = x2;
166 }
167 else
168 {
169 x = x2; y = y2; xe = x1;
170 }
171 points.push_back(std::make_tuple(x,y));
172 for (i = 0; x<xe; i++)
173 {
174 x = x + 1;
175 if (px<0)
176 px = px + 2 * dy1;
177 else
178 {
179 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
180 px = px + 2 * (dy1 - dx1);
181 }
182 points.push_back(std::make_tuple(x,y));
183 }
184 }
185 else
186 {
187 if (dy >= 0)
188 {
189 x = x1; y = y1; ye = y2;
190 }
191 else
192 {
193 x = x2; y = y2; ye = y1;
194 }
195 points.push_back(std::make_tuple(x,y));
196 for (i = 0; y<ye; i++)
197 {
198 y = y + 1;
199 if (py <= 0)
200 py = py + 2 * dx1;
201 else
202 {
203 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
204 py = py + 2 * (dx1 - dy1);
14 Appendix A: Source Code Listings 328

205 }
206 points.push_back(std::make_tuple(x,y));
207 }
208 }
209 }
210
211 void draw(std::vector<std::tuple<int,int>> points,std::vector<std::tuple<float, floa\
212 t, float>> &image, std::tuple<float,float,float> color, int width, int height, int r
213 adius)
214 {
215 for (auto& p : points) {
216 if (radius == 1) {
217 image[get_index(std::get<0>(p),std::get<1>(p),width)]=std::make_tuple(0.0f,
218 0.0f);
219 } else {
220 draw_filled_circle(std::get<0>(p),std::get<1>(p),radius,image,color,width,he
221 }
222 }
223 }
224
225 void draw_labels(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
226 at,float,float> &color, int width, int height)
227 {
228 // These pixels are drawn in a graphics application and converted to 1's and 0's to\
229 render them here.
230
231 // 16_lable_10.png
232 // 60 29
233 // 870 657
234 char lable_10[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,\
235 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,
236 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
237 0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,
238 0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
239 1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
240 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,
241 0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,
242 0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,
243 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,
244 0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,
245 1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
246 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,
247 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
14 Appendix A: Source Code Listings 329

248 1,1,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,
249 1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,
250 0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,1,
251 1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
252 0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
253 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
254 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,
255 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
256 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,
257 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
258 0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,
259 1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,
260 0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
261 0,1,1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
262 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,
263 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,
264 1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,
265 1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
266 0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,
267 0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
268 0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,
269 1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,
270 0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,
271 0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,
272 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,
273 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
274 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,
275 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0};
276 int xx=0; int yy=0;
277 for (int y=657;y<(657+29);++y)
278 {
279 for (int x=870;x<(870+60);x++) {
280 if (lable_10[get_index(xx,yy,60)] == 1) {
281 image[get_index(x,y,width)]=color;
282 }
283 xx++;
284 }
285 yy++;
286 xx=0;
287 }
288
289 // 16_lable_15.png
290 // 80 39
14 Appendix A: Source Code Listings 330

291 // 691 576


292 char lable_15[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
293 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
294 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
295 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
296 0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,
297 1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
298 0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
299 0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
300 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,
301 0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,
302 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
303 1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,
304 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,
305 0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,
306 0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,
307 1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
308 0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,
309 0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
310 0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
311 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
312 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,
313 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,
314 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,
315 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,
316 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,
317 0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
318 0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
319 0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
320 0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
321 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
322 0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,
323 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
324 1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,
325 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
326 0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,
327 0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
328 0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
329 0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
330 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
331 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,
332 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
333 0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,
14 Appendix A: Source Code Listings 331

334 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
335 0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,
336 0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
337 0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
338 0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
339 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,
340 0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,
341 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,
342 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,
343 0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,
344 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
345 0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,
346 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
347 1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
348 0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,
349 0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
350 1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,
351 1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
352 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,
353 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
354 0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,
355 1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,
356 0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
357 0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,
358 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
359 0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,
360 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,
361 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
362 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,
363 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
364 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
365 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
366 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0};
367 xx=0; yy=0;
368 for (int y=576;y<(576+39);++y)
369 {
370 for (int x=691;x<(691+80);x++) {
371 if (lable_15[get_index(xx,yy,80)] == 1) {
372 image[get_index(x,y,width)]=color;
373 }
374 xx++;
375 }
376 yy++;
14 Appendix A: Source Code Listings 332

377 xx=0;
378 }
379
380 // 16_lable_30.png
381 // 101 49
382 // 473 459
383 char lable_30[]={0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
384 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
385 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,
386 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,
387 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
388 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
389 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,
390 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,
391 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
392 0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
393 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,
394 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
395 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
396 0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,
397 0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
398 0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,
399 0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,
400 0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
401 1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,
402 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
403 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
404 0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,
405 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,
406 0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
407 1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,
408 0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,
409 0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
410 0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
411 1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
412 0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
413 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,
414 1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
415 1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,
416 0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
417 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,
418 0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,
419 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,
14 Appendix A: Source Code Listings 333

420 0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,
421 0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
422 0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
423 1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,
424 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
425 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,
426 1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
427 1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,
428 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
429 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
430 0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,
431 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
432 0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,
433 1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
434 0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
435 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,
436 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
437 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
438 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,
439 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,
440 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
441 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,
442 0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,
443 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,
444 0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
445 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
446 0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
447 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
448 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
449 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
450 0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
451 1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,
452 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
453 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,
454 0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,
455 0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,
456 0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
457 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
458 0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
459 0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,
460 0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,
461 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
462 0,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
14 Appendix A: Source Code Listings 334

463 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,
464 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,
465 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,
466 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
467 1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,
468 0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
469 0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,
470 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
471 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
472 0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
473 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
474 1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
475 0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,
476 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,
477 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,
478 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,
479 0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,
480 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
481 0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,0,
482 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
483 0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,
484 0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
485 0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
486 1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,
487 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,
488 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,
489 1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
490 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
491 0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,
492 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
493 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,
494 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
495 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
496 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
497 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
498 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,
499 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,
500 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,
501 0,0};
502 xx=0; yy=0;
503 for (int y=459;y<(459+49);++y)
504 {
505 for (int x=473;x<(473+101);x++) {
14 Appendix A: Source Code Listings 335

506 if (lable_30[get_index(xx,yy,101)] == 1) {
507 image[get_index(x,y,width)]=color;
508 }
509 xx++;
510 }
511 yy++;
512 xx=0;
513 }
514
515 // 16_lable_45.png
516 // 124 58
517 // 726 287
518 char lable_45[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
519 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
520 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
521 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,
522 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
523 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
524 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
525 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,
526 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
527 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
528 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
529 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
530 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
531 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
532 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
533 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
534 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
535 1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
536 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
537 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
538 0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
539 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
540 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,
541 0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
542 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
543 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,
544 0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
545 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
546 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,
547 0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
548 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,
14 Appendix A: Source Code Listings 336

549 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
550 0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
551 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,
552 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,
553 1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
554 1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,
555 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
556 1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
557 1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
558 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
559 0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
560 1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
561 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,
562 0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,
563 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
564 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,
565 0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,
566 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
567 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,
568 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,
569 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
570 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,
571 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,
572 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
573 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,
574 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,
575 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
576 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,
577 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,
578 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
579 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,
580 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,
581 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
582 0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,
583 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
584 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
585 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
586 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
587 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
588 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
589 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
590 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
591 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
14 Appendix A: Source Code Listings 337

592 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
593 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
594 0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
595 0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
596 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
597 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
598 0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
599 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
600 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
601 0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
602 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
603 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
604 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
605 1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
606 0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
607 1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
608 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
609 0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
610 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
611 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
612 0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,
613 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
614 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
615 0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,
616 0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
617 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
618 1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,
619 0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
620 0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
621 1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
622 0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
623 0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,
624 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
625 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
626 0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,
627 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
628 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
629 0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,
630 1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
631 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
632 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,
633 1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
634 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
14 Appendix A: Source Code Listings 338

635 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,
636 0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
637 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
638 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,
639 0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
640 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
641 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,
642 0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
643 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,
644 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,
645 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
646 0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,
647 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
648 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
649 0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,
650 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,
651 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
652 0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
653 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
654 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
655 0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
656 0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,
657 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
658 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
659 0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,
660 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
661 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
662 0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,
663 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
664 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
665 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,
666 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
667 1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
668 1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
669 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
670 1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
671 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
672 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,
673 1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
674 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
675 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
676 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
677 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
14 Appendix A: Source Code Listings 339

678 0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,
679 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
680 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
681 0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
682 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
683 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
684 0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
685 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
686 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
687 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
688 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
689 0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0};
690 xx=0; yy=0;
691 for (int y=287;y<(287+58);++y)
692 {
693 for (int x=726;x<(726+124);x++) {
694 if (lable_45[get_index(xx,yy,124)] == 1) {
695 image[get_index(x,y,width)]=color;
696 }
697 xx++;
698 }
699 yy++;
700 xx=0;
701 }
702
703 // 16_lable_jupiter.png
704 // 73 17
705 // 691 700
706 char lable_jupiter[]={0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1\
707 ,1,1,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,0
708 ,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0
709 ,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0
710 ,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,0,0
711 ,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1
712 ,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1
713 ,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1
714 ,1,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0
715 ,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0
716 ,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,1
717 ,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1
718 ,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0
719 ,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1
720 ,1,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0
14 Appendix A: Source Code Listings 340

721 ,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0
722 ,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1
723 ,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1
724 ,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0
725 ,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1
726 ,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0
727 ,0,1,1,1,0,1,1,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0
728 ,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,1,1,1,0,0,0
729 ,1,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1
730 ,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0
731 ,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1
732 ,1,1,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1
733 ,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,0,1
734 ,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1
735 ,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,0,1,1,1,0};
736 xx=0; yy=0;
737 for (int y=700;y<(700+17);++y)
738 {
739 for (int x=691;x<(691+73);x++) {
740 if (lable_jupiter[get_index(xx,yy,73)] == 1) {
741 image[get_index(x,y,width)]=color;
742 }
743 xx++;
744 }
745 yy++;
746 xx=0;
747 }
748
749 // 16_lable_market_size.png
750 // 357 53
751 // 1112 68
752 char lable_market_size[]={0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0\
753 ,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
754 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
755 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
756 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
757 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
758 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
759 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
760 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
761 ,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
762 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
763 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
14 Appendix A: Source Code Listings 341

764 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1
765 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
766 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
767 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
768 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
769 ,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1
770 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1
771 ,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
772 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1
773 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
774 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
775 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
776 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
777 ,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1
778 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
779 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
780 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1
781 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1
782 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
783 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1
784 ,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
785 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
786 ,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
787 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1
788 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
789 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1
790 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
791 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
792 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
793 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
794 ,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1
795 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
796 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
797 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1
798 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1
799 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
800 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
801 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
802 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
803 ,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
804 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1
805 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
806 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1
14 Appendix A: Source Code Listings 342

807 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
808 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
809 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
810 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
811 ,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
812 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
813 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
814 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
815 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
816 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
817 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1
818 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
819 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
820 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1
821 ,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
822 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1
823 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1
824 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
825 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
826 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
827 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
828 ,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
829 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
830 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
831 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
832 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
833 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
834 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0
835 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
836 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
837 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
838 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
839 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
840 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1
841 ,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
842 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
843 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
844 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
845 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
846 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
847 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
848 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
849 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
14 Appendix A: Source Code Listings 343

850 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
851 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
852 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
853 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
854 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
855 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
856 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
857 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1
858 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
859 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
860 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
861 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
862 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
863 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
864 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
865 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
866 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
867 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
868 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
869 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
870 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
871 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
872 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
873 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
874 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1
875 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
876 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
877 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
878 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
879 ,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
880 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
881 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
882 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
883 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
884 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
885 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
886 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
887 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
888 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
889 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
890 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
891 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1
892 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
14 Appendix A: Source Code Listings 344

893 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
894 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
895 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
896 ,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
897 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
898 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
899 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
900 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
901 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
902 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
903 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
904 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
905 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
906 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
907 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
908 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1
909 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
910 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
911 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
912 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1
913 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
914 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
915 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
916 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
917 ,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
918 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
919 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
920 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
921 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
922 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
923 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
924 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
925 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1
926 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
927 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
928 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
929 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0
930 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
931 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
932 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
933 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
934 ,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
935 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
14 Appendix A: Source Code Listings 345

936 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1
937 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
938 ,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
939 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
940 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
941 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
942 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1
943 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
944 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
945 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0
946 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
947 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1
948 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
949 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
950 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1
951 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
952 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
953 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1
954 ,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
955 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
956 ,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
957 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
958 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
959 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
960 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
961 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
962 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
963 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
964 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1
965 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
966 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
967 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1
968 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
969 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
970 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
971 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
972 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
973 ,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
974 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
975 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
976 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
977 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
978 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
14 Appendix A: Source Code Listings 346

979 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
980 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0
981 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1
982 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
983 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
984 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1
985 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
986 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
987 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1
988 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
989 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
990 ,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
991 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
992 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
993 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
994 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
995 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
996 ,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
997 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
998 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1
999 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1000 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1001 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1
1002 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1003 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1004 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1
1005 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1006 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1007 ,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1008 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1009 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1010 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1011 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
1012 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1013 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1014 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
1015 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1
1016 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1017 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1018 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1019 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1020 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1021 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
14 Appendix A: Source Code Listings 347

1022 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1023 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1024 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1025 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1026 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1027 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1
1028 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1029 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1030 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1031 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1032 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1033 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1034 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1035 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1036 ,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1037 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1038 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1039 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1040 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1041 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1042 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1043 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1044 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1
1045 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1046 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1047 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1048 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1049 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1050 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1051 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1052 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1053 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1054 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1055 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1056 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1057 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1058 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1059 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1060 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1061 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1
1062 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1063 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1064 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
14 Appendix A: Source Code Listings 348

1065 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1066 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1067 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1068 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1069 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1070 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1071 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1072 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1073 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1074 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1075 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1076 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1077 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1078 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1
1079 ,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1080 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1081 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1082 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1083 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1084 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1085 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1086 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1087 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1088 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1089 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1090 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1091 ,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1092 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1093 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1094 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1095 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1
1096 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1097 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1098 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1099 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
1100 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1101 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1102 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1103 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1104 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1105 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1106 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1107 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
14 Appendix A: Source Code Listings 349

1108 ,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1109 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1110 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1111 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1112 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1
1113 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1114 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1115 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1116 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
1117 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1118 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1119 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1120 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1121 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1122 ,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1123 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1124 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1125 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1126 ,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1127 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1128 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1129 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1
1130 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1131 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1132 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1133 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
1134 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1135 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1136 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1137 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1138 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1
1139 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1140 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1141 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
1142 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1143 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1144 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1145 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1146 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1
1147 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1148 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1149 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1150 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
14 Appendix A: Source Code Listings 350

1151 ,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1152 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1153 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1154 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1155 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1
1156 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1157 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
1158 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
1159 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1160 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1161 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1162 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1163 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1
1164 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1165 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1166 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1167 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1168 ,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1169 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1170 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1171 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1172 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1
1173 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1174 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1
1175 ,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
1176 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1177 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1178 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1179 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1180 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1
1181 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1182 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1183 ,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1184 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1185 ,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1186 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1187 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1188 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1189 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1
1190 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1191 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1
1192 ,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
1193 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
14 Appendix A: Source Code Listings 351

1194 ,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1195 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1196 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1197 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1198 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1199 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1200 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0
1201 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1202 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1203 xx=0; yy=0;
1204 for (int y=68;y<(68+53);++y)
1205 {
1206 for (int x=1112;x<(1112+357);x++) {
1207 if (lable_market_size[get_index(xx,yy,357)] == 1) {
1208 image[get_index(x,y,width)]=color;
1209 }
1210 xx++;
1211 }
1212 yy++;
1213 xx=0;
1214 }
1215
1216 // 16_lable_mars.png
1217 // 53 18
1218 // 1163 700
1219 char lable_mars[]={0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,\
1220 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,
1221 1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1222 1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,
1223 1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,
1224 0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,
1225 0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,
1226 1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,
1227 1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,
1228 0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,
1229 1,1,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,
1230 1,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,
1231 0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
1232 1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,
1233 0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,
1234 0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,
1235 1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,
1236 1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,
14 Appendix A: Source Code Listings 352

1237 0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,
1238 1,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,
1239 0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,
1240 0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,
1241 1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0};
1242 xx=0; yy=0;
1243 for (int y=700;y<(700+18);++y)
1244 {
1245 for (int x=1163;x<(1163+53);x++) {
1246 if (lable_mars[get_index(xx,yy,53)] == 1) {
1247 image[get_index(x,y,width)]=color;
1248 }
1249 xx++;
1250 }
1251 yy++;
1252 xx=0;
1253 }
1254
1255 // 16_lable_mercury.png
1256 // 88 17
1257 // 462 700
1258 char lable_mercury[]={0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1\
1259 ,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1
1260 ,1,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0
1261 ,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1
1262 ,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,1
1263 ,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0
1264 ,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0
1265 ,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1
1266 ,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1
1267 ,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1
1268 ,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0
1269 ,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0
1270 ,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,1,0,0,1,1,1,1,0,0,1
1271 ,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0
1272 ,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,1,0,0,1,1,1
1273 ,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,1,1,1,1
1274 ,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0
1275 ,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0
1276 ,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1
1277 ,1,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1
1278 ,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0
1279 ,0,1,1,1,1,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0
14 Appendix A: Source Code Listings 353

1280 ,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1
1281 ,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0
1282 ,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0
1283 ,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0
1284 ,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1
1285 ,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1
1286 ,1,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1
1287 ,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0
1288 ,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0
1289 ,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,0
1290 ,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1
1291 ,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1
1292 ,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0
1293 ,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0};
1294 xx=0; yy=0;
1295 for (int y=700;y<(700+17);++y)
1296 {
1297 for (int x=462;x<(462+88);x++) {
1298 if (lable_mercury[get_index(xx,yy,88)] == 1) {
1299 image[get_index(x,y,width)]=color;
1300 }
1301 xx++;
1302 }
1303 yy++;
1304 xx=0;
1305 }
1306
1307 // 16_lable_venus.png
1308 // 58 17
1309 // 1158 345
1310 char lable_venus[]={1,1,1,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1\
1311 ,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,1,1,1
1312 ,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0
1313 ,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0
1314 ,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1
1315 ,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1,1,1
1316 ,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0
1317 ,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0
1318 ,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0
1319 ,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1
1320 ,1,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0
1321 ,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0
1322 ,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,0,0,0,0,1
14 Appendix A: Source Code Listings 354

1323 ,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1
1324 ,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0
1325 ,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1
1326 ,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1
1327 ,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1
1328 ,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0
1329 ,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1
1330 ,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0
1331 ,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1
1332 ,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0
1333 ,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0};
1334 xx=0; yy=0;
1335 for (int y=345;y<(345+17);++y)
1336 {
1337 for (int x=1158;x<(1158+58);x++) {
1338 if (lable_venus[get_index(xx,yy,58)] == 1) {
1339 image[get_index(x,y,width)]=color;
1340 }
1341 xx++;
1342 }
1343 yy++;
1344 xx=0;
1345 }
1346 }
1347
1348 void draw_label_lines(std::vector<std::tuple<float, float, float>> &image, std::tupl\
1349 e<float,float,float> &color, int width, int height, int radius)
1350 {
1351 std::tuple<int, int, int, int> coords;
1352 std::vector<std::tuple<int,int>> points;
1353 coords=std::make_tuple(976,668,1212,668);
1354 get_line_points(points,coords);
1355 draw(points,image,color,width,height,radius);
1356 points.clear();
1357 coords=std::make_tuple(973,314,1212,314);
1358 get_line_points(points,coords);
1359 draw(points,image,color,width,height,radius);
1360 points.clear();
1361 coords=std::make_tuple(676,685,676,723);
1362 get_line_points(points,coords);
1363 draw(points,image,color,width,height,radius);
1364 points.clear();
1365 coords=std::make_tuple(448,602,448,723);
14 Appendix A: Source Code Listings 355

1366 get_line_points(points,coords);
1367 draw(points,image,color,width,height,radius);
1368 points.clear();
1369 }
1370
1371 void draw_hexagon(std::vector<std::tuple<float, float, float>> &image, std::tuple<fl\
1372 oat,float,float> &color, int centerx, int centery, int radius, int width, int height
1373 , int cradius)
1374 {
1375 std::tuple<int, int, int, int> coords;
1376 float ux = centerx - radius;
1377 float uy = centery - radius;
1378 float pt1x=ux, pt1y=uy, pt2x=ux, pt2y=uy, pt3x=ux, pt3y=uy, pt4x=ux, pt4y=uy, pt5x=\
1379 ux, pt5y=uy, pt6x=ux, pt6y=uy;
1380
1381 float const PI = 3.14159265;
1382 float A, B, C;
1383 A = radius/2;
1384 C = A / sin(30*PI/180);
1385 B = C * cos(30*PI/180);
1386
1387 pt1x += 0; pt1y += B;
1388 pt2x += A; pt2y += 0;
1389 pt3x += A+C; pt3y += 0;
1390 pt4x += 2*C; pt4y += B;
1391 pt5x += A+C; pt5y += 2*B;
1392 pt6x += A; pt6y += 2*B;
1393
1394 std::vector<std::tuple<int,int>> points;
1395 coords=std::make_tuple(pt1x,pt1y,pt2x,pt2y);
1396 get_line_points(points,coords);
1397 draw(points,image,color,width,height,cradius);
1398 points.clear();
1399 coords=std::make_tuple(pt2x,pt2y,pt3x,pt3y);
1400 get_line_points(points,coords);
1401 draw(points,image,color,width,height,cradius);
1402 points.clear();
1403 coords=std::make_tuple(pt3x,pt3y,pt4x,pt4y);
1404 get_line_points(points,coords);
1405 draw(points,image,color,width,height,cradius);
1406 points.clear();
1407 coords=std::make_tuple(pt4x,pt4y,pt5x,pt5y);
1408 get_line_points(points,coords);
14 Appendix A: Source Code Listings 356

1409 draw(points,image,color,width,height,cradius);
1410 points.clear();
1411 coords=std::make_tuple(pt5x,pt5y,pt6x,pt6y);
1412 get_line_points(points,coords);
1413 draw(points,image,color,width,height,cradius);
1414 points.clear();
1415 coords=std::make_tuple(pt6x,pt6y,pt1x,pt1y);
1416 get_line_points(points,coords);
1417 draw(points,image,color,width,height,cradius);
1418 points.clear();
1419 }
1420
1421 void generate_noise_image(std::vector<std::tuple<float, float, float>> &image, int w\
1422 idth, int height)
1423 {
1424 std::tuple<float, float, float> color;
1425 float rndnum=0.0f;
1426
1427 std::random_device rd;
1428 std::mt19937 mt(rd());
1429 std::uniform_real_distribution<float> dist(0.0f, 1.0f);
1430
1431 for (int y=0;y<height;++y) {
1432 for (int x=0;x<width;++x) {
1433 rndnum=dist(mt);
1434 color=std::make_tuple(rndnum,rndnum,rndnum);
1435 image[get_index(x,y,width)]=color;
1436 }
1437 }
1438 }
1439
1440 void generate_linear_gradient_image(std::vector<std::tuple<float, float, float>> &im\
1441 age, std::tuple<float, float, float> &fcolor, std::tuple<float, float, float> &tcolo
1442 r, int width, int height)
1443 {
1444 std::tuple<float, float, float> color;
1445 double resultRed=0.0f;
1446 double resultGreen=0.0f;
1447 double resultBlue=0.0f;
1448 double fr,fg,fb,tr,tg,tb;
1449 double percent=0.0f;
1450 std::tie(fr,fg,fb)=fcolor;
1451 std::tie(tr,tg,tb)=tcolor;
14 Appendix A: Source Code Listings 357

1452
1453 for (int y=0;y<height;++y) {
1454 percent=double(y)/double(height);
1455 resultRed = fr + percent * (tr - fr);
1456 resultGreen = fg + percent * (tg - fg);
1457 resultBlue = fb + percent * (tb - fb);
1458 color=std::make_tuple(resultRed,resultGreen,resultBlue);
1459 for (int x=0;x<width;++x) {
1460 image[get_index(x,y,width)]=color;
1461 }
1462 }
1463 }
1464
1465 void blended_two_images(std::vector<std::tuple<float, float, float>> &blend1,std::ve\
1466 ctor<std::tuple<float, float, float>> &blend2,int width,int height,float alpha)
1467 {
1468 std::tuple<float, float, float> color1=std::make_tuple(0.0f,0.0f,0.0f);
1469 std::tuple<float, float, float> color2=std::make_tuple(0.0f,0.0f,0.0f);
1470 float r=0.0f; float g=0.0f; float b=0.0f;
1471
1472 for (int y=0;y<height;++y) {
1473 for (int x=0;x<width;++x) {
1474 color1=blend1[get_index(x,y,width)];
1475 color2=blend2[get_index(x,y,width)];
1476 r = (std::get<0>(color2) * alpha) + (std::get<0>(color1) * (1.0f - alpha));
1477 g = (std::get<1>(color2) * alpha) + (std::get<1>(color1) * (1.0f - alpha));
1478 b = (std::get<2>(color2) * alpha) + (std::get<2>(color1) * (1.0f - alpha));
1479 blend1[get_index(x,y,width)]=std::make_tuple(r, g, b);
1480 }
1481 }
1482 }
1483
1484 void blend_hexagon(std::vector<std::tuple<float, float, float>> &blend1,std::vector<\
1485 std::tuple<float, float, float>> &blend2,int width,int height)
1486 {
1487 std::tuple<float, float, float> color1=std::make_tuple(0.0f,0.0f,0.0f);
1488 std::tuple<float, float, float> color2=std::make_tuple(1.0f,1.0f,1.0f);
1489 float r=0.0f; float g=0.0f; float b=0.0f; float alpha=0.8f;
1490
1491 for (int y=0;y<height;++y) {
1492 for (int x=0;x<width;++x) {
1493 if (blend2[get_index(x,y,width)] == color2)
1494 {
14 Appendix A: Source Code Listings 358

1495 color1=blend1[get_index(x,y,width)];
1496 r = (std::get<0>(color1) * alpha) + (0.0f * (1.0f - alpha));
1497 g = (std::get<1>(color1) * alpha) + (0.0f * (1.0f - alpha));
1498 b = (std::get<2>(color1) * alpha) + (0.0f * (1.0f - alpha));
1499 blend1[get_index(x,y,width)]=std::make_tuple(r,g,b);
1500 }
1501 }
1502 }
1503 }
1504
1505 double distance(int x1, int y1, int x2, int y2)
1506 {
1507 return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2) * 1.0);
1508 }
1509
1510 void generate_radial_gradient_image(std::vector<std::tuple<float, float, float>> &im\
1511 age, std::tuple<float, float, float> &fcolor, std::tuple<float, float, float> &tcolo
1512 r, int width, int height)
1513 {
1514 std::tuple<float, float, float> color;
1515 std::tuple<float, float, float> pink=std::tuple(1.0f,0.0f,1.0f);
1516 std::vector<std::tuple<float, float, float>> mask;
1517 mask.resize(calc_size(width,height));
1518 double distanceFromCenter=0.0f;
1519 double resultRed=0.0f;
1520 double resultGreen=0.0f;
1521 double resultBlue=0.0f;
1522
1523 for (int y=0;y<height;++y)
1524 {
1525 for (int x=0;x<width;++x)
1526 {
1527 mask[get_index(x,y,width)]=pink;
1528 image[get_index(x,y,width)]=fcolor;
1529 }
1530 }
1531
1532 int x0 = 0;
1533 int y0 = (height/2);
1534 int d = 3 - 2 * (height/2);
1535 int xx=(width/2)-1;
1536 int yy=(height/2)-1;
1537
14 Appendix A: Source Code Listings 359

1538 auto drawline = [&](int sx, int ex, int ny)


1539 {
1540 // uncomment if on windows
1541 //if (((sx>=0)&&(sx<width)) && ((ex>=0)&&(ex<width)) && ((ny>=0)&&(ny<height))) {
1542 for (int i = sx; i <= ex; i++) {
1543 mask[get_index(i, ny, width)]=fcolor;
1544 }
1545 //}
1546 };
1547
1548 while (y0 >= x0)
1549 {
1550 drawline(xx - x0, yy + x0, xx - y0);
1551 drawline(xx - y0, yy + y0, xx - x0);
1552 drawline(xx - x0, yy + x0, xx + y0);
1553 drawline(xx - y0, yy + y0, xx + x0);
1554 if (d < 0) d += 4 * x0++ + 6;
1555 else d += 4 * (x0++ - y0--) + 10;
1556 }
1557
1558 for (int y=0;y<height;++y)
1559 {
1560 for (int x=0;x<width;++x)
1561 {
1562 if (mask[get_index(x,y,width)] != pink) {
1563 distanceFromCenter = (distance(x, y, width/2, height/2)/(height/2));
1564 resultRed = std::get<0>(fcolor) + distanceFromCenter * (std::get<0>(
1565 d::get<0>(fcolor));
1566 resultGreen = std::get<1>(fcolor) + distanceFromCenter * (std::get<1
1567 std::get<1>(fcolor));
1568 resultBlue = std::get<2>(fcolor) + distanceFromCenter * (std::get<2>
1569 td::get<2>(fcolor));
1570 color=std::tuple(resultRed,resultGreen,resultBlue);
1571 image[get_index(x,y,width)]=color;
1572 } else {
1573 image[get_index(x,y,width)]=tcolor;
1574 }
1575 }
1576 }
1577 }
1578
1579 void generate_repeating_texture_image(std::vector<std::tuple<float, float, float>> &\
1580 image, std::tuple<float, float, float> &color, int width, int height)
14 Appendix A: Source Code Listings 360

1581 {
1582 std::tuple<float, float, float> bgcolor=std::make_tuple(1.0f,0.0f,1.0f);
1583 // 0,0 0,22 18,32 36,22 54,32 54,54 36,64 18,54 18,32 36,0 36,22 72,0 72,22 54,32 7\
1584 2,64 54,54 0,64 18,54
1585 for (int y=0;y<height;++y) {
1586 for (int x=0;x<width;++x) {
1587 image[get_index(x,y,width)]=bgcolor;
1588 }
1589 }
1590
1591 int arr[13][2] = {{0,0},{0,22},{18,32},{36,22},{54,32},{54,54},{36,64},{18,54},{36,\
1592 0},{72,0},{72,22},{72,64},{0,64}};
1593 int arr2[13][2] = {{0,1},{1,2},{2,3},{3,4},{4,5},{5,6},{6,7},{7,2},{8,3},{9,10},{10\
1594 ,4},{11,5},{12,7}};
1595 std::tuple<int, int, int, int> coords;
1596
1597 for (int i=0;i<13;++i) {
1598 coords=std::make_tuple(int(arr[arr2[i][0]][0]), int(arr[arr2[i][0]][1]), int(arr[a\
1599 rr2[i][1]][0]), int(arr[arr2[i][1]][1]));
1600 draw_line(image,coords,color,width,height);
1601 }
1602 }
1603
1604 void render_repeating_texture_image(std::vector<std::tuple<float, float, float>> &te\
1605 xture, int tw, int th,std::vector<std::tuple<float, float, float>> &image, int iw, i
1606 nt ih)
1607 {
1608 for (int y=0;y<ih;++y) {
1609 for (int x=0;x<iw;++x) {
1610 image[get_index(x,y,iw)]=texture[get_index(x%(tw-1),y%(th-1),tw)];
1611 }
1612 }
1613 }
1614
1615 void do_cookie_cut(std::vector<std::tuple<float, float, float>> &image, int w, int h\
1616 , std::vector<std::tuple<float, float, float>> &cookie, int cw, int ch, int startx,
1617 int starty)
1618 {
1619 int cx=0;int cy=0;
1620 for (int y=starty;y<(starty+ch);++y) {
1621 for (int x=startx;x<(startx+cw);++x) {
1622 cookie[get_index(cx,cy,cw)]=image[get_index(x,y,w)];
1623 cx++;
14 Appendix A: Source Code Listings 361

1624 }
1625 cy++;
1626 cx=0;
1627 }
1628 }
1629
1630 void add_honeycomb(std::vector<std::tuple<float, float, float>> &image, std::vector<\
1631 std::tuple<float, float, float>> &alpha, std::vector<std::tuple<float, float, float>
1632 > &texture, int w, int h)
1633 {
1634 std::tuple<float, float, float> color1;
1635 std::tuple<float, float, float> color2;
1636 std::tuple<float, float, float> color3;
1637 std::tuple<float, float, float> pink=std::make_tuple(1.0f,0.0f,1.0f);
1638 float ir,ig,ib;
1639
1640 for (int y=0;y<h;++y) {
1641 for (int x=0;x<w;++x) {
1642 if (texture[get_index(x,y,w)] != pink) {
1643 color1=image[get_index(x,y,w)];
1644 color2=texture[get_index(x,y,w)];
1645 color3=alpha[get_index(x,y,w)];
1646 ir = ((std::get<0>(color2) * std::get<0>(color3)) + (std::get<0>(col
1647 - std::get<0>(color3))));
1648 ig = ((std::get<1>(color2) * std::get<0>(color3)) + (std::get<1>(col
1649 - std::get<0>(color3))));
1650 ib = ((std::get<2>(color2) * std::get<0>(color3)) + (std::get<2>(col
1651 - std::get<0>(color3))));
1652 image[get_index(x,y,w)]=std::make_tuple(ir,ig,ib);
1653 }
1654 }
1655 }
1656 }
1657
1658 void add_white_heaxagon_border(std::vector<std::tuple<float, float, float>> &image1,\
1659 std::vector<std::tuple<float, float, float>> &image2,int width,int height)
1660 {
1661 std::tuple<float, float, float> color=std::make_tuple(1.0f,1.0f,1.0f);
1662
1663 for (int y=0;y<height;++y) {
1664 for (int x=0;x<width;++x) {
1665 if (image2[get_index(x,y,width)] == color)
1666 {
14 Appendix A: Source Code Listings 362

1667 image1[get_index(x,y,width)]=color;
1668 }
1669 }
1670 }
1671 }
1672
1673 void stamp_cookie(std::vector<std::tuple<float, float, float>> &image, int w, int h,\
1674 std::vector<std::tuple<float, float, float>> &cookie, int cw, int ch, int startx, i
1675 nt starty)
1676 {
1677 int cx=0;int cy=0;
1678 for (int y=starty;y<(starty+ch);++y) {
1679 for (int x=startx;x<(startx+cw);++x) {
1680 image[get_index(x,y,w)]=cookie[get_index(cx,cy,cw)];
1681 cx++;
1682 }
1683 cy++;
1684 cx=0;
1685 }
1686 }
1687
1688 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
1689 height, std::string filename)
1690 {
1691 std::tuple<float, float, float> color;
1692 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);
1693 out << "P6" << std::endl << width << ' ' << height << std::endl << "255" << std::en\
1694 dl;
1695
1696 for (int i=0;i<(width*height);++i)
1697 {
1698 color=image[i];
1699 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*255.0f) << char(\
1700 std::get<2>(color)*255.0f);
1701 }
1702 out.close();
1703 }
1704
1705 int main()
1706 {
1707 std::vector<std::tuple<float, float, float>> image1;
1708 int width=1600,height=900;
1709
14 Appendix A: Source Code Listings 363

1710 image1.resize(calc_size(width,height));
1711
1712 generate_noise_image(image1, width, height);
1713
1714 std::cout << "saving: 16_draw_market_size1.ppm." << std::endl;
1715 save_image(image1,width,height,"16_draw_market_size1.ppm");
1716
1717 std::vector<std::tuple<float, float, float>> image2;
1718 image2.resize(calc_size(width,height));
1719
1720 std::tuple<float, float, float> fcolor=std::make_tuple(0.5294117647f,0.8235294118f,\
1721 0.8078431373f);
1722 std::tuple<float, float, float> tcolor=std::make_tuple(0.2588235294f,0.2196078431f,\
1723 0.3921568627f);
1724 generate_linear_gradient_image(image2,fcolor,tcolor,width,height);
1725
1726 std::cout << "saving: 16_draw_market_size2.ppm." << std::endl;
1727 save_image(image2,width,height,"16_draw_market_size2.ppm");
1728
1729 blended_two_images(image1,image2,width,height,0.9);
1730
1731 std::cout << "saving: 16_draw_market_size3.ppm." << std::endl;
1732 save_image(image1,width,height,"16_draw_market_size3.ppm");
1733
1734 // radial gradient
1735 std::vector<std::tuple<float, float, float>> image3;
1736 image3.resize(calc_size(900,900));
1737
1738 fcolor=std::make_tuple(1.0f,1.0f,1.0f);
1739 tcolor=std::make_tuple(0.0f,0.0f,0.0f);
1740
1741 generate_radial_gradient_image(image3,fcolor,tcolor,900,900);
1742
1743 std::cout << "saving: 16_draw_market_size4.ppm." << std::endl;
1744 save_image(image3,900,900,"16_draw_market_size4.ppm");
1745
1746 // Repeating texture generation
1747 std::vector<std::tuple<float, float, float>> image4;
1748 image4.resize(calc_size(73,65));
1749
1750 fcolor=std::make_tuple(0.5294117647f,0.8235294118f,0.8078431373f);
1751 generate_repeating_texture_image(image4,fcolor,73,65);
1752
14 Appendix A: Source Code Listings 364

1753 std::cout << "saving: 16_draw_market_size5.ppm." << std::endl;


1754 save_image(image4,73,65,"16_draw_market_size5.ppm");
1755
1756 // Render repeating texture
1757 std::vector<std::tuple<float, float, float>> image5;
1758 image5.resize(calc_size(900,900));
1759
1760 render_repeating_texture_image(image4,73,65,image5,900,900);
1761
1762 std::cout << "saving: 16_draw_market_size6.ppm." << std::endl;
1763 save_image(image5,900,900,"16_draw_market_size6.ppm");
1764
1765 // Do cookie cut
1766 std::vector<std::tuple<float, float, float>> image6;
1767 image6.resize(calc_size(900,900));
1768
1769 do_cookie_cut(image1,width,height,image6,900,900,350,0);
1770
1771 std::cout << "saving: 16_draw_market_size7.ppm." << std::endl;
1772 save_image(image6,900,900,"16_draw_market_size7.ppm");
1773
1774 // Add honeycomb
1775 add_honeycomb(image6,image3,image5,900,900);
1776
1777 std::cout << "saving: 16_draw_market_size8.ppm." << std::endl;
1778 save_image(image6,900,900,"16_draw_market_size8.ppm");
1779
1780 // Stamp cookie
1781 stamp_cookie(image1,width,height,image6,900,900,350,0);
1782
1783 std::cout << "saving: 16_draw_market_size9.ppm." << std::endl;
1784 save_image(image1,width,height,"16_draw_market_size9.ppm");
1785
1786 // Hexagons
1787 std::vector<std::tuple<float, float, float>> image7;
1788 image7.resize(calc_size(width,height));
1789 fcolor=std::make_tuple(1.0f,1.0f,1.0f);
1790 tcolor=std::make_tuple(0.0f,0.0f,0.0f);
1791 draw_hexagon(image7,fcolor,784,340,190,width,height,2);
1792 draw_hexagon(image7,fcolor,520,500,143,width,height,2);
1793 draw_hexagon(image7,fcolor,730,610,107,width,height,2);
1794 draw_hexagon(image7,fcolor,900,680,76,width,height,2);
1795
14 Appendix A: Source Code Listings 365

1796 flood_fill(image7,784,340,tcolor,fcolor,width);
1797 flood_fill(image7,520,500,tcolor,fcolor,width);
1798 flood_fill(image7,730,610,tcolor,fcolor,width);
1799 flood_fill(image7,900,680,tcolor,fcolor,width);
1800
1801 std::cout << "saving: 16_draw_market_size10.ppm." << std::endl;
1802 save_image(image7,width,height,"16_draw_market_size10.ppm");
1803
1804 std::vector<std::tuple<float, float, float>> image8;
1805 image8.resize(calc_size(width,height));
1806 fcolor=std::make_tuple(1.0f,1.0f,1.0f);
1807 draw_hexagon(image8,fcolor,784,340,190,width,height,2);
1808 draw_hexagon(image8,fcolor,520,500,143,width,height,2);
1809 draw_hexagon(image8,fcolor,730,610,107,width,height,2);
1810 draw_hexagon(image8,fcolor,900,680,76,width,height,2);
1811
1812 std::cout << "saving: 16_draw_market_size11.ppm." << std::endl;
1813 save_image(image8,width,height,"16_draw_market_size11.ppm");
1814
1815 blend_hexagon(image1,image7,width,height);
1816
1817 std::cout << "saving: 16_draw_market_size12.ppm." << std::endl;
1818 save_image(image1,width,height,"16_draw_market_size12.ppm");
1819
1820 add_white_heaxagon_border(image1,image8,width,height);
1821
1822 std::cout << "saving: 16_draw_market_size13.ppm." << std::endl;
1823 save_image(image1,width,height,"16_draw_market_size13.ppm");
1824
1825 // Add label lines
1826 fcolor=std::make_tuple(1.0f,1.0f,1.0f);
1827 draw_label_lines(image1,fcolor,width,height,2);
1828
1829 std::cout << "saving: 16_draw_market_size14.ppm." << std::endl;
1830 save_image(image1,width,height,"16_draw_market_size14.ppm");
1831
1832 // Add labels
1833 draw_labels(image1,fcolor,width,height);
1834
1835 std::cout << "saving: 16_draw_market_size15.ppm." << std::endl;
1836 save_image(image1,width,height,"16_draw_market_size15.ppm");
1837
1838 return 0;
14 Appendix A: Source Code Listings 366

1839 }

16_draw_investment.cpp - 94001 bytes.

1 // Compile: clang++ -std=c++17 16_draw_investment.cpp -o 16_draw_investment


2 #define _USE_MATH_DEFINES
3
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10 #include <algorithm>
11
12 int get_index(int x, int y, int width)
13 {
14 return x+width*y;
15 }
16
17 int calc_size(int width, int height)
18 {
19 return width*height;
20 }
21
22 void clear_image(std::vector<std::tuple<float, float, float>> &image, std::tuple<fl\
23 oat, float, float> &color, int width, int height)
24 {
25 for (int y=0;y<height;++y) {
26 for (int x=0;x<width;++x) {
27 image[get_index(x,y,width)]=color;
28 }
29 }
30 }
31
32 void draw_filled_circle(int x, int y, int radius, std::vector<std::tuple<float, floa\
33 t, float>> &image, std::tuple<float, float, float> &color, int width, int height)
34 {
35 int x0 = 0;
36 int y0 = radius;
37 int d = 3 - 2 * radius;
38 if (!radius) return;
39
14 Appendix A: Source Code Listings 367

40 auto drawline = [&](int sx, int ex, int ny)


41 {
42 // uncomment if on windows
43 // if (((sx>=0)&&(sx<width)) && ((ex>=0)&&(ex<width)) && ((ny>=0)&&(ny<height))) {
44 for (int i = sx; i <= ex; i++) {
45 image[get_index(i, ny, width)]=color;
46 }
47 //}
48 };
49
50 while (y0 >= x0)
51 {
52 drawline(x - x0, x + x0, y - y0);
53 drawline(x - y0, x + y0, y - x0);
54 drawline(x - x0, x + x0, y + y0);
55 drawline(x - y0, x + y0, y + x0);
56 if (d < 0) d += 4 * x0++ + 6;
57 else d += 4 * (x0++ - y0--) + 10;
58 }
59 }
60
61 void get_all_ys(std::vector<int> &ys,std::vector<std::tuple<int,int>> &coords)
62 {
63 for (auto& c : coords) {
64 ys.push_back(std::get<1>(c));
65 }
66
67 sort(ys.begin(), ys.end());
68 ys.erase( unique( ys.begin(), ys.end() ), ys.end() );
69 }
70
71 void draw_line_coords(int x1, int y1, int x2, int y2,std::vector<std::tuple<int,int>\
72 > &coords)
73 {
74 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
75 dx = x2 - x1; dy = y2 - y1;
76 if (dx == 0)
77 {
78 if (y2 < y1) std::swap(y1, y2);
79 for (y = y1; y <= y2; y++)
80 coords.push_back(std::make_tuple(x1,y));
81 return;
82 }
14 Appendix A: Source Code Listings 368

83 if (dy == 0)
84 {
85 if (x2 < x1) std::swap(x1, x2);
86 for (x = x1; x <= x2; x++)
87 coords.push_back(std::make_tuple(x,y1));
88 return;
89 }
90 dx1 = abs(dx); dy1 = abs(dy);
91 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
92 if (dy1 <= dx1)
93 {
94 if (dx >= 0)
95 {
96 x = x1; y = y1; xe = x2;
97 }
98 else
99 {
100 x = x2; y = y2; xe = x1;
101 }
102 coords.push_back(std::make_tuple(x,y));
103 for (i = 0; x<xe; i++)
104 {
105 x = x + 1;
106 if (px<0)
107 px = px + 2 * dy1;
108 else
109 {
110 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
111 px = px + 2 * (dy1 - dx1);
112 }
113 coords.push_back(std::make_tuple(x,y));
114 }
115 }
116 else
117 {
118 if (dy >= 0)
119 {
120 x = x1; y = y1; ye = y2;
121 }
122 else
123 {
124 x = x2; y = y2; ye = y1;
125 }
14 Appendix A: Source Code Listings 369

126 coords.push_back(std::make_tuple(x,y));
127 for (i = 0; y<ye; i++)
128 {
129 y = y + 1;
130 if (py <= 0)
131 py = py + 2 * dx1;
132 else
133 {
134 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
135 py = py + 2 * (dx1 - dy1);
136 }
137 coords.push_back(std::make_tuple(x,y));
138 }
139 }
140 }
141
142 void draw_filled_wedge(int x_cen,int y_cen,int rad,int start_ang,int end_ang,std::ve\
143 ctor<std::tuple<float, float, float>> &image,std::tuple<float, float, float> &color,
144 int width, int height)
145 {
146 std::vector<std::tuple<int,int>> coords;
147
148 float ang=(((start_ang<=end_ang)?start_ang:end_ang)*(M_PI/180));
149 float range=(((end_ang>start_ang)?end_ang:start_ang)*(M_PI/180));
150 float x=(rad*cos(ang));
151 float y=(rad*sin(ang));
152 do
153 {
154 coords.push_back(std::make_tuple((int)(x_cen+x+0.5),(int)(y_cen-y+0.5)));
155 ang+=0.001;
156 x=(rad*cos(ang));
157 y=(rad*sin(ang));
158 }
159 while(ang<=range);
160
161 std::tuple<int,int> co1=coords.front();
162 std::tuple<int,int> co2=coords.back();
163
164 draw_line_coords(x_cen,y_cen,std::get<0>(co1),std::get<1>(co1),coords);
165 draw_line_coords(x_cen,y_cen,std::get<0>(co2),std::get<1>(co2),coords);
166
167 std::vector<int> ys;
168 std::vector<int> xs;
14 Appendix A: Source Code Listings 370

169 get_all_ys(ys,coords);
170 std::vector<std::tuple<int,int,int,int>> lines;
171
172 for (int search=0;search<=ys.size();++search)
173 {
174 for (auto& c : coords) {
175 if (std::get<1>(c) == ys[search]) {
176 xs.push_back(std::get<0>(c));
177 }
178 }
179 sort(xs.begin(), xs.end());
180 lines.push_back(std::make_tuple(xs.front(),ys[search],xs.back(),ys[search]));
181 xs.clear();
182 }
183
184 auto drawline = [&](int sx, int ex, int ny)
185 {
186 for (int i = sx; i <= ex; i++)
187 image[get_index(i, ny, width)]=color;
188 };
189
190 for (auto& l : lines) {
191 drawline(std::get<0>(l),std::get<2>(l),std::get<1>(l));
192 }
193 }
194
195 void draw_line(std::vector<std::tuple<float, float, float>> &image, std::tuple<int, \
196 int, int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
197 {
198 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
199 int y2=std::get<3>(coords);
200 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
201 dx = x2 - x1; dy = y2 - y1;
202
203 if (dx == 0)
204 {
205 if (y2 < y1) std::swap(y1, y2);
206 for (y = y1; y <= y2; y++)
207 image[get_index(x1,y,width)]=color;
208 return;
209 }
210 if (dy == 0)
211 {
14 Appendix A: Source Code Listings 371

212 if (x2 < x1) std::swap(x1, x2);


213 for (x = x1; x <= x2; x++)
214 image[get_index(x,y1,width)]=color;
215 return;
216 }
217 dx1 = abs(dx); dy1 = abs(dy);
218 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
219 if (dy1 <= dx1)
220 {
221 if (dx >= 0)
222 {
223 x = x1; y = y1; xe = x2;
224 }
225 else
226 {
227 x = x2; y = y2; xe = x1;
228 }
229 image[get_index(x,y,width)]=color;
230 for (i = 0; x<xe; i++)
231 {
232 x = x + 1;
233 if (px<0)
234 px = px + 2 * dy1;
235 else
236 {
237 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
238 px = px + 2 * (dy1 - dx1);
239 }
240 image[get_index(x,y,width)]=color;
241 }
242 }
243 else
244 {
245 if (dy >= 0)
246 {
247 x = x1; y = y1; ye = y2;
248 }
249 else
250 {
251 x = x2; y = y2; ye = y1;
252 }
253 image[get_index(x,y,width)]=color;
254 for (i = 0; y<ye; i++)
14 Appendix A: Source Code Listings 372

255 {
256 y = y + 1;
257 if (py <= 0)
258 py = py + 2 * dx1;
259 else
260 {
261 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
262 py = py + 2 * (dx1 - dy1);
263 }
264 image[get_index(x,y,width)]=color;
265 }
266 }
267 }
268
269 void generate_noise_image(std::vector<std::tuple<float, float, float>> &image, int w\
270 idth, int height)
271 {
272 std::tuple<float, float, float> color;
273 float rndnum=0.0f;
274
275 std::random_device rd;
276 std::mt19937 mt(rd());
277 std::uniform_real_distribution<float> dist(0.0f, 1.0f);
278
279 for (int y=0;y<height;++y) {
280 for (int x=0;x<width;++x) {
281 rndnum=dist(mt);
282 color=std::make_tuple(rndnum,rndnum,rndnum);
283 image[get_index(x,y,width)]=color;
284 }
285 }
286 }
287
288 void generate_linear_gradient_image(std::vector<std::tuple<float, float, float>> &im\
289 age, std::tuple<float, float, float> &fcolor, std::tuple<float, float, float> &tcolo
290 r, int width, int height)
291 {
292 std::tuple<float, float, float> color;
293 double resultRed=0.0f;
294 double resultGreen=0.0f;
295 double resultBlue=0.0f;
296 double fr,fg,fb,tr,tg,tb;
297 double percent=0.0f;
14 Appendix A: Source Code Listings 373

298 std::tie(fr,fg,fb)=fcolor;
299 std::tie(tr,tg,tb)=tcolor;
300
301 for (int y=0;y<height;++y) {
302 percent=double(y)/double(height);
303 resultRed = fr + percent * (tr - fr);
304 resultGreen = fg + percent * (tg - fg);
305 resultBlue = fb + percent * (tb - fb);
306 color=std::make_tuple(resultRed,resultGreen,resultBlue);
307 for (int x=0;x<width;++x) {
308 image[get_index(x,y,width)]=color;
309 }
310 }
311 }
312
313 void blended_two_images(std::vector<std::tuple<float, float, float>> &blend1,std::ve\
314 ctor<std::tuple<float, float, float>> &blend2,int width,int height,float alpha)
315 {
316 std::tuple<float, float, float> color1=std::make_tuple(0.0f,0.0f,0.0f);
317 std::tuple<float, float, float> color2=std::make_tuple(0.0f,0.0f,0.0f);
318 float r=0.0f; float g=0.0f; float b=0.0f;
319
320 for (int y=0;y<height;++y) {
321 for (int x=0;x<width;++x) {
322 color1=blend1[get_index(x,y,width)];
323 color2=blend2[get_index(x,y,width)];
324 r = (std::get<0>(color2) * alpha) + (std::get<0>(color1) * (1.0f - alpha));
325 g = (std::get<1>(color2) * alpha) + (std::get<1>(color1) * (1.0f - alpha));
326 b = (std::get<2>(color2) * alpha) + (std::get<2>(color1) * (1.0f - alpha));
327 blend1[get_index(x,y,width)]=std::make_tuple(r, g, b);
328 }
329 }
330 }
331
332 double distance(int x1, int y1, int x2, int y2)
333 {
334 return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2) * 1.0);
335 }
336
337 void generate_radial_gradient_image(std::vector<std::tuple<float, float, float>> &im\
338 age, std::tuple<float, float, float> &fcolor, std::tuple<float, float, float> &tcolo
339 r, int width, int height)
340 {
14 Appendix A: Source Code Listings 374

341 std::tuple<float, float, float> color;


342 std::tuple<float, float, float> pink=std::tuple(1.0f,0.0f,1.0f);
343 std::vector<std::tuple<float, float, float>> mask;
344 mask.resize(calc_size(width,height));
345 double distanceFromCenter=0.0f;
346 double resultRed=0.0f;
347 double resultGreen=0.0f;
348 double resultBlue=0.0f;
349
350 for (int y=0;y<height;++y)
351 {
352 for (int x=0;x<width;++x)
353 {
354 mask[get_index(x,y,width)]=pink;
355 image[get_index(x,y,width)]=fcolor;
356 }
357 }
358
359 int x0 = 0;
360 int y0 = (height/2);
361 int d = 3 - 2 * (height/2);
362 int xx=(width/2)-1;
363 int yy=(height/2)-1;
364
365 auto drawline = [&](int sx, int ex, int ny)
366 {
367 // uncomment if on windows
368 //if (((sx >= 0)&&(sx < width)) && ((ex >= 0)&&(ex < width)) && ((ny >= 0)&&(ny < \
369 height))) {
370 for (int i = sx; i <= ex; i++) {
371 mask[get_index(i, ny, width)]=fcolor;
372 }
373 //}
374 };
375
376 while (y0 >= x0)
377 {
378 drawline(xx - x0, yy + x0, xx - y0);
379 drawline(xx - y0, yy + y0, xx - x0);
380 drawline(xx - x0, yy + x0, xx + y0);
381 drawline(xx - y0, yy + y0, xx + x0);
382 if (d < 0) d += 4 * x0++ + 6;
383 else d += 4 * (x0++ - y0--) + 10;
14 Appendix A: Source Code Listings 375

384 }
385
386 for (int y=0;y<height;++y)
387 {
388 for (int x=0;x<width;++x)
389 {
390 if (mask[get_index(x,y,width)] != pink) {
391 distanceFromCenter = (distance(x, y, width/2, height/2)/(height/2));
392 resultRed = std::get<0>(fcolor) + distanceFromCenter * (std::get<0>(
393 d::get<0>(fcolor));
394 resultGreen = std::get<1>(fcolor) + distanceFromCenter * (std::get<1
395 std::get<1>(fcolor));
396 resultBlue = std::get<2>(fcolor) + distanceFromCenter * (std::get<2>
397 td::get<2>(fcolor));
398 color=std::tuple(resultRed,resultGreen,resultBlue);
399 image[get_index(x,y,width)]=color;
400 } else {
401 image[get_index(x,y,width)]=tcolor;
402 }
403 }
404 }
405 }
406
407 void generate_repeating_texture_image(std::vector<std::tuple<float, float, float>> &\
408 image, std::tuple<float, float, float> &color, int width, int height)
409 {
410 std::tuple<float, float, float> bgcolor=std::make_tuple(1.0f,0.0f,1.0f);
411 // 0,0 0,22 18,32 36,22 54,32 54,54 36,64 18,54 18,32 36,0 36,22 72,0 72,22 54,32 7\
412 2,64 54,54 0,64 18,54
413 for (int y=0;y<height;++y) {
414 for (int x=0;x<width;++x) {
415 image[get_index(x,y,width)]=bgcolor;
416 }
417 }
418
419 int arr[13][2] = {{0,0},{0,22},{18,32},{36,22},{54,32},{54,54},{36,64},{18,54},{36,\
420 0},{72,0},{72,22},{72,64},{0,64}};
421 int arr2[13][2] = {{0,1},{1,2},{2,3},{3,4},{4,5},{5,6},{6,7},{7,2},{8,3},{9,10},{10\
422 ,4},{11,5},{12,7}};
423 std::tuple<int, int, int, int> coords;
424
425 for (int i=0;i<13;++i) {
426 coords=std::make_tuple(int(arr[arr2[i][0]][0]), int(arr[arr2[i][0]][1]), int(arr[a\
14 Appendix A: Source Code Listings 376

427 rr2[i][1]][0]), int(arr[arr2[i][1]][1]));


428 draw_line(image,coords,color,width,height);
429 }
430 }
431
432 void render_repeating_texture_image(std::vector<std::tuple<float, float, float>> &te\
433 xture, int tw, int th,std::vector<std::tuple<float, float, float>> &image, int iw, i
434 nt ih)
435 {
436 for (int y=0;y<ih;++y) {
437 for (int x=0;x<iw;++x) {
438 image[get_index(x,y,iw)]=texture[get_index(x%(tw-1),y%(th-1),tw)];
439 }
440 }
441 }
442
443 void do_cookie_cut(std::vector<std::tuple<float, float, float>> &image, int w, int h\
444 , std::vector<std::tuple<float, float, float>> &cookie, int cw, int ch, int startx,
445 int starty)
446 {
447 int cx=0;int cy=0;
448 for (int y=starty;y<(starty+ch);++y) {
449 for (int x=startx;x<(startx+cw);++x) {
450 cookie[get_index(cx,cy,cw)]=image[get_index(x,y,w)];
451 cx++;
452 }
453 cy++;
454 cx=0;
455 }
456 }
457
458 void add_honeycomb(std::vector<std::tuple<float, float, float>> &image, std::vector<\
459 std::tuple<float, float, float>> &alpha, std::vector<std::tuple<float, float, float>
460 > &texture, int w, int h)
461 {
462 std::tuple<float, float, float> color1;
463 std::tuple<float, float, float> color2;
464 std::tuple<float, float, float> color3;
465 std::tuple<float, float, float> pink=std::make_tuple(1.0f,0.0f,1.0f);
466 float ir,ig,ib;
467
468 for (int y=0;y<h;++y) {
469 for (int x=0;x<w;++x) {
14 Appendix A: Source Code Listings 377

470 if (texture[get_index(x,y,w)] != pink) {


471 color1=image[get_index(x,y,w)];
472 color2=texture[get_index(x,y,w)];
473 color3=alpha[get_index(x,y,w)];
474 ir = ((std::get<0>(color2) * std::get<0>(color3)) + (std::get<0>(col
475 - std::get<0>(color3))));
476 ig = ((std::get<1>(color2) * std::get<0>(color3)) + (std::get<1>(col
477 - std::get<0>(color3))));
478 ib = ((std::get<2>(color2) * std::get<0>(color3)) + (std::get<2>(col
479 - std::get<0>(color3))));
480 image[get_index(x,y,w)]=std::make_tuple(ir,ig,ib);
481 }
482 }
483 }
484 }
485
486 void stamp_cookie(std::vector<std::tuple<float, float, float>> &image, int w, int h,\
487 std::vector<std::tuple<float, float, float>> &cookie, int cw, int ch, int startx, i
488 nt starty)
489 {
490 int cx=0;int cy=0;
491 for (int y=starty;y<(starty+ch);++y) {
492 for (int x=startx;x<(startx+cw);++x) {
493 image[get_index(x,y,w)]=cookie[get_index(cx,cy,cw)];
494 cx++;
495 }
496 cy++;
497 cx=0;
498 }
499 }
500
501 void draw_labels(std::vector<std::tuple<float, float, float>> &image, std::tuple<flo\
502 at,float,float> &color, int width, int height)
503 {
504 // 16_lable_investment_10.png
505 // 79 38
506 // 1198 577
507 char lable_investment_10[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\
508 ,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0
509 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
510 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
511 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
512 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
14 Appendix A: Source Code Listings 378

513 ,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
514 ,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
515 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0
516 ,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
517 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1
518 ,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0
519 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0
520 ,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0
521 ,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1
522 ,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
523 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0
524 ,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0
525 ,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0
526 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0
527 ,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0
528 ,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
529 ,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
530 ,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0
531 ,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
532 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0
533 ,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0
534 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1
535 ,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0
536 ,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
537 ,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
538 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0
539 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
540 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0
541 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0
542 ,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0
543 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0
544 ,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
545 ,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
546 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
547 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0
548 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
549 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0
550 ,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0
551 ,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
552 ,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0
553 ,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
554 ,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
555 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1
14 Appendix A: Source Code Listings 379

556 ,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
557 ,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0
558 ,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0
559 ,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1
560 ,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1
561 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0
562 ,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
563 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1
564 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0
565 ,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
566 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
567 ,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0
568 ,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0
569 ,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
570 ,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0
571 ,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
572 ,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0
573 ,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
574 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1
575 ,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
576 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0
577 ,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0
578 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0};
579 int xx=0; int yy=0;
580 for (int y=577;y<(577+38);++y)
581 {
582 for (int x=1198;x<(1198+79);x++) {
583 if (lable_investment_10[get_index(xx,yy,79)] == 1) {
584 image[get_index(x,y,width)]=color;
585 }
586 xx++;
587 }
588 yy++;
589 xx=0;
590 }
591
592 // 16_lable_investment_20.png
593 // 80 38
594 // 338 615
595 char lable_investment_20[]={0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\
596 ,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0
597 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
598 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
14 Appendix A: Source Code Listings 380

599 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
600 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
601 ,0,0,0,0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,1,1,1
602 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
603 ,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0
604 ,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0
605 ,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0
606 ,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0
607 ,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0
608 ,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0
609 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0
610 ,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1
611 ,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0
612 ,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
613 ,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1
614 ,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0
615 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0
616 ,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1
617 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1
618 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0
619 ,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0
620 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0
621 ,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0
622 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
623 ,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
624 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
625 ,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
626 ,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0
627 ,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
628 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0
629 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
630 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
631 ,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0
632 ,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
633 ,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0
634 ,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
635 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1
636 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0
637 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0
638 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
639 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0
640 ,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1
641 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0
14 Appendix A: Source Code Listings 381

642 ,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0
643 ,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1
644 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0
645 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0
646 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1
647 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0
648 ,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0
649 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0
650 ,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0
651 ,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
652 ,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
653 ,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0
654 ,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
655 ,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0
656 ,1,1,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
657 ,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0
658 ,0,0,0,0,0,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0
659 ,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0
660 ,0,0,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0
661 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1
662 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1
663 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,1,1,1,1
664 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
665 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1
666 ,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
667 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0};
668 xx=0; yy=0;
669 for (int y=615;y<(615+38);++y)
670 {
671 for (int x=338;x<(338+80);x++) {
672 if (lable_investment_20[get_index(xx,yy,80)] == 1) {
673 image[get_index(x,y,width)]=color;
674 }
675 xx++;
676 }
677 yy++;
678 xx=0;
679 }
680
681 // 16_lable_investment_30.png
682 // 81 38
683 // 1196 345
684 char lable_investment_30[]={0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0\
14 Appendix A: Source Code Listings 382

685 ,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0
686 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
687 ,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
688 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
689 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
690 ,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
691 ,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
692 ,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0
693 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
694 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1
695 ,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1
696 ,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0
697 ,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0
698 ,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
699 ,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0
700 ,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0
701 ,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
702 ,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1
703 ,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
704 ,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0
705 ,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
706 ,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0
707 ,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
708 ,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1
709 ,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0
710 ,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0
711 ,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1
712 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1
713 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1
714 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0
715 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
716 ,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0
717 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0
718 ,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0
719 ,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0
720 ,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
721 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
722 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
723 ,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
724 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
725 ,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0
726 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
727 ,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0
14 Appendix A: Source Code Listings 383

728 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
729 ,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0
730 ,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
731 ,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0
732 ,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
733 ,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
734 ,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0
735 ,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
736 ,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0
737 ,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0
738 ,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0
739 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1
740 ,1,0,0,0,0,0,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1
741 ,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0
742 ,0,0,0,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0
743 ,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0
744 ,0,0,0,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0
745 ,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0
746 ,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0
747 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0
748 ,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1
749 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,1
750 ,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0
751 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1
752 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
753 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1
754 ,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
755 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0
756 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
757 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0};
758 xx=0; yy=0;
759 for (int y=345;y<(345+38);++y)
760 {
761 for (int x=1196;x<(1196+81);x++) {
762 if (lable_investment_30[get_index(xx,yy,81)] == 1) {
763 image[get_index(x,y,width)]=color;
764 }
765 xx++;
766 }
767 yy++;
768 xx=0;
769 }
770
14 Appendix A: Source Code Listings 384

771 // 16_lable_investment_40.png
772 // 81 38
773 // 337 430
774 char lable_investment_40[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0\
775 ,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0
776 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
777 ,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
778 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
779 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0
780 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0
781 ,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
782 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0
783 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
784 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1
785 ,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0
786 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1
787 ,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
788 ,0,0,0,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0
789 ,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
790 ,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0
791 ,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0
792 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1
793 ,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1
794 ,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0
795 ,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0
796 ,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0
797 ,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0
798 ,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1
799 ,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0
800 ,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0
801 ,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0
802 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1
803 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1
804 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0
805 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0
806 ,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0
807 ,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0
808 ,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0
809 ,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0
810 ,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
811 ,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
812 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
813 ,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
14 Appendix A: Source Code Listings 385

814 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0
815 ,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0
816 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0
817 ,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0
818 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0
819 ,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0
820 ,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1
821 ,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0
822 ,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0
823 ,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
824 ,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
825 ,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
826 ,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
827 ,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0
828 ,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
829 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1
830 ,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1
831 ,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0
832 ,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0
833 ,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0
834 ,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0
835 ,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0
836 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0
837 ,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,0
838 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1
839 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0
840 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0
841 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0
842 ,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
843 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0
844 ,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
845 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
846 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
847 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0};
848 xx=0; yy=0;
849 for (int y=430;y<(430+38);++y)
850 {
851 for (int x=337;x<(337+81);x++) {
852 if (lable_investment_40[get_index(xx,yy,81)] == 1) {
853 image[get_index(x,y,width)]=color;
854 }
855 xx++;
856 }
14 Appendix A: Source Code Listings 386

857 yy++;
858 xx=0;
859 }
860
861 // 16_lable_investment_investment.png
862 // 338 52
863 // 1114 128
864 char lable_investment_investment[]={1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0\
865 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
866 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1
867 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
868 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
869 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
870 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
871 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
872 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
873 ,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
874 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1
875 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
876 ,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
877 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
878 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
879 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1
880 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
881 ,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
882 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
883 ,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
884 ,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
885 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1
886 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
887 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1
888 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
889 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1
890 ,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
891 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
892 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
893 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
894 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
895 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
896 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
897 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1
898 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1
899 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
14 Appendix A: Source Code Listings 387

900 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
901 ,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
902 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
903 ,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
904 ,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
905 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
906 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1
907 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
908 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
909 ,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
910 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
911 ,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
912 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
913 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
914 ,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
915 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1
916 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
917 ,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
918 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
919 ,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
920 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
921 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
922 ,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
923 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0
924 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
925 ,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1
926 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
927 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
928 ,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
929 ,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
930 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
931 ,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
932 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
933 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
934 ,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
935 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
936 ,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
937 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
938 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
939 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
940 ,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
941 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
942 ,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0
14 Appendix A: Source Code Listings 388

943 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1
944 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1
945 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
946 ,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0
947 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
948 ,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
949 ,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1
950 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
951 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1
952 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
953 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1
954 ,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0
955 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
956 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
957 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1
958 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
959 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1
960 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
961 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1
962 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
963 ,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
964 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
965 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1
966 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1
967 ,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
968 ,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
969 ,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
970 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
971 ,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
972 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
973 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
974 ,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1
975 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
976 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
977 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
978 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1
979 ,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
980 ,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
981 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
982 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1
983 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0
984 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
985 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
14 Appendix A: Source Code Listings 389

986 ,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1
987 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
988 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
989 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0
990 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
991 ,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0
992 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
993 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
994 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1
995 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
996 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
997 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0
998 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
999 ,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1000 ,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1001 ,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
1002 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1003 ,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
1004 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1005 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1006 ,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1007 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
1008 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1009 ,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1010 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0
1011 ,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
1012 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1013 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
1014 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
1015 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
1016 ,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
1017 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1018 ,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0
1019 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1020 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1021 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
1022 ,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1023 ,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
1024 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
1025 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1026 ,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1027 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1028 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
14 Appendix A: Source Code Listings 390

1029 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
1030 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1031 ,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
1032 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1033 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1
1034 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
1035 ,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1036 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
1037 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
1038 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1039 ,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1040 ,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
1041 ,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1
1042 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
1043 ,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1
1044 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1045 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1046 ,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1
1047 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
1048 ,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
1049 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
1050 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1
1051 ,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1052 ,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1053 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0
1054 ,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1055 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
1056 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1057 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1058 ,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1
1059 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1060 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1061 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
1062 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1063 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1064 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1065 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1066 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
1067 ,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1068 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1069 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1070 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1071 ,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
14 Appendix A: Source Code Listings 391

1072 ,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1073 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1074 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1075 ,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
1076 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1077 ,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
1078 ,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1079 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1080 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1081 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
1082 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1083 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1
1084 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1
1085 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0
1086 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1087 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1088 ,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1
1089 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1090 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1091 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
1092 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1093 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0
1094 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1
1095 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1096 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1097 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1098 ,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
1099 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0
1100 ,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
1101 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1102 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1103 ,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
1104 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
1105 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1106 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1107 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
1108 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1109 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1110 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
1111 ,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0
1112 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1
1113 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1
1114 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
14 Appendix A: Source Code Listings 392

1115 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1116 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1117 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1118 ,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1
1119 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1120 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1
1121 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1122 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1123 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0
1124 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1125 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
1126 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1
1127 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
1128 ,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1
1129 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1130 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1
1131 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,0,0,0
1132 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1133 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
1134 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1
1135 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1
1136 ,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1137 ,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1138 ,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1139 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0
1140 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1141 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1142 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1143 ,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1
1144 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
1145 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1146 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1147 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1
1148 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1149 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0
1150 ,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
1151 ,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1
1152 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0
1153 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
1154 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1155 ,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1
1156 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1157 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
14 Appendix A: Source Code Listings 393

1158 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0
1159 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1160 ,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0
1161 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1162 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1163 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1
1164 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1165 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1166 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0
1167 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1168 ,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1169 ,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1170 ,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
1171 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1
1172 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
1173 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
1174 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1175 ,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1176 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
1177 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1178 ,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1179 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1180 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
1181 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0
1182 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
1183 ,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
1184 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
1185 ,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
1186 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1187 ,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
1188 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1189 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0
1190 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
1191 ,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1192 ,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
1193 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
1194 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1195 ,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
1196 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1197 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1198 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
1199 ,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1200 ,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
14 Appendix A: Source Code Listings 394

1201 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1202 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1
1203 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1
1204 ,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1205 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
1206 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
1207 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1208 ,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1209 ,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
1210 ,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1
1211 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
1212 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1
1213 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1214 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1215 ,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1
1216 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1217 ,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
1218 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
1219 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1220 ,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1221 ,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1222 ,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0
1223 ,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1
1224 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
1225 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1226 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1227 ,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
1228 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1229 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1230 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
1231 ,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
1232 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1233 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1234 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1235 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
1236 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1237 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1238 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
1239 ,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1240 ,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1241 ,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1242 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1243 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
14 Appendix A: Source Code Listings 395

1244 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
1245 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1246 ,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
1247 ,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1248 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1249 ,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1250 ,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
1251 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
1252 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
1253 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1
1254 ,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0
1255 ,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0
1256 ,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1257 ,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1
1258 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1259 ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0
1260 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1261 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1262 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0
1263 ,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1
1264 ,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1265 ,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1266 ,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
1267 ,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0
1268 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1269 ,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
1270 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1
1271 ,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
1272 ,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
1273 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
1274 ,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1275 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1276 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1277 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1
1278 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1279 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1280 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1281 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1282 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1283 xx=0; yy=0;
1284 for (int y=128;y<(128+52);++y)
1285 {
1286 for (int x=1114;x<(1114+338);x++) {
14 Appendix A: Source Code Listings 396

1287 if (lable_investment_investment[get_index(xx,yy,338)] == 1) {
1288 image[get_index(x,y,width)]=color;
1289 }
1290 xx++;
1291 }
1292 yy++;
1293 xx=0;
1294 }
1295
1296 // 16_lable_investment_jupiter.png
1297 // 84 20
1298 // 1194 440
1299 char lable_investment_jupiter[]={0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,\
1300 0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,
1301 1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1302 0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,
1303 1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1304 0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,
1305 1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1306 0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
1307 0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1308 0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
1309 0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1310 0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
1311 0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1312 0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
1313 0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1314 0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
1315 0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1316 0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,
1317 1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1318 0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,
1319 1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1320 0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,
1321 1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1322 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
1323 0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1324 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
1325 0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1326 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
1327 0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1328 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
1329 0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
14 Appendix A: Source Code Listings 397

1330 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
1331 0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,
1332 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
1333 0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,
1334 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,
1335 1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,
1336 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,
1337 1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,
1338 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1339 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1340 xx=0; yy=0;
1341 for (int y=440;y<(440+20);++y)
1342 {
1343 for (int x=1194;x<(1194+84);x++) {
1344 if (lable_investment_jupiter[get_index(xx,yy,84)] == 1) {
1345 image[get_index(x,y,width)]=color;
1346 }
1347 xx++;
1348 }
1349 yy++;
1350 xx=0;
1351 }
1352
1353 // 16_lable_investment_mercury.png
1354 // 101 20
1355 // 337 519
1356 char lable_investment_mercury[]={0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,\
1357 1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,
1358 0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,
1359 1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,
1360 1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,
1361 1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,
1362 1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,
1363 0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,
1364 1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,
1365 0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,
1366 0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,
1367 1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,
1368 0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,
1369 1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,
1370 0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,1,1,0,0,1,1,1,0,0,0,0,
1371 1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,
1372 1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,
14 Appendix A: Source Code Listings 398

1373 0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,
1374 0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,
1375 0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,
1376 1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
1377 0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,
1378 0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,
1379 1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,
1380 1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,
1381 1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
1382 0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,0,0,0,
1383 0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,
1384 1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,
1385 0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,
1386 0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,
1387 0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,
1388 1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,
1389 0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,
1390 0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,
1391 0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,
1392 0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1393 1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,
1394 1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,
1395 0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,
1396 0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,
1397 0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
1398 0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
1399 0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,
1400 0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,
1401 1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,
1402 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1403 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
1404 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
1405 xx=0; yy=0;
1406 for (int y=519;y<(519+20);++y)
1407 {
1408 for (int x=337;x<(337+101);x++) {
1409 if (lable_investment_mercury[get_index(xx,yy,101)] == 1) {
1410 image[get_index(x,y,width)]=color;
1411 }
1412 xx++;
1413 }
1414 yy++;
1415 xx=0;
14 Appendix A: Source Code Listings 399

1416 }
1417
1418 // 16_lable_investment_saturn.png
1419 // 81 20
1420 // 1197 665
1421 char lable_investment_saturn[]={0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0\
1422 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1423 ,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0
1424 ,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
1425 ,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1
1426 ,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1
1427 ,1,1,1,1,1,1,1,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1
1428 ,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0
1429 ,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0
1430 ,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1
1431 ,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0
1432 ,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1
1433 ,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1
1434 ,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0
1435 ,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0
1436 ,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,1,1,1,0,0,0,0
1437 ,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1
1438 ,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,0
1439 ,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0
1440 ,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0
1441 ,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0
1442 ,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1
1443 ,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1
1444 ,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1
1445 ,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0
1446 ,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1
1447 ,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1
1448 ,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1
1449 ,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0
1450 ,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0
1451 ,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1
1452 ,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0
1453 ,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1
1454 ,0,0,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1
1455 ,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0
1456 ,0,1,1,1,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0
1457 ,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1
1458 ,1,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0
14 Appendix A: Source Code Listings 400

1459 ,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1};
1460 xx=0; yy=0;
1461 for (int y=665;y<(665+20);++y)
1462 {
1463 for (int x=1197;x<(1197+81);x++) {
1464 if (lable_investment_saturn[get_index(xx,yy,81)] == 1) {
1465 image[get_index(x,y,width)]=color;
1466 }
1467 xx++;
1468 }
1469 yy++;
1470 xx=0;
1471 }
1472
1473 // 16_lable_investment_venus.png
1474 // 66 20
1475 // 336 705
1476 char lable_investment_venus[]={1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,\
1477 0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,
1478 1,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,
1479 1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,
1480 1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,
1481 1,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,
1482 0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,0,0,
1483 0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,
1484 1,1,1,0,0,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,
1485 0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,
1486 1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,
1487 1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,
1488 0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,
1489 1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,
1490 1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,
1491 1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,
1492 1,1,1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,
1493 0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0,0,
1494 0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,
1495 0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,
1496 0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,0,0,1,
1497 1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,
1498 1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,
1499 0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,
1500 0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,
1501 1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,
14 Appendix A: Source Code Listings 401

1502 0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,
1503 0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,
1504 0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,
1505 0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
1506 1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,
1507 0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0};
1508 xx=0; yy=0;
1509 for (int y=705;y<(705+20);++y)
1510 {
1511 for (int x=336;x<(336+66);x++) {
1512 if (lable_investment_venus[get_index(xx,yy,66)] == 1) {
1513 image[get_index(x,y,width)]=color;
1514 }
1515 xx++;
1516 }
1517 yy++;
1518 xx=0;
1519 }
1520 }
1521
1522 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
1523 height, std::string filename)
1524 {
1525 std::tuple<float, float, float> color;
1526 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);
1527 out << "P6" << std::endl << width << ' ' << height << std::endl << "255" << std::en\
1528 dl;
1529
1530 for (int i=0;i<(width*height);++i)
1531 {
1532 color=image[i];
1533 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*255.0f) << char(\
1534 std::get<2>(color)*255.0f);
1535 }
1536 out.close();
1537 }
1538
1539 int main()
1540 {
1541 std::vector<std::tuple<float, float, float>> image1;
1542 int width=1600,height=900;
1543
1544 image1.resize(calc_size(width,height));
14 Appendix A: Source Code Listings 402

1545
1546 generate_noise_image(image1, width, height);
1547
1548 std::cout << "saving: 16_draw_investment1.ppm." << std::endl;
1549 save_image(image1,width,height,"16_draw_investment1.ppm");
1550
1551 std::vector<std::tuple<float, float, float>> image2;
1552 image2.resize(calc_size(width,height));
1553
1554 std::tuple<float, float, float> fcolor=std::make_tuple(0.5294117647f,0.8235294118f,\
1555 0.8078431373f);
1556 std::tuple<float, float, float> tcolor=std::make_tuple(0.2588235294f,0.2196078431f,\
1557 0.3921568627f);
1558 generate_linear_gradient_image(image2,fcolor,tcolor,width,height);
1559
1560 std::cout << "saving: 16_draw_investment2.ppm." << std::endl;
1561 save_image(image2,width,height,"16_draw_investment2.ppm");
1562
1563 blended_two_images(image1,image2,width,height,0.9);
1564
1565 std::cout << "saving: 16_draw_investment3.ppm." << std::endl;
1566 save_image(image1,width,height,"16_draw_investment3.ppm");
1567
1568 // radial gradient
1569 std::vector<std::tuple<float, float, float>> image3;
1570 image3.resize(calc_size(900,900));
1571
1572 fcolor=std::make_tuple(1.0f,1.0f,1.0f);
1573 tcolor=std::make_tuple(0.0f,0.0f,0.0f);
1574
1575 generate_radial_gradient_image(image3,fcolor,tcolor,900,900);
1576
1577 std::cout << "saving: 16_draw_investment4.ppm." << std::endl;
1578 save_image(image3,900,900,"16_draw_investment4.ppm");
1579
1580 // Repeating texture generation
1581 std::vector<std::tuple<float, float, float>> image4;
1582 image4.resize(calc_size(73,65));
1583
1584 fcolor=std::make_tuple(0.5294117647f,0.8235294118f,0.8078431373f);
1585 generate_repeating_texture_image(image4,fcolor,73,65);
1586
1587 std::cout << "saving: 16_draw_investment5.ppm." << std::endl;
14 Appendix A: Source Code Listings 403

1588 save_image(image4,73,65,"16_draw_investment5.ppm");
1589
1590 // Render repeating texture
1591 std::vector<std::tuple<float, float, float>> image5;
1592 image5.resize(calc_size(900,900));
1593
1594 render_repeating_texture_image(image4,73,65,image5,900,900);
1595
1596 std::cout << "saving: 16_draw_investment6.ppm." << std::endl;
1597 save_image(image5,900,900,"16_draw_investment6.ppm");
1598
1599 // Do cookie cut
1600 std::vector<std::tuple<float, float, float>> image6;
1601 image6.resize(calc_size(900,900));
1602
1603 do_cookie_cut(image1,width,height,image6,900,900,350,0);
1604
1605 std::cout << "saving: 16_draw_investment7.ppm." << std::endl;
1606 save_image(image6,900,900,"16_draw_investment7.ppm");
1607
1608 // Add honeycomb
1609 add_honeycomb(image6,image3,image5,900,900);
1610
1611 std::cout << "saving: 16_draw_investment8.ppm." << std::endl;
1612 save_image(image6,900,900,"16_draw_investment8.ppm");
1613
1614 // Stamp cookie
1615 stamp_cookie(image1,width,height,image6,900,900,350,0);
1616
1617 std::cout << "saving: 16_draw_investment9.ppm." << std::endl;
1618 save_image(image1,width,height,"16_draw_investment9.ppm");
1619
1620 // Create Doughnut
1621 std::vector<std::tuple<float, float, float>> image7;
1622 std::tuple<int, int, int, int> coords;
1623 image7.resize(calc_size(width,height));
1624 fcolor=std::make_tuple(1.0f,0.0f,1.0f);
1625 clear_image(image7,fcolor,width,height);
1626 fcolor=std::make_tuple(1.0f,1.0f,1.0f);
1627 draw_filled_wedge(801,491,209,0,79,image7,fcolor,width,height);
1628 draw_filled_wedge(801,491,209,331,360,image7,fcolor,width,height);
1629 coords=std::make_tuple(988,412,1277,412);
1630 draw_line(image7,coords,fcolor,width,height);
14 Appendix A: Source Code Listings 404

1631 coords=std::make_tuple(988,413,1277,413);
1632 draw_line(image7,coords,fcolor,width,height);
1633 // fcolor=std::make_tuple(1.0f,0.0f,1.0f);
1634 // draw_filled_wedge(801,491,156,0,60,image7,fcolor,width,height);
1635 // draw_filled_wedge(801,491,156,312,360,image7,fcolor,width,height);
1636 fcolor=std::make_tuple(0.8f,0.8f,0.8f);
1637 draw_filled_wedge(801,491,200,79,223,image7,fcolor,width,height);
1638 coords=std::make_tuple(604,489,335,489);
1639 draw_line(image7,coords,fcolor,width,height);
1640 coords=std::make_tuple(604,490,335,490);
1641 draw_line(image7,coords,fcolor,width,height);
1642 // fcolor=std::make_tuple(1.0f,0.0f,1.0f);
1643 // draw_filled_wedge(801,491,156,60,204,image7,fcolor,width,height);
1644 fcolor=std::make_tuple(0.8509803922f,0.8509803922f,0.8509803922f);
1645 draw_filled_wedge(801,491,203,223,294,image7,fcolor,width,height);
1646 coords=std::make_tuple(737,679,335,679);
1647 draw_line(image7,coords,fcolor,width,height);
1648 coords=std::make_tuple(737,680,335,680);
1649 draw_line(image7,coords,fcolor,width,height);
1650 fcolor=std::make_tuple(0.9411764706f,0.9411764706f,0.9411764706f);
1651 draw_filled_wedge(801,491,206,294,331,image7,fcolor,width,height);
1652 coords=std::make_tuple(938,640,1277,640);
1653 draw_line(image7,coords,fcolor,width,height);
1654 coords=std::make_tuple(938,641,1277,641);
1655 draw_line(image7,coords,fcolor,width,height);
1656 fcolor=std::make_tuple(1.0f,0.0f,1.0f);
1657 draw_filled_circle(801,491,153,image7,fcolor,width,height);
1658
1659 fcolor=std::make_tuple(1.0f,1.0f,1.0f);
1660 draw_labels(image7,fcolor,width,height);
1661
1662 std::cout << "saving: 16_draw_investment10.ppm." << std::endl;
1663 save_image(image7,width,height,"16_draw_investment10.ppm");
1664
1665 // Add doughnut to image1
1666 fcolor=std::make_tuple(1.0f,0.0f,1.0f);
1667 for (int y=0;y<height;++y) {
1668 for (int x=0;x<width;++x) {
1669 if (image7[get_index(x,y,width)] != fcolor) {
1670 image1[get_index(x,y,width)]=image7[get_index(x,y,width)];
1671 }
1672 }
1673 }
14 Appendix A: Source Code Listings 405

1674
1675 std::cout << "saving: 16_draw_investment11.ppm." << std::endl;
1676 save_image(image1,width,height,"16_draw_investment11.ppm");
1677
1678 return 0;
1679 }

17_colab_peacock.cpp - 12051 bytes.

1 // Compile: clang++ -std=c++17 17_colab_peacock.cpp -o 17_colab_peacock


2 #define _USE_MATH_DEFINES
3
4 #include <iostream>
5 #include <fstream>
6 #include <tuple>
7 #include <vector>
8 #include <random>
9 #include <cmath>
10 #include <algorithm>
11
12 bool startsWithCaseInsensitive(std::string mainStr, std::string toMatch)
13 {
14 // Convert mainStr to lower case
15 std::transform(mainStr.begin(), mainStr.end(), mainStr.begin(), ::tolower);
16 // Convert toMatch to lower case
17 std::transform(toMatch.begin(), toMatch.end(), toMatch.begin(), ::tolower);
18 if(mainStr.find(toMatch) == 0)
19 return true;
20 else
21 return false;
22 }
23
24 int get_index(int x, int y, int width)
25 {
26 return x+width*y;
27 }
28
29 int calc_size(int width, int height)
30 {
31 return width*height;
32 }
33
34 void clear_image(std::vector<std::tuple<float, float, float>> &image, int width, int\
14 Appendix A: Source Code Listings 406

35 height)
36 {
37 for (int y=0;y<height;++y) {
38 for (int x=0;x<width;++x) {
39 image[get_index(x,y,width)]=std::make_tuple(0.0f, 0.0f, 0.0f);
40 }
41 }
42 }
43
44 void generate_noise_image(std::vector<std::tuple<float, float, float>> &image, int w\
45 idth, int height)
46 {
47 std::tuple<float, float, float> color;
48 float rndnum=0.0f;
49
50 std::random_device rd;
51 std::mt19937 mt(rd());
52 std::uniform_real_distribution<float> dist(0.0f, 1.0f);
53
54 for (int y=0;y<height;++y) {
55 for (int x=0;x<width;++x) {
56 rndnum=dist(mt);
57 color=std::make_tuple(rndnum,rndnum,rndnum);
58 image[get_index(x,y,width)]=color;
59 }
60 }
61 }
62
63 void generate_linear_gradient_image(std::vector<std::tuple<float, float, float>> &im\
64 age, std::tuple<float, float, float> &fcolor, std::tuple<float, float, float> &tcolo
65 r, int width, int height)
66 {
67 std::tuple<float, float, float> color;
68 double resultRed=0.0f;
69 double resultGreen=0.0f;
70 double resultBlue=0.0f;
71 double fr,fg,fb,tr,tg,tb;
72 double percent=0.0f;
73 std::tie(fr,fg,fb)=fcolor;
74 std::tie(tr,tg,tb)=tcolor;
75
76 for (int y=0;y<height;++y) {
77 percent=double(y)/double(height);
14 Appendix A: Source Code Listings 407

78 resultRed = fr + percent * (tr - fr);


79 resultGreen = fg + percent * (tg - fg);
80 resultBlue = fb + percent * (tb - fb);
81 color=std::make_tuple(resultRed,resultGreen,resultBlue);
82 for (int x=0;x<width;++x) {
83 image[get_index(x,y,width)]=color;
84 }
85 }
86 }
87
88 void blended_two_images(std::vector<std::tuple<float, float, float>> &blend1,std::ve\
89 ctor<std::tuple<float, float, float>> &blend2,int width,int height,float alpha)
90 {
91 std::tuple<float, float, float> color1=std::make_tuple(0.0f,0.0f,0.0f);
92 std::tuple<float, float, float> color2=std::make_tuple(0.0f,0.0f,0.0f);
93 float r=0.0f; float g=0.0f; float b=0.0f;
94
95 for (int y=0;y<height;++y) {
96 for (int x=0;x<width;++x) {
97 color1=blend1[get_index(x,y,width)];
98 color2=blend2[get_index(x,y,width)];
99 r = (std::get<0>(color2) * alpha) + (std::get<0>(color1) * (1.0f - alpha));
100 g = (std::get<1>(color2) * alpha) + (std::get<1>(color1) * (1.0f - alpha));
101 b = (std::get<2>(color2) * alpha) + (std::get<2>(color1) * (1.0f - alpha));
102 blend1[get_index(x,y,width)]=std::make_tuple(r, g, b);
103 }
104 }
105 }
106
107 void draw_line(std::vector<std::tuple<float, float, float>> &image, std::tuple<int, \
108 int, int, int> &coords, std::tuple<float,float,float> &color, int width, int height)
109 {
110 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(coords);\
111 int y2=std::get<3>(coords);
112 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
113 dx = x2 - x1; dy = y2 - y1;
114 if (dx == 0)
115 {
116 if (y2 < y1) std::swap(y1, y2);
117 for (y = y1; y <= y2; y++)
118 image[get_index(x1,y,width)]=color;
119 return;
120 }
14 Appendix A: Source Code Listings 408

121 if (dy == 0)
122 {
123 if (x2 < x1) std::swap(x1, x2);
124 for (x = x1; x <= x2; x++)
125 image[get_index(x,y1,width)]=color;
126 return;
127 }
128 dx1 = abs(dx); dy1 = abs(dy);
129 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
130 if (dy1 <= dx1)
131 {
132 if (dx >= 0)
133 {
134 x = x1; y = y1; xe = x2;
135 }
136 else
137 {
138 x = x2; y = y2; xe = x1;
139 }
140 image[get_index(x,y,width)]=color;
141 for (i = 0; x<xe; i++)
142 {
143 x = x + 1;
144 if (px<0)
145 px = px + 2 * dy1;
146 else
147 {
148 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; else y = y - 1;
149 px = px + 2 * (dy1 - dx1);
150 }
151 image[get_index(x,y,width)]=color;
152 }
153 }
154 else
155 {
156 if (dy >= 0)
157 {
158 x = x1; y = y1; ye = y2;
159 }
160 else
161 {
162 x = x2; y = y2; ye = y1;
163 }
14 Appendix A: Source Code Listings 409

164 image[get_index(x,y,width)]=color;
165 for (i = 0; y<ye; i++)
166 {
167 y = y + 1;
168 if (py <= 0)
169 py = py + 2 * dx1;
170 else
171 {
172 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; else x = x - 1;
173 py = py + 2 * (dx1 - dy1);
174 }
175 image[get_index(x,y,width)]=color;
176 }
177 }
178 }
179
180 int find_region(int x, int y, int width, int height)
181 {
182 int code=0;
183 if(y >= height)
184 code |= 1; //top
185 else if(y < 0)
186 code |= 2; //bottom
187 if(x >= width)
188 code |= 4; //right
189 else if (x < 0)
190 code |= 8; //left
191 return(code);
192 }
193
194 bool clip_line(std::tuple<int, int, int, int> &coords1, std::tuple<int, int, int, in\
195 t> &coords2, int width, int height)
196 {
197 int x1=std::get<0>(coords1); int y1=std::get<1>(coords1); int x2=std::get<2>(coords\
198 1); int y2=std::get<3>(coords1);
199 int x3=0; int y3=0; int x4=0; int y4=0;
200 int code1=0, code2=0, codeout=0;
201 bool accept = 0, done=0;
202 code1 = find_region(x1, y1, width, height); //the region outcodes for the endpoints
203 code2 = find_region(x2, y2, width, height);
204 do //In theory, this can never end up in an infinite loop, it'll always come in one\
205 of the trivial cases eventually
206 {
14 Appendix A: Source Code Listings 410

207 if(!(code1 | code2)) accept = done = 1; //accept because both endpoints are in sc\
208 reen or on the border, trivial accept
209 else if(code1 & code2) done = 1; //the line isn't visible on screen, trivial reject
210 else //if no trivial reject or accept, continue the loop
211 {
212 int x, y;
213 codeout = code1 ? code1 : code2;
214 if(codeout & 1) //top
215 {
216 x = x1 + (x2 - x1) * (height - y1) / (y2 - y1);
217 y = height - 1;
218 }
219 else if(codeout & 2) //bottom
220 {
221 x = x1 + (x2 - x1) * -y1 / (y2 - y1);
222 y = 0;
223 }
224 else if(codeout & 4) //right
225 {
226 y = y1 + (y2 - y1) * (width - x1) / (x2 - x1);
227 x = width - 1;
228 }
229 else //left
230 {
231 y = y1 + (y2 - y1) * -x1 / (x2 - x1);
232 x = 0;
233 }
234 if(codeout == code1) //first endpoint was clipped
235 {
236 x1 = x; y1 = y;
237 code1 = find_region(x1, y1, width, height);
238 }
239 else //second endpoint was clipped
240 {
241 x2 = x; y2 = y;
242 code2 = find_region(x2, y2, width, height);
243 }
244 }
245 }
246 while(done == 0);
247 if(accept)
248 {
249 x3 = x1;
14 Appendix A: Source Code Listings 411

250 x4 = x2;
251 y3 = y1;
252 y4 = y2;
253 coords2=std::make_tuple(x3,y3,x4,y4);
254 return 1;
255 }
256 else
257 {
258 x3 = x4 = y3 = y4 = 0;
259 coords2=std::make_tuple(x3,y3,x4,y4);
260 return 0;
261 }
262 }
263
264 void get_angle_line(std::tuple<int, int, int, int> &coords,int x_cen,int y_cen,doubl\
265 e degrees,int length)
266 {
267 double angle = degrees * (M_PI / 180);
268 coords=std::make_tuple(x_cen,y_cen,int(double(x_cen) + cos(angle)*double(length)),i\
269 nt(double(y_cen) + sin(angle)*double(length)));
270 }
271
272 void save_image(std::vector<std::tuple<float, float, float>> &image, int width, int \
273 height, std::string filename)
274 {
275 std::tuple<float, float, float> color;
276 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);
277 out << "P6" << std::endl << width << ' ' << height << std::endl << "255" << std::en\
278 dl;
279
280 for (int i=0;i<(width*height);++i)
281 {
282 color=image[i];
283 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*255.0f) << char(\
284 std::get<2>(color)*255.0f);
285 }
286 out.close();
287 }
288
289 void draw(std::vector<std::tuple<float, float, float>> &image,std::tuple<int, int, i\
290 nt, int> &coords,std::vector<std::tuple<float,float,float>> &colors,int width,int he
291 ight,int x_cen,int y_cen,double degrees,int length,int color)
292 {
14 Appendix A: Source Code Listings 412

293 get_angle_line(coords,x_cen,y_cen,degrees,length);
294 if (clip_line(coords,coords,width,height)) {
295 draw_line(image,coords,colors[color],width,height);
296 }
297 std::cout << "L " << std::get<0>(coords) << " " << std::get<1>(coords) << " " << st\
298 d::get<2>(coords) << " " << std::get<3>(coords) << " " << color << std::endl;
299 }
300
301 void parse_draw_line_from_file(const std::string str,std::vector<std::tuple<float, f\
302 loat, float>> &image,std::vector<std::tuple<float,float,float>> &colors,int width,in
303 t height)
304 {
305 size_t start;
306 size_t end = 0;
307 std::vector<std::string> out;
308
309 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
310 {
311 end = str.find(' ', start);
312 out.push_back(str.substr(start, end - start));
313 }
314
315 std::tuple<int, int, int, int> coords=std::make_tuple(stoi(out[1]),stoi(out[2]),sto\
316 i(out[3]),stoi(out[4]));
317 draw_line(image,coords,colors[stoi(out[5])],width,height);
318 }
319
320 void parse_draw_marker_from_file(const std::string str,std::vector<std::tuple<float,\
321 float, float>> &image,std::vector<std::tuple<float,float,float>> &colors,int width,
322 int height)
323 {
324 size_t start;
325 size_t end = 0;
326 std::vector<std::string> out;
327
328 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
329 {
330 end = str.find(' ', start);
331 out.push_back(str.substr(start, end - start));
332 }
333
334 int x=stoi(out[1]),y=stoi(out[2]),color=stoi(out[3]);
335
14 Appendix A: Source Code Listings 413

336 // Draw Marker


337 image[get_index(x-1,y-1,width)]=colors[color];
338 image[get_index(x,y-1,width)]=colors[color];
339 image[get_index(x+1,y-1,width)]=colors[color];
340 image[get_index(x+1,y,width)]=colors[color];
341 image[get_index(x+1,y+1,width)]=colors[color];
342 image[get_index(x,y+1,width)]=colors[color];
343 image[get_index(x-1,y+1,width)]=colors[color];
344 image[get_index(x-1,y,width)]=colors[color];
345 image[get_index(x,y,width)]=colors[color];
346 }
347
348 void parse_draw_spot_from_file(const std::string str,std::vector<std::tuple<float, f\
349 loat, float>> &image,std::vector<std::tuple<float,float,float>> &colors,int width,in
350 t height)
351 {
352 size_t start;
353 size_t end = 0;
354 int radius=5;
355 std::vector<std::string> out;
356
357 while ((start = str.find_first_not_of(' ', end)) != std::string::npos)
358 {
359 end = str.find(' ', start);
360 out.push_back(str.substr(start, end - start));
361 }
362
363 int x=stoi(out[1]),y=stoi(out[2]),color=stoi(out[3]);
364
365 int x0 = 0;
366 int y0 = radius;
367 int d = 3 - 2 * radius;
368 if (!radius) return;
369
370 auto drawline = [&](int sx, int ex, int ny)
371 {
372 for (int i = sx; i <= ex; i++)
373 image[get_index(i, ny, width)]=colors[color];
374 };
375
376 while (y0 >= x0)
377 {
378 drawline(x - x0, x + x0, y - y0);
14 Appendix A: Source Code Listings 414

379 drawline(x - y0, x + y0, y - x0);


380 drawline(x - x0, x + x0, y + y0);
381 drawline(x - y0, x + y0, y + x0);
382 if (d < 0) d += 4 * x0++ + 6;
383 else d += 4 * (x0++ - y0--) + 10;
384 }
385 }
386
387 int main()
388 {
389 std::vector<std::tuple<float, float, float>> image;
390 std::vector<std::tuple<float, float, float>> image2;
391 std::tuple<int, int, int, int> coords;
392 std::vector<std::tuple<float,float,float>> colors;
393 colors.push_back(std::make_tuple(0.5f,0.5f,0.5f));// Medium Grey
394 colors.push_back(std::make_tuple(0.862745098f,0.862745098f,0.862745098f));// Red
395 colors.push_back(std::make_tuple(1.0f,1.0f,1.0f));// Black
396 colors.push_back(std::make_tuple(0.7f,0.7f,0.7f));// Blue
397 colors.push_back(std::make_tuple(0.6f,0.6f,0.6f));// Purple
398 colors.push_back(std::make_tuple(0.2f,0.2f,0.2f));// Light Green
399 colors.push_back(std::make_tuple(0.1f,0.1f,0.1f));// Green
400 colors.push_back(std::make_tuple(0.4f,0.4f,0.4f));// Cyan
401 float deg=0.0;
402 int len=0,len2=0;
403
404 int width=1600;int height=900;
405
406 image.resize(calc_size(width, height));
407 image2.resize(calc_size(width, height));
408
409 generate_noise_image(image, width, height);
410
411 std::tuple<float, float, float> fcolor=std::make_tuple(0.05882352941f,0.0862745098f\
412 ,0.1254901961f);
413 std::tuple<float, float, float> tcolor=std::make_tuple(0.2156862745f,0.3019607843f,\
414 0.3490196078f);
415 generate_linear_gradient_image(image2,fcolor,tcolor,width,height);
416
417 blended_two_images(image,image2,width,height,0.9);
418
419 // read 17_colab.txt and draw it
420 std::ifstream infile("17_colab_peacock.txt");
421 std::string line;
14 Appendix A: Source Code Listings 415

422 while (getline(infile, line))


423 {
424 if (startsWithCaseInsensitive(line,"L")) {
425 parse_draw_line_from_file(line,image,colors,width,height);
426 }
427 if (startsWithCaseInsensitive(line,"M")) {
428 parse_draw_marker_from_file(line,image,colors,width,height);
429 }
430 if (startsWithCaseInsensitive(line,"S")) {
431 parse_draw_spot_from_file(line,image,colors,width,height);
432 }
433 }
434 infile.close();
435
436 save_image(image,width,height,"17_colab_peacock.ppm");
437 return 0;
438 }

17_colab_peacock.txt - 15936 bytes.

1 L 1321 223 1202 151 0


2 L 1321 223 1416 160 0
3 L 1321 223 1304 335 0
4 L 1321 223 1247 198 0
5 L 1321 223 1372 280 0
6 L 1321 223 1310 271 0
7 L 1321 223 1368 238 0
8 L 1321 223 1363 189 0
9 L 1321 223 1369 256 0
10 L 1321 223 1330 337 0
11 L 1321 223 1333 129 0
12 L 1321 223 1452 226 0
13 L 1321 223 1234 195 0
14 L 1321 223 1251 194 0
15 L 1321 223 1259 149 0
16 L 1321 223 1239 178 0
17 L 1321 223 1360 306 0
18 L 1321 223 1354 171 0
19 L 1321 223 1255 282 0
20 L 1321 223 1429 218 0
21 L 1321 223 1287 175 0
22 L 1321 223 1345 285 0
23 L 1321 223 1303 145 0
14 Appendix A: Source Code Listings 416

24 L 1321 223 1452 264 0


25 L 1321 223 1256 241 0
26 L 1321 223 1403 196 0
27 L 1321 223 1315 290 0
28 L 1321 223 1258 271 0
29 L 1321 223 1426 215 0
30 L 1321 223 1325 168 0
31 L 1321 223 1415 260 0
32 L 1321 223 1331 280 0
33 L 1321 223 1361 129 0
34 L 1321 223 1262 223 0
35 L 1321 223 1433 290 0
36 L 1321 223 1320 283 0
37 L 1321 223 1290 358 0
38 L 1321 223 1323 164 0
39 L 1321 223 1423 283 0
40 L 1321 223 1342 308 0
41 L 1321 223 1309 305 0
42 L 1321 223 1243 113 0
43 L 1321 223 1295 305 0
44 L 1321 223 1410 204 0
45 L 1321 223 1271 81 0
46 L 1321 223 1385 201 0
47 L 1321 223 1333 306 0
48 L 1321 223 1419 306 0
49 L 1321 223 1262 257 0
50 L 1321 223 1380 269 0
51 L 1321 223 1260 256 0
52 L 1321 223 1295 270 0
53 L 1321 223 1258 87 0
54 L 1321 223 1246 190 0
55 L 1321 223 1292 112 0
56 L 1321 223 1393 202 0
57 L 1321 223 1461 246 0
58 L 1321 223 1393 293 0
59 L 1321 223 1239 261 0
60 L 1321 223 1408 297 0
61 L 1321 223 1325 302 0
62 L 1321 223 1435 258 0
63 L 1321 223 1379 216 0
64 L 1321 223 1326 280 0
65 L 1321 223 1356 187 0
66 L 1321 223 1348 367 0
14 Appendix A: Source Code Listings 417

67 L 1321 223 1407 193 0


68 L 1321 223 1247 203 0
69 L 1321 223 1343 293 0
70 L 1321 223 1445 293 0
71 L 1321 223 1285 350 0
72 L 1321 223 1240 182 0
73 L 1321 223 1452 182 0
74 L 1321 223 1354 272 0
75 L 1321 223 1247 147 0
76 L 1321 223 1300 279 0
77 L 1321 223 1312 139 0
78 L 1321 223 1290 282 0
79 L 1321 223 1403 218 0
80 L 1321 223 1420 125 0
81 L 1321 223 1385 114 0
82 L 1321 223 1398 203 0
83 L 1321 223 1406 177 0
84 L 1321 223 1232 255 0
85 L 1321 223 1396 338 0
86 L 1321 223 1378 332 0
87 L 1321 223 1443 198 0
88 L 1321 223 1369 319 0
89 L 1321 223 1246 168 0
90 L 1321 223 1267 241 0
91 L 1321 223 1273 95 0
92 L 1321 223 1325 297 0
93 L 1321 223 1290 348 0
94 L 1321 223 1269 251 0
95 L 1321 223 1390 301 0
96 L 1321 223 1236 219 0
97 L 1321 223 1399 250 0
98 L 1321 223 1388 236 0
99 L 1321 223 1236 219 0
100 L 1321 223 1268 207 1
101 L 1321 223 1002 211 1
102 L 1321 223 1026 224 1
103 L 1321 223 1014 247 0
104 L 1321 223 1037 260 1
105 L 1321 223 1025 277 1
106 L 1321 223 1009 307 1
107 L 1321 223 1200 370 0
108 L 1321 223 1264 405 0
109 L 721 297 730 370 0
14 Appendix A: Source Code Listings 418

110 L 721 297 778 343 0


111 L 721 297 738 343 0
112 L 721 297 773 283 0
113 L 721 297 724 382 0
114 L 721 297 660 407 0
115 L 721 297 699 238 0
116 L 721 297 771 286 0
117 L 721 297 692 442 0
118 L 721 297 649 239 0
119 L 721 297 754 390 0
120 L 721 297 718 410 0
121 L 721 297 699 379 0
122 L 721 297 780 334 0
123 L 721 297 614 343 0
124 L 721 297 688 441 0
125 L 721 297 628 216 0
126 L 721 297 811 303 0
127 L 721 297 768 239 0
128 L 721 297 795 253 0
129 L 721 297 813 327 0
130 L 721 297 777 290 0
131 L 721 297 667 289 0
132 L 721 297 728 349 0
133 L 721 297 653 346 0
134 L 721 297 751 213 0
135 L 721 297 792 350 0
136 L 721 297 808 289 0
137 L 721 297 811 290 0
138 L 721 297 809 259 0
139 L 721 297 493 308 0
140 L 721 297 707 354 0
141 L 721 297 719 167 0
142 L 721 297 655 418 0
143 L 721 297 593 317 0
144 L 721 297 789 294 0
145 L 721 297 801 260 0
146 L 721 297 775 284 0
147 L 721 297 618 325 0
148 L 721 297 631 312 0
149 L 721 297 695 212 0
150 L 721 297 809 344 0
151 L 721 297 665 191 0
152 L 721 297 755 237 0
14 Appendix A: Source Code Listings 419

153 L 721 297 802 298 0


154 L 721 297 684 364 0
155 L 721 297 744 392 0
156 L 721 297 706 375 0
157 L 721 297 756 362 0
158 L 721 297 780 346 0
159 L 721 297 791 357 0
160 L 721 297 671 276 0
161 L 721 297 646 184 0
162 L 721 297 719 405 0
163 L 721 297 687 414 0
164 L 721 297 642 256 0
165 L 721 297 730 217 0
166 L 721 297 790 273 0
167 L 721 297 623 313 0
168 L 721 297 766 225 0
169 L 721 297 658 388 0
170 L 721 297 701 358 0
171 L 721 297 661 266 0
172 L 721 297 677 327 0
173 L 721 297 629 320 0
174 L 721 297 781 278 0
175 L 721 297 795 237 0
176 L 721 297 776 233 0
177 L 721 297 792 228 0
178 L 721 297 661 301 0
179 L 721 297 758 352 0
180 L 721 297 744 372 0
181 L 721 297 780 369 0
182 L 721 297 745 345 0
183 L 721 297 618 266 0
184 L 721 297 730 243 0
185 L 721 297 707 242 0
186 L 721 297 815 285 0
187 L 721 297 669 292 0
188 L 721 297 724 362 0
189 L 721 297 758 252 0
190 L 721 297 701 246 0
191 L 721 297 672 373 0
192 L 721 297 702 153 0
193 L 721 297 739 226 0
194 L 721 297 757 372 0
195 L 721 297 636 201 0
14 Appendix A: Source Code Listings 420

196 L 721 297 697 402 0


197 L 721 297 799 307 0
198 L 721 297 759 244 0
199 L 721 297 665 191 0
200 L 721 297 803 353 0
201 L 721 297 750 235 0
202 L 721 297 753 387 0
203 L 721 297 589 368 0
204 L 721 297 662 405 0
205 L 721 297 748 391 0
206 L 721 297 729 226 0
207 L 721 297 758 264 0
208 L 721 297 801 277 0
209 L 721 297 1002 211 0
210 L 721 297 1026 224 0
211 L 721 297 1014 247 1
212 L 721 297 1037 260 0
213 L 721 297 1025 277 0
214 L 721 297 1009 307 0
215 L 721 297 879 423 0
216 L 721 297 866 439 0
217 L 721 297 844 458 0
218 L 1091 592 758 623 0
219 L 1091 592 1010 739 0
220 L 1091 592 1160 722 0
221 L 1091 592 904 523 0
222 L 1091 592 1031 705 0
223 L 1091 592 1314 673 0
224 L 1091 592 1220 489 0
225 L 1091 592 1048 740 0
226 L 1091 592 920 542 0
227 L 1091 592 985 465 0
228 L 1091 592 1125 784 1
229 L 1091 592 1137 465 0
230 L 1091 592 1136 762 0
231 L 1091 592 802 661 0
232 L 1091 592 977 674 0
233 L 1091 592 1031 737 0
234 L 1091 592 1000 691 0
235 L 1091 592 1077 744 0
236 L 1091 592 967 498 0
237 L 1091 592 906 514 0
238 L 1091 592 1042 752 0
14 Appendix A: Source Code Listings 421

239 L 1091 592 1036 737 0


240 L 1091 592 1001 457 0
241 L 1091 592 1145 775 0
242 L 1091 592 1200 621 0
243 L 1091 592 945 553 0
244 L 1091 592 1169 472 0
245 L 1091 592 922 605 0
246 L 1091 592 1245 623 0
247 L 1091 592 1036 747 0
248 L 1091 592 1216 563 0
249 L 1091 592 1217 710 0
250 L 1091 592 993 623 0
251 L 1091 592 974 554 0
252 L 1091 592 1156 501 0
253 L 1091 592 1242 481 0
254 L 1091 592 1003 441 0
255 L 1091 592 1218 471 0
256 L 1091 592 1312 602 0
257 L 1091 592 1196 535 0
258 L 1091 592 1171 653 0
259 L 1091 592 956 606 0
260 L 1091 592 1137 471 0
261 L 1091 592 1222 722 0
262 L 1091 592 936 508 0
263 L 1091 592 1094 445 0
264 L 1091 592 979 701 0
265 L 1091 592 1086 395 0
266 L 1091 592 961 573 0
267 L 1091 592 1159 709 0
268 L 1091 592 961 645 0
269 L 1091 592 936 473 0
270 L 1091 592 992 647 0
271 L 1091 592 1222 718 0
272 L 1091 592 1270 534 0
273 L 1091 592 974 558 0
274 L 1091 592 1071 407 0
275 L 1091 592 913 665 0
276 L 1091 592 1131 702 0
277 L 1091 592 1020 493 0
278 L 1091 592 1152 728 0
279 L 1091 592 1003 444 0
280 L 1091 592 1049 724 0
281 L 1091 592 1196 577 0
14 Appendix A: Source Code Listings 422

282 L 1091 592 979 668 0


283 L 1091 592 1209 680 0
284 L 1091 592 1156 692 0
285 L 1091 592 1276 638 0
286 L 1091 592 916 558 0
287 L 1091 592 1211 461 0
288 L 1091 592 999 660 0
289 L 1091 592 930 575 0
290 L 1091 592 1138 454 0
291 L 1091 592 1198 573 0
292 L 1091 592 1221 538 0
293 L 1091 592 1152 468 0
294 L 1091 592 1172 530 0
295 L 1091 592 1024 448 0
296 L 1091 592 1131 473 0
297 L 1091 592 1035 414 0
298 L 1091 592 1122 460 0
299 L 1091 592 974 731 0
300 L 1091 592 974 449 0
301 L 1091 592 1010 711 0
302 L 1091 592 1109 450 0
303 L 1091 592 1135 502 0
304 L 1091 592 1073 725 0
305 L 1091 592 1226 555 0
306 L 1091 592 957 701 0
307 L 1091 592 1277 568 0
308 L 1091 592 1002 520 0
309 L 1091 592 1139 766 0
310 L 1091 592 1029 692 0
311 L 1091 592 1157 675 0
312 L 1091 592 1156 448 0
313 L 1091 592 1148 704 0
314 L 1091 592 1272 552 0
315 L 1091 592 1183 473 0
316 L 1091 592 1024 701 0
317 L 1091 592 1067 425 0
318 L 1091 592 1200 370 1
319 L 1091 592 1264 405 1
320 L 1091 592 879 423 1
321 L 1091 592 866 439 1
322 L 1091 592 844 458 1
323 L 1196 535 1385 449 1
324 L 1385 449 1515 391 0
14 Appendix A: Source Code Listings 423

325 L 1312 602 1355 604 1


326 L 1355 604 1398 565 0
327 L 1355 604 1414 596 0
328 L 1355 604 1414 618 0
329 L 1355 604 1398 647 0
330 L 1091 592 1314 673 0
331 L 1314 673 1376 660 3
332 L 1314 673 1368 691 1
333 L 1314 673 1339 720 4
334 L 1091 592 1160 637 0
335 L 1160 637 1214 672 1
336 L 1214 672 1257 700 0
337 L 1222 718 1249 741 1
338 L 1249 741 1305 750 0
339 L 1249 741 1253 802 0
340 L 1125 784 1128 863 0
341 L 1136 762 1158 845 1
342 L 1145 775 1168 841 1
343 L 1091 592 831 618 1
344 L 1091 592 876 573 1
345 L 1091 592 816 534 1
346 L 1091 592 808 702 1
347 L 876 573 584 551 0
348 L 831 618 544 683 4
349 L 808 702 544 683 0
350 L 802 661 544 683 1
351 L 816 534 538 515 0
352 L 758 623 694 731 1
353 L 802 661 584 551 3
354 L 831 618 584 551 0
355 L 831 618 756 580 3
356 L 758 623 356 623 3
357 L 758 623 356 623 3
358 L 493 308 426 442 4
359 L 493 308 437 290 1
360 L 493 308 387 243 4
361 L 387 243 316 198 0
362 L 493 308 440 214 3
363 L 440 214 399 137 0
364 L 426 442 406 413 0
365 L 426 442 379 404 0
366 L 426 442 366 434 0
367 L 426 442 393 451 0
14 Appendix A: Source Code Listings 424

368 L 426 442 314 522 1


369 L 314 522 277 598 0
370 L 314 522 355 589 3
371 L 355 589 325 604 1
372 L 325 604 356 623 0
373 L 277 598 285 624 4
374 L 426 442 511 470 0
375 L 511 470 570 442 4
376 L 570 442 721 297 0
377 L 570 442 422 549 7
378 L 422 549 402 509 5
379 L 422 549 326 574 6
380 L 326 574 232 574 0
381 L 422 549 538 515 4
382 L 538 515 491 508 0
383 L 538 515 476 486 0
384 L 538 515 522 483 0
385 L 285 624 189 692 3
386 L 189 692 162 705 0
387 L 356 623 315 654 0
388 L 356 623 342 663 0
389 L 356 623 383 658 1
390 L 356 623 307 635 0
391 L 356 623 407 654 0
392 L 356 623 420 646 0
393 L 356 623 442 641 0
394 L 544 683 407 654 1
395 L 544 683 420 646 1
396 L 544 683 442 641 1
397 L 422 549 369 593 0
398 L 369 593 266 673 0
399 L 266 673 224 732 0
400 L 224 732 154 790 1
401 L 154 790 110 814 0
402 L 266 673 245 709 0
403 L 266 673 236 679 0
404 L 422 549 415 594 1
405 L 415 594 383 658 0
406 L 422 549 356 623 3
407 L 422 549 544 683 3
408 L 538 515 503 597 0
409 L 503 597 544 683 3
410 L 503 597 584 551 4
14 Appendix A: Source Code Listings 425

411 L 426 442 509 460 0


412 L 509 460 584 551 1
413 L 356 623 275 768 0
414 L 275 768 226 803 4
415 L 226 803 185 828 0
416 L 275 768 218 846 3
417 L 218 846 145 883 0
418 L 356 623 309 643 0
419 L 356 623 292 645 0
420 L 356 623 359 685 0
421 L 356 623 387 614 1
422 L 356 623 427 646 0
423 L 356 623 288 648 0
424 L 356 623 299 658 3
425 L 356 623 392 581 3
426 L 356 623 327 554 0
427 L 356 623 330 639 0
428 L 356 623 325 643 1
429 L 356 623 327 637 0
430 L 356 623 283 628 0
431 L 356 623 338 668 0
432 L 356 623 402 659 0
433 L 356 623 337 661 4
434 L 356 623 317 600 3
435 L 356 623 382 613 0
436 L 356 623 340 649 0
437 L 356 623 349 557 0
438 L 356 623 353 694 1
439 L 356 623 320 616 0
440 L 356 623 376 640 0
441 L 356 623 372 562 3
442 L 356 623 351 598 0
443 L 426 442 492 496 0
444 L 426 442 414 545 0
445 L 426 442 494 392 4
446 L 426 442 367 492 0
447 L 426 442 407 527 0
448 L 426 442 371 510 3
449 L 426 442 357 409 1
450 L 426 442 359 518 0
451 L 426 442 501 445 0
452 L 426 442 356 382 3
453 L 426 442 332 489 0
14 Appendix A: Source Code Listings 426

454 L 426 442 376 535 0


455 L 426 442 328 386 0
456 L 426 442 341 452 0
457 L 426 442 328 470 4
458 L 426 442 440 524 0
459 L 426 442 317 457 0
460 L 426 442 327 397 0
461 L 426 442 524 443 3
462 L 426 442 490 351 0
463 L 426 442 419 537 0
464 L 426 442 330 482 1
465 L 426 442 320 401 1
466 L 426 442 334 462 1
467 L 426 442 539 421 1
468 L 426 442 336 513 0
469 L 426 442 448 526 0
470 L 426 442 435 536 0
471 L 426 442 312 449 0
472 L 426 442 369 520 0
473 L 426 442 329 480 3
474 L 426 442 504 379 0
475 L 426 442 466 540 0
476 L 426 442 357 512 0
477 L 426 442 484 505 0
478 L 426 442 346 523 3
479 L 426 442 371 360 4
480 L 426 442 433 346 0
481 L 426 442 524 466 0
482 L 426 442 500 358 1
483 L 426 442 530 447 1
484 L 426 442 482 501 1
485 L 426 442 320 441 0
486 L 426 442 506 445 3
487 L 426 442 519 384 0
488 M 1202 151 2
489 M 1416 160 2
490 M 1304 335 2
491 M 1247 198 2
492 M 1372 280 2
493 M 1310 271 2
494 M 1368 238 2
495 M 1363 189 2
496 M 1369 256 2
14 Appendix A: Source Code Listings 427

497 M 1330 337 2


498 M 1333 129 2
499 M 1452 226 2
500 M 1234 195 2
501 M 1251 194 2
502 M 1259 149 2
503 M 1239 178 2
504 M 1360 306 2
505 M 1354 171 2
506 M 1255 282 2
507 M 1429 218 2
508 M 1287 175 2
509 M 1345 285 2
510 M 1303 145 2
511 M 1452 264 2
512 M 1256 241 2
513 M 1403 196 2
514 M 1315 290 2
515 M 1258 271 2
516 M 1426 215 2
517 M 1325 168 2
518 M 1415 260 2
519 M 1331 280 2
520 M 1361 129 2
521 M 1262 223 2
522 M 1433 290 2
523 M 1320 283 2
524 M 1290 358 2
525 M 1323 164 2
526 M 1423 283 2
527 M 1342 308 2
528 M 1309 305 2
529 M 1243 113 2
530 M 1295 305 2
531 M 1410 204 2
532 M 1271 81 2
533 M 1385 201 2
534 M 1333 306 2
535 M 1419 306 2
536 M 1262 257 2
537 M 1380 269 2
538 M 1260 256 2
539 M 1295 270 2
14 Appendix A: Source Code Listings 428

540 M 1258 87 2
541 M 1246 190 2
542 M 1292 112 2
543 M 1393 202 2
544 M 1461 246 2
545 M 1393 293 2
546 M 1239 261 2
547 M 1408 297 2
548 M 1325 302 2
549 M 1435 258 2
550 M 1379 216 2
551 M 1326 280 2
552 M 1356 187 2
553 M 1348 367 2
554 M 1407 193 2
555 M 1247 203 2
556 M 1343 293 2
557 M 1445 293 2
558 M 1285 350 2
559 M 1240 182 2
560 M 1452 182 2
561 M 1354 272 2
562 M 1247 147 2
563 M 1300 279 2
564 M 1312 139 2
565 M 1290 282 2
566 M 1403 218 2
567 M 1420 125 2
568 M 1385 114 2
569 M 1398 203 2
570 M 1406 177 2
571 M 1232 255 2
572 M 1396 338 2
573 M 1378 332 2
574 M 1443 198 2
575 M 1369 319 2
576 M 1246 168 2
577 M 1267 241 2
578 M 1273 95 2
579 M 1325 297 2
580 M 1290 348 2
581 M 1269 251 2
582 M 1390 301 2
14 Appendix A: Source Code Listings 429

583 M 1236 219 2


584 M 1399 250 2
585 M 1388 236 2
586 M 1236 219 2
587 M 1268 207 2
588 M 1002 211 2
589 M 1026 224 2
590 M 1014 247 2
591 M 1037 260 2
592 M 1025 277 2
593 M 1009 307 2
594 M 730 370 2
595 M 778 343 2
596 M 738 343 2
597 M 773 283 2
598 M 724 382 2
599 M 660 407 2
600 M 699 238 2
601 M 771 286 2
602 M 692 442 2
603 M 649 239 2
604 M 754 390 2
605 M 718 410 2
606 M 699 379 2
607 M 780 334 2
608 M 614 343 2
609 M 688 441 2
610 M 628 216 2
611 M 811 303 2
612 M 768 239 2
613 M 795 253 2
614 M 813 327 2
615 M 777 290 2
616 M 667 289 2
617 M 728 349 2
618 M 653 346 2
619 M 751 213 2
620 M 792 350 2
621 M 808 289 2
622 M 811 290 2
623 M 809 259 2
624 M 493 308 2
625 M 707 354 2
14 Appendix A: Source Code Listings 430

626 M 719 167 2


627 M 655 418 2
628 M 593 317 2
629 M 789 294 2
630 M 801 260 2
631 M 775 284 2
632 M 618 325 2
633 M 631 312 2
634 M 695 212 2
635 M 809 344 2
636 M 665 191 2
637 M 755 237 2
638 M 802 298 2
639 M 684 364 2
640 M 744 392 2
641 M 706 375 2
642 M 756 362 2
643 M 780 346 2
644 M 791 357 2
645 M 671 276 2
646 M 646 184 2
647 M 719 405 2
648 M 687 414 2
649 M 642 256 2
650 M 730 217 2
651 M 790 273 2
652 M 623 313 2
653 M 766 225 2
654 M 658 388 2
655 M 701 358 2
656 M 661 266 2
657 M 677 327 2
658 M 629 320 2
659 M 781 278 2
660 M 795 237 2
661 M 776 233 2
662 M 792 228 2
663 M 661 301 2
664 M 758 352 2
665 M 744 372 2
666 M 780 369 2
667 M 745 345 2
668 M 618 266 2
14 Appendix A: Source Code Listings 431

669 M 730 243 2


670 M 707 242 2
671 M 815 285 2
672 M 669 292 2
673 M 724 362 2
674 M 758 252 2
675 M 701 246 2
676 M 672 373 2
677 M 702 153 2
678 M 739 226 2
679 M 757 372 2
680 M 636 201 2
681 M 697 402 2
682 M 799 307 2
683 M 759 244 2
684 M 665 191 2
685 M 803 353 2
686 M 750 235 2
687 M 753 387 2
688 M 589 368 2
689 M 662 405 2
690 M 748 391 2
691 M 729 226 2
692 M 758 264 2
693 M 801 277 2
694 M 758 623 2
695 M 1010 739 2
696 M 1160 722 2
697 M 904 523 2
698 M 1031 705 2
699 M 1314 673 2
700 M 1220 489 2
701 M 1048 740 2
702 M 920 542 2
703 M 985 465 2
704 M 1125 784 2
705 M 1137 465 2
706 M 1136 762 2
707 M 802 661 2
708 M 977 674 2
709 M 1031 737 2
710 M 1000 691 2
711 M 1077 744 2
14 Appendix A: Source Code Listings 432

712 M 967 498 2


713 M 906 514 2
714 M 1042 752 2
715 M 1036 737 2
716 M 1001 457 2
717 M 1145 775 2
718 M 1200 621 2
719 M 945 553 2
720 M 1169 472 2
721 M 922 605 2
722 M 1245 623 2
723 M 1036 747 2
724 M 1216 563 2
725 M 1217 710 2
726 M 993 623 2
727 M 974 554 2
728 M 1156 501 2
729 M 1242 481 2
730 M 1003 441 2
731 M 1218 471 2
732 M 1312 602 2
733 M 1196 535 2
734 M 1171 653 2
735 M 956 606 2
736 M 1137 471 2
737 M 1222 722 2
738 M 936 508 2
739 M 1094 445 2
740 M 979 701 2
741 M 1086 395 2
742 M 961 573 2
743 M 1159 709 2
744 M 961 645 2
745 M 936 473 2
746 M 992 647 2
747 M 1222 718 2
748 M 1270 534 2
749 M 974 558 2
750 M 1071 407 2
751 M 913 665 2
752 M 1131 702 2
753 M 1020 493 2
754 M 1152 728 2
14 Appendix A: Source Code Listings 433

755 M 1003 444 2


756 M 1049 724 2
757 M 1196 577 2
758 M 979 668 2
759 M 1209 680 2
760 M 1156 692 2
761 M 1276 638 2
762 M 916 558 2
763 M 1211 461 2
764 M 999 660 2
765 M 930 575 2
766 M 1138 454 2
767 M 1198 573 2
768 M 1221 538 2
769 M 1152 468 2
770 M 1172 530 2
771 M 1024 448 2
772 M 1131 473 2
773 M 1035 414 2
774 M 1122 460 2
775 M 974 731 2
776 M 974 449 2
777 M 1010 711 2
778 M 1109 450 2
779 M 1135 502 2
780 M 1073 725 2
781 M 1226 555 2
782 M 957 701 2
783 M 1277 568 2
784 M 1002 520 2
785 M 1139 766 2
786 M 1029 692 2
787 M 1157 675 2
788 M 1156 448 2
789 M 1148 704 2
790 M 1272 552 2
791 M 1183 473 2
792 M 1024 701 2
793 M 1067 425 2
794 M 1200 370 2
795 M 1264 405 2
796 M 1385 449 2
797 M 1515 391 2
14 Appendix A: Source Code Listings 434

798 M 1355 604 2


799 M 879 423 2
800 M 866 439 2
801 M 844 458 2
802 M 1398 565 2
803 M 1414 596 2
804 M 1414 618 2
805 M 1398 647 2
806 M 1314 673 2
807 M 1376 660 2
808 M 1368 691 2
809 M 1339 720 2
810 M 1160 637 2
811 M 1214 672 2
812 M 1257 700 2
813 M 1249 741 2
814 M 1305 750 2
815 M 1253 802 2
816 M 1128 863 2
817 M 1158 845 2
818 M 1168 841 2
819 M 831 618 2
820 M 876 573 2
821 M 816 534 2
822 M 808 702 2
823 M 538 515 2
824 M 694 731 2
825 M 756 580 2
826 M 437 290 2
827 M 387 243 2
828 M 316 198 2
829 M 440 214 2
830 M 399 137 2
831 M 406 413 2
832 M 379 404 2
833 M 366 434 2
834 M 393 451 2
835 M 314 522 2
836 M 277 598 2
837 M 355 589 2
838 M 325 604 2
839 M 285 624 2
840 M 511 470 2
14 Appendix A: Source Code Listings 435

841 M 570 442 2


842 M 422 549 2
843 M 402 509 2
844 M 326 574 2
845 M 232 574 2
846 M 491 508 2
847 M 476 486 2
848 M 522 483 2
849 M 189 692 2
850 M 162 705 2
851 M 315 654 2
852 M 342 663 2
853 M 383 658 2
854 M 407 654 2
855 M 420 646 2
856 M 442 641 2
857 M 307 635 2
858 M 369 593 2
859 M 266 673 2
860 M 224 732 2
861 M 154 790 2
862 M 110 814 2
863 M 245 709 2
864 M 236 679 2
865 M 415 594 2
866 M 383 658 2
867 M 503 597 2
868 M 509 460 2
869 M 275 768 2
870 M 226 803 2
871 M 185 828 2
872 M 218 846 2
873 M 145 883 2
874 M 309 643 2
875 M 292 645 2
876 M 359 685 2
877 M 387 614 2
878 M 427 646 2
879 M 288 648 2
880 M 299 658 2
881 M 392 581 2
882 M 327 554 2
883 M 330 639 2
14 Appendix A: Source Code Listings 436

884 M 325 643 2


885 M 327 637 2
886 M 283 628 2
887 M 338 668 2
888 M 402 659 2
889 M 337 661 2
890 M 317 600 2
891 M 382 613 2
892 M 340 649 2
893 M 349 557 2
894 M 353 694 2
895 M 320 616 2
896 M 376 640 2
897 M 372 562 2
898 M 351 598 2
899 M 492 496 2
900 M 414 545 2
901 M 494 392 2
902 M 367 492 2
903 M 407 527 2
904 M 371 510 2
905 M 357 409 2
906 M 359 518 2
907 M 501 445 2
908 M 356 382 2
909 M 332 489 2
910 M 376 535 2
911 M 328 386 2
912 M 341 452 2
913 M 328 470 2
914 M 440 524 2
915 M 317 457 2
916 M 327 397 2
917 M 524 443 2
918 M 490 351 2
919 M 419 537 2
920 M 330 482 2
921 M 320 401 2
922 M 334 462 2
923 M 539 421 2
924 M 336 513 2
925 M 448 526 2
926 M 435 536 2
14 Appendix A: Source Code Listings 437

927 M 312 449 2


928 M 369 520 2
929 M 329 480 2
930 M 504 379 2
931 M 466 540 2
932 M 357 512 2
933 M 484 505 2
934 M 346 523 2
935 M 371 360 2
936 M 433 346 2
937 M 524 466 2
938 M 500 358 2
939 M 530 447 2
940 M 482 501 2
941 M 320 441 2
942 M 506 445 2
943 M 519 384 2
944 S 1321 223 1
945 S 721 297 1
946 S 1091 592 1
947 S 584 551 1
948 S 544 683 1
949 S 356 623 1
950 S 426 442 1

ppmpp.hpp - 23814 bytes.

1 // MIT No Attribution
2 //
3 // ppmpp.hpp - A header-only class to draw/read/write 2D graphics using only the sta\
4 ndard library.
5 // Version 1.0 release (3:rd of December 2022).
6 // Copyright (c) 2022-2023 Håkan Blomqvist
7 //
8 // For more information:
9 // https://leanpub.com/2dcomputergraphicsinmoderncandstandardlibrary/
10 // https://gist.github.com/chbtoys/cdd6a85e321593ea0a1e7141d0a09fbc <- ppmpp.hpp
11 // https://gist.github.com/chbtoys/a665b52f86768b8e601c82b47ce18e49 <- test.cpp
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a copy of t\
14 his
15 // software and associated documentation files (the "Software"), to deal in the Soft\
16 ware
14 Appendix A: Source Code Listings 438

17 // without restriction, including without limitation the rights to use, copy, modify,
18 // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIE\
22 D,
23 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
24 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 #define _USE_MATH_DEFINES
30
31 #include <iostream>
32 #include <fstream>
33 #include <tuple>
34 #include <vector>
35 #include <random>
36 #include <cmath>
37 #include <algorithm>
38
39 namespace ppm
40 {
41 // Typedef
42 typedef std::tuple<float, float, float> pixel;
43 typedef std::tuple<int, int, int, int> coord;
44 typedef std::tuple<int, int> point;
45
46 class image
47 {
48 public:
49 // Constructs an empty image.
50 image() {}
51
52 // Constructs an empty image of specified width and height.
53 image(int width, int height) {resize(width, height);}
54
55 // Constructs an image reading data from specified file
56 explicit image(std::string const& filename)
57 {
58 read(filename);
59 }
14 Appendix A: Source Code Listings 439

60
61 // Resizes the image pixel buffer.
62 void resize(int width, int height)
63 {
64 m_img.clear();
65 m_img.resize(width*height);
66 set_width(width);
67 set_height(height);
68 }
69
70 void set_width(int width)
71 {
72 m_width=width;
73 }
74
75 void set_height(int height)
76 {
77 m_height=height;
78 }
79
80 int get_width()
81 {
82 return m_width;
83 }
84
85 int get_height()
86 {
87 return m_height;
88 }
89
90 void set_pixel(int x, int y, pixel px)
91 {
92 m_img[x+m_width*y]=px;
93 }
94
95 pixel get_pixel(int x, int y)
96 {
97 return m_img[x+m_width*y];
98 }
99
100 void set_all_pixels(pixel px)
101 {
102 for (int y=0;y<m_height;++y)
14 Appendix A: Source Code Listings 440

103 {
104 for (int x=0;x<m_width;++x)
105 {
106 m_img[x+m_width*y]=px;
107 }
108 }
109 }
110
111 // Drawline
112 void draw_line(coord &coords, pixel &linecolor)
113 {
114 coord coords2;
115 if (clipline(coords,coords2)) {
116 drawline(coords2,linecolor);
117 }
118 }
119
120 // Get angled line
121 void get_angled_line(coord &coords, point &center, double degrees, int length)
122 {
123 double angle = degrees * (M_PI / 180);
124 coords=std::make_tuple(std::get<0>(center),std::get<1>(center),int(double(st
125 t<0>(center)) + cos(angle)*double(length)),int(double(std::get<1>(center)) + sin(ang
126 le)*double(length)));
127 }
128
129 // Draw Curves (requires C++20)
130 #if __cplusplus >= 202002L
131 void draw_bezier_quadratic(point pt0, point pt1, point pt2, int split, pixel bezie\
132 rcolor)
133 {
134 std::vector<std::tuple<int,int>> xy;
135 quadraticbeziercurves(pt0,pt1,pt2,split,xy);
136 // drawxydots(xy,beziercolor);
137 drawxyline(xy,beziercolor,pt2);
138 }
139
140 void draw_bezier_cubic(point pt0, point pt1, point pt2, point pt3, int split, pixe\
141 l beziercolor)
142 {
143 std::vector<std::tuple<int,int>> xy;
144 cubicbeziercurves(pt0,pt1,pt2,pt3,split,xy);
145 drawxyline(xy,beziercolor,pt3);
14 Appendix A: Source Code Listings 441

146 }
147 #endif
148
149 // Draw rectangles
150 void draw_rectangle(point &xy, point &wh, pixel &rectanglecolor)
151 {
152 drawrect(xy,wh,rectanglecolor);
153 }
154
155 void draw_filled_rectangle(point &xy, point &wh, pixel &rectanglecolor)
156 {
157 drawfilledrect(xy,wh,rectanglecolor);
158 }
159
160 // Draw Circles
161 void draw_circle(point &xy, int radius, pixel &circlecolor)
162 {
163 drawcircle(xy,radius,circlecolor);
164 }
165
166 void draw_filled_circle(point &xy, int radius, pixel &circlecolor)
167 {
168 drawfilledcircle(xy,radius,circlecolor);
169 }
170
171 // Draw Wedge
172 void draw_wedge(point center,int radius,int start_angle,int end_angle,pixel &wedge\
173 color)
174 {
175 drawwedge(center,radius,start_angle,end_angle,wedgecolor);
176 }
177
178 void draw_filled_wedge(point center,int radius,int start_angle,int end_angle,pixel\
179 &wedgecolor)
180 {
181 drawfilledwedge(center,radius,start_angle,end_angle,wedgecolor);
182 }
183
184 // Draw Triangles
185 void draw_triangle(point pt1, point pt2, point pt3, pixel &trianglecolor)
186 {
187 drawtriangle(pt1,pt2,pt3,trianglecolor);
188 }
14 Appendix A: Source Code Listings 442

189
190 void draw_filled_triangle(point pt1,point pt2,point pt3,pixel &color)
191 {
192 drawfilledtriangle(pt1,pt2,pt3,color);
193 }
194
195 // Blend Colors
196 pixel blend_colors(pixel &colorbackground, pixel &colorforeground, float alpha)
197 {
198 float r=0.0f; float g=0.0f; float b=0.0f;
199 r = (std::get<0>(colorforeground) * alpha) + (std::get<0>(colorbackground) *
200 - alpha));
201 g = (std::get<1>(colorforeground) * alpha) + (std::get<1>(colorbackground) *
202 - alpha));
203 b = (std::get<2>(colorforeground) * alpha) + (std::get<2>(colorbackground) *
204 - alpha));
205
206 return std::make_tuple(r,g,b);
207 }
208
209 // Read PPM Image
210 void read(std::string const& filename)
211 {
212 std::string magic;
213 int max;
214 uint8_t buffer[3];
215 pixel color;
216
217 std::ifstream in(filename, std::ifstream::binary);
218
219 if (!in.is_open())
220 {
221 std::cout << "Can't open " << filename << std::endl;
222 exit(1);
223 }
224
225 in >> magic;
226 in.seekg(1, in.cur);
227 char c;
228 in.get(c);
229 if (c == '#')
230 {
231 // We got comments in the PPM image and skip the comments
14 Appendix A: Source Code Listings 443

232 while (c != '\n')


233 {
234 in.get(c);
235 }
236 }
237 else
238 {
239 in.seekg(-1, in.cur);
240 }
241
242 in >> m_width >> m_height >> max;
243
244 if (max != 255) {
245 std::cout << "Not 8 bit per rgb color." << std::endl;
246 exit(1);
247 }
248
249 if (magic == "P6")
250 {
251 // Move curser once to skip '\n'
252 in.seekg(1, in.cur);
253
254 m_img.clear();
255
256 for (int i = 0; i < m_width * m_height; ++i)
257 {
258 in.read(reinterpret_cast<char *>(buffer), 3);
259 color=std::make_tuple(float(float(buffer[0])/255.0),float(fl
260 0),float(float(buffer[2])/255.0));
261 m_img.push_back(color);
262 }
263 } else {
264 std::cout << filename << " is not a P6 file." << std::endl;
265 exit(1);
266 }
267
268 in.close();
269 }
270
271 // Write PPM image.
272 void write(std::string const& filename)
273 {
274 pixel color;
14 Appendix A: Source Code Listings 444

275 std::ofstream out(filename, std::ios_base::out | std::ios_base::binary);


276 out << "P6" << std::endl << m_width << ' ' << m_height << std::endl << "255"
277 td::endl;
278
279 for (int i=0;i<(m_width*m_height);++i)
280 {
281 color=m_img[i];
282 out << char(std::get<0>(color)*255.0f) << char(std::get<1>(color)*25
283 r(std::get<2>(color)*255.0f);
284 }
285 out.close();
286 }
287
288 protected:
289 int getindex(int x, int y)
290 {
291 return x+m_width*y;
292 }
293
294 void drawline(coord &coords, pixel &color)
295 {
296 int x1=std::get<0>(coords); int y1=std::get<1>(coords); int x2=std::get<2>(c
297 ); int y2=std::get<3>(coords);
298 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
299 dx = x2 - x1; dy = y2 - y1;
300 if (dx == 0)
301 {
302 if (y2 < y1) std::swap(y1, y2);
303 for (y = y1; y <= y2; y++)
304 m_img[getindex(x1,y)]=color;
305 return;
306 }
307 if (dy == 0)
308 {
309 if (x2 < x1) std::swap(x1, x2);
310 for (x = x1; x <= x2; x++)
311 m_img[getindex(x,y1)]=color;
312 return;
313 }
314 dx1 = abs(dx); dy1 = abs(dy);
315 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
316 if (dy1 <= dx1)
317 {
14 Appendix A: Source Code Listings 445

318 if (dx >= 0)


319 {
320 x = x1; y = y1; xe = x2;
321 }
322 else
323 {
324 x = x2; y = y2; xe = x1;
325 }
326 m_img[getindex(x,y)]=color;
327 for (i = 0; x<xe; i++)
328 {
329 x = x + 1;
330 if (px<0)
331 px = px + 2 * dy1;
332 else
333 {
334 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; els
335 px = px + 2 * (dy1 - dx1);
336 }
337 m_img[getindex(x,y)]=color;
338 }
339 }
340 else
341 {
342 if (dy >= 0)
343 {
344 x = x1; y = y1; ye = y2;
345 }
346 else
347 {
348 x = x2; y = y2; ye = y1;
349 }
350 m_img[getindex(x,y)]=color;
351 for (i = 0; y<ye; i++)
352 {
353 y = y + 1;
354 if (py <= 0)
355 py = py + 2 * dx1;
356 else
357 {
358 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; els
359 py = py + 2 * (dx1 - dy1);
360 }
14 Appendix A: Source Code Listings 446

361 m_img[getindex(x,y)]=color;
362 }
363 }
364 }
365
366 int findregion(int x, int y, int width, int height)
367 {
368 int code=0;
369 if(y >= height)
370 code |= 1; //top
371 else if(y < 0)
372 code |= 2; //bottom
373 if(x >= width)
374 code |= 4; //right
375 else if (x < 0)
376 code |= 8; //left
377 return(code);
378 }
379
380 bool clipline(coord &coords1, coord &coords2)
381 {
382 int x1=std::get<0>(coords1); int y1=std::get<1>(coords1); int x2=std::get<2>
383 ds1); int y2=std::get<3>(coords1);
384 int x3=0; int y3=0; int x4=0; int y4=0;
385 int code1=0, code2=0, codeout=0;
386 bool accept = 0, done=0;
387 code1 = findregion(x1, y1, m_width, m_height); //the region outcodes for the
388 oints
389 code2 = findregion(x2, y2, m_width, m_height);
390 do //In theory, this can never end up in an infinite loop, it'll always come
391 ne of the trivial cases eventually
392 {
393 if(!(code1 | code2)) accept = done = 1; //accept because both endpo
394 screen or on the border, trivial accept
395 else if(code1 & code2) done = 1; //the line isn't visible on screen,
396 ect
397 else //if no trivial reject or accept, continue the loop
398 {
399 int x, y;
400 codeout = code1 ? code1 : code2;
401 if(codeout & 1) //top
402 {
403 x = x1 + (x2 - x1) * (m_height - y1) / (y2 - y1);
14 Appendix A: Source Code Listings 447

404 y = m_height - 1;
405 }
406 else if(codeout & 2) //bottom
407 {
408 x = x1 + (x2 - x1) * -y1 / (y2 - y1);
409 y = 0;
410 }
411 else if(codeout & 4) //right
412 {
413 y = y1 + (y2 - y1) * (m_width - x1) / (x2 - x1);
414 x = m_width - 1;
415 }
416 else //left
417 {
418 y = y1 + (y2 - y1) * -x1 / (x2 - x1);
419 x = 0;
420 }
421 if(codeout == code1) //first endpoint was clipped
422 {
423 x1 = x; y1 = y;
424 code1 = findregion(x1, y1, m_width, m_height);
425 }
426 else //second endpoint was clipped
427 {
428 x2 = x; y2 = y;
429 code2 = findregion(x2, y2, m_width, m_height);
430 }
431 }
432 }
433 while(done == 0);
434 if(accept)
435 {
436 x3 = x1;
437 x4 = x2;
438 y3 = y1;
439 y4 = y2;
440 coords2=std::make_tuple(x3,y3,x4,y4);
441 return 1;
442 }
443 else
444 {
445 x3 = x4 = y3 = y4 = 0;
446 coords2=std::make_tuple(x3,y3,x4,y4);
14 Appendix A: Source Code Listings 448

447 return 0;
448 }
449 }
450
451 #if __cplusplus >= 202002L
452 void quadraticbeziercurves(point pt0, point pt1, point pt2, int split, std::vector\
453 <std::tuple<int,int>>& xy)
454 {
455 double t=0.0;
456 double delta=(double(1)/double(split));
457 int x=0;
458 int y=0;
459 int x1=0;
460 int y1=0;
461 int x2=0;
462 int y2=0;
463 for (int i=0;i<split;++i)
464 {
465 x1 = std::lerp(std::get<0>(pt0),std::get<0>(pt1),t);
466 y1 = std::lerp(std::get<1>(pt0),std::get<1>(pt1),t);
467 x2 = std::lerp(std::get<0>(pt1),std::get<0>(pt2),t);
468 y2 = std::lerp(std::get<1>(pt1),std::get<1>(pt2),t);
469 x = std::lerp(x1,x2,t);
470 y = std::lerp(y1,y2,t);
471 xy.push_back(std::make_tuple(x,y));
472 t+=delta;
473 }
474 }
475
476 void cubicbeziercurves(point pt0, point pt1, point pt2, point pt3, int split, std:\
477 :vector<std::tuple<int,int>>& xy)
478 {
479 float t=0.0;
480 float delta=(float(1)/float(split));
481 int x=0;
482 int y=0;
483 int x1=0;
484 int y1=0;
485 int x2=0;
486 int y2=0;
487 int x3=0;
488 int y3=0;
489 int x4=0;
14 Appendix A: Source Code Listings 449

490 int y4=0;


491 int xx1=0;
492 int yy1=0;
493 int xx2=0;
494 int yy2=0;
495 for (int i=0;i<split;++i)
496 {
497 x1 = std::lerp(std::get<0>(pt0),std::get<0>(pt1),t);
498 y1 = std::lerp(std::get<1>(pt0),std::get<1>(pt1),t);
499 x2 = std::lerp(std::get<0>(pt1),std::get<0>(pt2),t);
500 y2 = std::lerp(std::get<1>(pt1),std::get<1>(pt2),t);
501
502 x3 = std::lerp(std::get<0>(pt1),std::get<0>(pt2),t);
503 y3 = std::lerp(std::get<1>(pt1),std::get<1>(pt2),t);
504 x4 = std::lerp(std::get<0>(pt2),std::get<0>(pt3),t);
505 y4 = std::lerp(std::get<1>(pt2),std::get<1>(pt3),t);
506
507 xx1 = std::lerp(x1,x2,t);
508 yy1 = std::lerp(y1,y2,t);
509 xx2 = std::lerp(x3,x4,t);
510 yy2 = std::lerp(y3,y4,t);
511
512 x = std::lerp(xx1,xx2,t);
513 y = std::lerp(yy1,yy2,t);
514 xy.push_back(std::make_tuple(x,y));
515 t+=delta;
516 }
517 }
518 #endif
519
520 void drawxyline(std::vector<point> &xy, pixel &color, point stop)
521 {
522 point temp=xy[0];
523 point store;
524 store=std::make_tuple(std::get<0>(stop),std::get<1>(stop));
525 xy.push_back(store);
526 std::vector<coord> xyxy;
527 for (int i=1;i<xy.size();++i)
528 {
529 store=xy[i];
530 xyxy.push_back(std::make_tuple(std::get<0>(temp),std::get<1>(temp),s
531 tore),std::get<1>(store)));
532 temp=xy[i];
14 Appendix A: Source Code Listings 450

533 }
534
535 for (auto& li : xyxy)
536 {
537 draw_line(li,color);
538 }
539 }
540
541 void drawxydots(std::vector<point> &xy, pixel &color)
542 {
543 for (auto& pt : xy)
544 {
545 m_img[getindex(std::get<0>(pt),std::get<1>(pt))]=color;
546 }
547 }
548
549 void drawrect(point &xy, point &wh, pixel &color)
550 {
551 int x=std::get<0>(xy);int y=std::get<1>(xy);int w=std::get<0>(wh);int h=std:
552 1>(wh);
553 coord coords=std::make_tuple(x, y, x+w, y);
554 draw_line(coords, color);
555 coords=std::make_tuple(x+w, y, x+w, y+h);
556 draw_line(coords, color);
557 coords=std::make_tuple(x+w, y+h, x, y+h);
558 draw_line(coords, color);
559 coords=std::make_tuple(x, y+h, x, y);
560 draw_line(coords, color);
561 }
562
563 void drawfilledrect(point &xy, point &wh, pixel &color)
564 {
565 int x2 = std::get<0>(xy) + std::get<0>(wh);
566 int y2 = std::get<1>(xy) + std::get<1>(wh);
567
568 coord coords=std::make_tuple(0,0,0,0);
569 for (int i = std::get<1>(xy); i < y2; ++i)
570 {
571 coords=std::make_tuple(std::get<0>(xy),i,x2,i);
572 draw_line(coords, color);
573 }
574 }
575
14 Appendix A: Source Code Listings 451

576 void drawcircle(point &xy, int radius, pixel &color)


577 {
578 int x0 = 0;
579 int y0 = radius;
580 int d = 3 - 2 * radius;
581 int xx=0;
582 int yy=0;
583 int x=std::get<0>(xy);
584 int y=std::get<1>(xy);
585 coord coords=std::make_tuple(0,0,0,0);
586 unsigned char mask=255;
587 if (!radius) return;
588
589 while (y0 >= x0)
590 {
591 if (mask & 0x01) {xx=x + x0;yy=y - y0;coords=std::make_tuple(xx,yy,x
592 ine(coords, color);}
593 if (mask & 0x02) {xx=x + y0;yy=y - x0;coords=std::make_tuple(xx,yy,x
594 ine(coords, color);}
595 if (mask & 0x04) {xx=x + y0;yy=y + x0;coords=std::make_tuple(xx,yy,x
596 ine(coords, color);}
597 if (mask & 0x08) {xx=x + x0;yy=y + y0;coords=std::make_tuple(xx,yy,x
598 ine(coords, color);}
599 if (mask & 0x10) {xx=x - x0;yy=y + y0;coords=std::make_tuple(xx,yy,x
600 ine(coords, color);}
601 if (mask & 0x20) {xx=x - y0;yy=y + x0;coords=std::make_tuple(xx,yy,x
602 ine(coords, color);}
603 if (mask & 0x40) {xx=x - y0;yy=y - x0;coords=std::make_tuple(xx,yy,x
604 ine(coords, color);}
605 if (mask & 0x80) {xx=x - x0;yy=y - y0;coords=std::make_tuple(xx,yy,x
606 ine(coords, color);}
607 if (d < 0) d += 4 * x0++ + 6;
608 else d += 4 * (x0++ - y0--) + 10;
609 }
610 }
611
612 void drawfilledcircle(point &xy, int radius, pixel &color)
613 {
614 int x0 = 0;
615 int y0 = radius;
616 int d = 3 - 2 * radius;
617 int x=std::get<0>(xy);
618 int y=std::get<1>(xy);
14 Appendix A: Source Code Listings 452

619 coord coords=std::make_tuple(0,0,0,0);


620 if (!radius) return;
621
622 while (y0 >= x0)
623 {
624 coords=std::make_tuple(x-x0,y-y0,x+x0,y-y0);
625 draw_line(coords, color);
626 coords=std::make_tuple(x-y0,y-x0,x+y0,y-x0);
627 draw_line(coords, color);
628 coords=std::make_tuple(x-x0,y+y0,x+x0,y+y0);
629 draw_line(coords, color);
630 coords=std::make_tuple(x-y0,y+x0,x+y0,y+x0);
631 draw_line(coords, color);
632 if (d < 0) d += 4 * x0++ + 6;
633 else d += 4 * (x0++ - y0--) + 10;
634 }
635 }
636
637 void getallys(std::vector<int> &ys,std::vector<point> &coords)
638 {
639 for (auto& c : coords) {
640 ys.push_back(std::get<1>(c));
641 }
642
643 sort(ys.begin(), ys.end());
644 ys.erase( unique( ys.begin(), ys.end() ), ys.end() );
645 }
646
647 void getlinecoords(coord line,std::vector<point> &coords)
648 {
649 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
650 int x1=std::get<0>(line);int y1=std::get<1>(line);int x2=std::get<2>(line);i
651 =std::get<3>(line);
652 dx = x2 - x1; dy = y2 - y1;
653 if (dx == 0)
654 {
655 if (y2 < y1) std::swap(y1, y2);
656 for (y = y1; y <= y2; y++)
657 coords.push_back(std::make_tuple(x1,y));
658 return;
659 }
660 if (dy == 0)
661 {
14 Appendix A: Source Code Listings 453

662 if (x2 < x1) std::swap(x1, x2);


663 for (x = x1; x <= x2; x++)
664 coords.push_back(std::make_tuple(x,y1));
665 return;
666 }
667 dx1 = abs(dx); dy1 = abs(dy);
668 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
669 if (dy1 <= dx1)
670 {
671 if (dx >= 0)
672 {
673 x = x1; y = y1; xe = x2;
674 }
675 else
676 {
677 x = x2; y = y2; xe = x1;
678 }
679 coords.push_back(std::make_tuple(x,y));
680 for (i = 0; x<xe; i++)
681 {
682 x = x + 1;
683 if (px<0)
684 px = px + 2 * dy1;
685 else
686 {
687 if ((dx<0 && dy<0) || (dx>0 && dy>0)) y = y + 1; els
688 px = px + 2 * (dy1 - dx1);
689 }
690 coords.push_back(std::make_tuple(x,y));
691 }
692 }
693 else
694 {
695 if (dy >= 0)
696 {
697 x = x1; y = y1; ye = y2;
698 }
699 else
700 {
701 x = x2; y = y2; ye = y1;
702 }
703 coords.push_back(std::make_tuple(x,y));
704 for (i = 0; y<ye; i++)
14 Appendix A: Source Code Listings 454

705 {
706 y = y + 1;
707 if (py <= 0)
708 py = py + 2 * dx1;
709 else
710 {
711 if ((dx<0 && dy<0) || (dx>0 && dy>0)) x = x + 1; els
712 py = py + 2 * (dx1 - dy1);
713 }
714 coords.push_back(std::make_tuple(x,y));
715 }
716 }
717 }
718
719 void drawwedge(point center,int radius,int start_angle,int end_angle,pixel &color)
720 {
721 std::vector<point> coords;
722
723 float angle=(((start_angle<=end_angle)?start_angle:end_angle)*(M_PI/180));
724 float range=(((end_angle>start_angle)?end_angle:start_angle)*(M_PI/180));
725 float x=(radius*cos(angle));
726 float y=(radius*sin(angle));
727 do
728 {
729 coords.push_back(std::make_tuple((int)(std::get<0>(center)+x+0.5),(i
730 <1>(center)-y+0.5)));
731 angle+=0.001;
732 x=(radius*cos(angle));
733 y=(radius*sin(angle));
734 }
735 while(angle<=range);
736
737 point co1=coords.front();
738 point co2=coords.back();
739
740 coord line1=std::make_tuple(std::get<0>(center),std::get<1>(center),std::get
741 o1),std::get<1>(co1));
742 coord line2=std::make_tuple(std::get<0>(center),std::get<1>(center),std::get
743 o2),std::get<1>(co2));
744
745 getlinecoords(line1,coords);
746 getlinecoords(line2,coords);
747
14 Appendix A: Source Code Listings 455

748 for (auto & e : coords)


749 {
750 line1=std::make_tuple(std::get<0>(e),std::get<1>(e),std::get<0>(e),s
751 ));
752 draw_line(line1,color);
753 }
754 }
755
756 void drawfilledwedge(point center,int radius,int start_angle,int end_angle,pixel &\
757 color)
758 {
759 std::vector<point> coords;
760
761 float angle=(((start_angle<=end_angle)?start_angle:end_angle)*(M_PI/180));
762 float range=(((end_angle>start_angle)?end_angle:start_angle)*(M_PI/180));
763 float x=(radius*cos(angle));
764 float y=(radius*sin(angle));
765 do
766 {
767 coords.push_back(std::make_tuple((int)(std::get<0>(center)+x+0.5),(i
768 <1>(center)-y+0.5)));
769 angle+=0.001;
770 x=(radius*cos(angle));
771 y=(radius*sin(angle));
772 }
773 while(angle<=range);
774
775 point co1=coords.front();
776 point co2=coords.back();
777
778 coord line1=std::make_tuple(std::get<0>(center),std::get<1>(center),std::get
779 o1),std::get<1>(co1));
780 coord line2=std::make_tuple(std::get<0>(center),std::get<1>(center),std::get
781 o2),std::get<1>(co2));
782
783 getlinecoords(line1,coords);
784 getlinecoords(line2,coords);
785
786 std::vector<int> ys;
787 std::vector<int> xs;
788 getallys(ys,coords);
789 std::vector<coord> lines;
790
14 Appendix A: Source Code Listings 456

791 for (int search=0;search<=ys.size();++search)


792 {
793 for (auto& c : coords) {
794 if (std::get<1>(c) == ys[search]) {
795 xs.push_back(std::get<0>(c));
796 }
797 }
798 sort(xs.begin(), xs.end());
799 lines.push_back(std::make_tuple(xs.front(),ys[search],xs.back(),ys[s
800 xs.clear();
801 }
802
803 coord cd=std::make_tuple(0,0,0,0);
804 for (auto& l : lines) {
805 draw_line(l,color);
806 }
807 }
808
809 void drawtriangle(point pt1, point pt2, point pt3, pixel &color)
810 {
811 coord coords=std::make_tuple(std::get<0>(pt1),std::get<1>(pt1),std::get<0>(p
812 td::get<1>(pt2));
813 draw_line(coords,color);
814 coords=std::make_tuple(std::get<0>(pt2),std::get<1>(pt2),std::get<0>(pt3),st
815 t<1>(pt3));
816 draw_line(coords,color);
817 coords=std::make_tuple(std::get<0>(pt3),std::get<1>(pt3),std::get<0>(pt1),st
818 t<1>(pt1));
819 draw_line(coords,color);
820 }
821
822 void drawfilledtriangle(point pt1,point pt2,point pt3,pixel &color)
823 {
824 int x1=std::get<0>(pt1); int y1=std::get<1>(pt1); int x2=std::get<0>(pt2); i
825 =std::get<1>(pt2); int x3=std::get<0>(pt3); int y3=std::get<1>(pt3);
826 coord coords=std::make_tuple(0,0,0,0);
827 auto SWAP = [](int &x, int &y) { int t = x; x = y; y = t; };
828
829 int t1x, t2x, y, minx, maxx, t1xp, t2xp;
830 bool changed1 = false;
831 bool changed2 = false;
832 int signx1, signx2, dx1, dy1, dx2, dy2;
833 int e1, e2;
14 Appendix A: Source Code Listings 457

834 if (y1>y2) { SWAP(y1, y2); SWAP(x1, x2); }


835 if (y1>y3) { SWAP(y1, y3); SWAP(x1, x3); }
836 if (y2>y3) { SWAP(y2, y3); SWAP(x2, x3); }
837
838 t1x = t2x = x1; y = y1;
839 dx1 = (int)(x2 - x1); if (dx1<0) { dx1 = -dx1; signx1 = -1; }
840 else signx1 = 1;
841 dy1 = (int)(y2 - y1);
842
843 dx2 = (int)(x3 - x1); if (dx2<0) { dx2 = -dx2; signx2 = -1; }
844 else signx2 = 1;
845 dy2 = (int)(y3 - y1);
846
847 if (dy1 > dx1) {
848 SWAP(dx1, dy1);
849 changed1 = true;
850 }
851 if (dy2 > dx2) {
852 SWAP(dy2, dx2);
853 changed2 = true;
854 }
855
856 e2 = (int)(dx2 >> 1);
857 if (y1 == y2) goto next;
858 e1 = (int)(dx1 >> 1);
859
860 for (int i = 0; i < dx1;) {
861 t1xp = 0; t2xp = 0;
862 if (t1x<t2x) { minx = t1x; maxx = t2x; }
863 else { minx = t2x; maxx = t1x; }
864 while (i<dx1) {
865 i++;
866 e1 += dy1;
867 while (e1 >= dx1) {
868 e1 -= dx1;
869 if (changed1) t1xp = signx1;
870 else goto next1;
871 }
872 if (changed1) break;
873 else t1x += signx1;
874 }
875 next1:
876 while (1) {
14 Appendix A: Source Code Listings 458

877 e2 += dy2;
878 while (e2 >= dx2) {
879 e2 -= dx2;
880 if (changed2) t2xp = signx2;
881 else goto next2;
882 }
883 if (changed2) break;
884 else t2x += signx2;
885 }
886 next2:
887 if (minx>t1x) minx = t1x;
888 if (minx>t2x) minx = t2x;
889 if (maxx<t1x) maxx = t1x;
890 if (maxx<t2x) maxx = t2x;
891 coords=std::make_tuple(minx,y,maxx,y);
892 draw_line(coords,color);
893 if (!changed1) t1x += signx1;
894 t1x += t1xp;
895 if (!changed2) t2x += signx2;
896 t2x += t2xp;
897 y += 1;
898 if (y == y2) break;
899
900 }
901 next:
902 dx1 = (int)(x3 - x2); if (dx1<0) { dx1 = -dx1; signx1 = -1; }
903 else signx1 = 1;
904 dy1 = (int)(y3 - y2);
905 t1x = x2;
906
907 if (dy1 > dx1) {
908 SWAP(dy1, dx1);
909 changed1 = true;
910 }
911 else changed1 = false;
912
913 e1 = (int)(dx1 >> 1);
914
915 for (int i = 0; i <= dx1; i++) {
916 t1xp = 0; t2xp = 0;
917 if (t1x<t2x) { minx = t1x; maxx = t2x; }
918 else { minx = t2x; maxx = t1x; }
919 while (i<dx1) {
14 Appendix A: Source Code Listings 459

920 e1 += dy1;
921 while (e1 >= dx1) {
922 e1 -= dx1;
923 if (changed1) { t1xp = signx1; break; }
924 else goto next3;
925 }
926 if (changed1) break;
927 else t1x += signx1;
928 if (i<dx1) i++;
929 }
930 next3:
931 while (t2x != x3) {
932 e2 += dy2;
933 while (e2 >= dx2) {
934 e2 -= dx2;
935 if (changed2) t2xp = signx2;
936 else goto next4;
937 }
938 if (changed2) break;
939 else t2x += signx2;
940 }
941 next4:
942
943 if (minx>t1x) minx = t1x;
944 if (minx>t2x) minx = t2x;
945 if (maxx<t1x) maxx = t1x;
946 if (maxx<t2x) maxx = t2x;
947 coords=std::make_tuple(minx,y,maxx,y);
948 draw_line(coords,color);
949 if (!changed1) t1x += signx1;
950 t1x += t1xp;
951 if (!changed2) t2x += signx2;
952 t2x += t2xp;
953 y += 1;
954 if (y>y3) return;
955 }
956 }
957
958 std::vector<pixel> m_img;
959 int m_width;
960 int m_height;
961 };
962
14 Appendix A: Source Code Listings 460

963 } // namespace ppm

test.cpp - 2521 bytes.

1 // Compile: clang++ -std=c++17 test.cpp -o test


2 // Compile: clang++ -std=c++20 test.cpp -o test
3
4 // Tests of ppmpp.hpp
5
6 #include <tuple>
7 #include "ppmpp.hpp"
8
9 int main()
10 {
11 ppm::image image("test.ppm");
12 image.write("test_copy.ppm");
13 std::cout << image.get_width() << " " << image.get_height() << std::endl;
14 ppm::pixel color=std::make_tuple(0.0f,0.0f,0.0f);
15 ppm::pixel color2=std::make_tuple(0.0f,1.0f,1.0f);
16 ppm::image image2(1920,1080);
17 std::cout << image2.get_width() << " " << image2.get_height() << std::endl;
18 // image2.set_all_pixels(color2);
19 for (int y=0;y<image2.get_height();++y)
20 {
21 for (int x=0;x<image2.get_width();++x)
22 {
23 image2.set_pixel(x,y,color2);
24 }
25 }
26 ppm::point pt0;ppm::point pt1;ppm::point pt2;ppm::point pt3;
27 ppm::coord coords=std::make_tuple(10,300,700,900);
28 ppm::point center=std::make_tuple(1920/2,1080/2);
29 image2.draw_line(coords,color);
30 image2.get_angled_line(coords,center,7,300);
31 image2.draw_line(coords,color);
32 // Lerp requires C++20.
33 #if __cplusplus >= 202002L
34 pt0=std::make_tuple(340,90);
35 pt1=std::make_tuple(480,2);
36 pt2=std::make_tuple(620,90);
37 pt3=std::make_tuple(0,0);
38 image2.draw_bezier_quadratic(pt0,pt1,pt2,50,color);
39 pt0=std::make_tuple(200,270);
14 Appendix A: Source Code Listings 461

40 pt1=std::make_tuple(293,182);
41 pt2=std::make_tuple(386,357);
42 pt3=std::make_tuple(480,270);
43 image2.draw_bezier_cubic(pt0,pt1,pt2,pt3,50,color);
44 #endif
45 ppm::point ptxy=std::make_tuple(500,500);
46 ppm::point ptwh=std::make_tuple(900,200);
47 image2.draw_rectangle(ptxy,ptwh,color);
48 ptxy=std::make_tuple(100,100);
49 ptwh=std::make_tuple(900,200);
50 image2.draw_filled_rectangle(ptxy,ptwh,color);
51 ptxy=std::make_tuple(945,300);
52 image2.draw_circle(ptxy,250,color);
53 ptxy=std::make_tuple(300,600);
54 image2.draw_filled_circle(ptxy,250,color);
55 ppm::pixel color4=std::make_tuple(0.8f,0.0f,0.8f);
56 ppm::pixel color5=std::make_tuple(1.0f,1.0f,1.0f);
57 ppm::pixel color3=image2.blend_colors(color4,color5,0.5f);
58 ptxy=std::make_tuple(900,900);
59 ptwh=std::make_tuple(100,100);
60 image2.draw_filled_rectangle(ptxy,ptwh,color3);
61 ppm::point pt=std::make_tuple(400,400);
62 image2.draw_wedge(pt,150,0,45,color3);
63 pt=std::make_tuple(800,800);
64 image2.draw_filled_wedge(pt,150,0,45,color5);
65 pt1=std::make_tuple(750,450);
66 pt2=std::make_tuple(350,650);
67 pt3=std::make_tuple(450,750);
68 image2.draw_triangle(pt1,pt2,pt3,color5);
69 pt1=std::make_tuple(750,450);
70 pt2=std::make_tuple(950,750);
71 pt3=std::make_tuple(1250,850);
72 image2.draw_filled_triangle(pt1,pt2,pt3,color5);
73 image2.write("test2.ppm");
74
75 return 0;
76 }

You might also like