simple linear programming example 3 – maximize earnings [GLPK]

This example was found on linkedIn SlideShare Page 7:

Kayla works no more than 20 hours per week
during the school year. She is paid \$10 an hour
for tutoring
Geometry students and \$7 an hour
for babysitting
. She wants to spend at least 3
hours but no more than 8 hours a week tutoring.

Find Kayla’s maximum weekly earnings.

t = number of hours spent tutoring
b = number of hours spent babysitting

Optimisation equation: E(Earnings)
E = 10 * t + 7 * b

Subject to:
t >= 3
t <= 8 b >= 0
t + b <= 20

Also written as:
p = t
q = b
r = t + b

3 <= p <= 8
0 <= x1 < +inf

0 < q <= +inf
0 <= x2 < +inf

-inf < r <= 20
0 <= x2 < +inf

```//  Philipp Siedler
//  Linear Programming
//  Real Life Example 3

#include <stdio.h>
#include <stdlib.h>
#include <glpk.h>
#include <std_lib_facilities.h>

int main(void)
{
glp_prob *lp;
int row_index[1 + 1000];					//Row indices of each element
int	col_index[1 + 1000];					//column indices of each element
double value[1 + 1000];						//numerical values of corresponding elements
double z, x1, x2, x3;
lp = glp_create_prob();						//creates a problem object
glp_set_prob_name(lp, "sample");			//assigns a symbolic name to the problem object
glp_set_obj_dir(lp, GLP_MAX);				//calls the routine glp_set_obj_dir to set the
//omptimization direction flag,
//where GLP_MAX means maximization

//ROWS
//row 1
glp_set_row_name(lp, 1, "p");				//assigns name p to first row
glp_set_row_bnds(lp, 1, GLP_UP, 3.0, 8.0);	//sets the type and bounds of the first row,
//where GLP_UP means that the row has an upper bound.
//3 <= p <= 8
//row 2
glp_set_row_name(lp, 2, "q");				//assigns name q to second row
glp_set_row_bnds(lp, 2, GLP_UP, 0.0, INFINITY);//0 < q <= +inf
//row 3
glp_set_row_name(lp, 3, "r");				//assigns name r to second row
glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 20.0);//-inf < r <= 20

//COLUMNS
//column 1
glp_set_col_name(lp, 1, "x1");				//assigns name x1 to first column
glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0);	//sets the type and bounds to the first column,
//where GLP_LO means that the column has an lower bound
glp_set_obj_coef(lp, 1, 10.0);				//sets the objective coefficient for thr first column
//E = 10 * t + 7 * b
//column 2
glp_set_col_name(lp, 2, "x2");				//assigns name x2 to first column
glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0);	//sets the type and bounds to the second column
glp_set_obj_coef(lp, 2, 7.0);				//sets the objective coefficient for thr second column

/*
E = 10 * t + 7 * b
p = t
q = b
r = t + b
*/

row_index[1] = 1, col_index[1] = 1, value[1] = 1.0;	// a[1,1] = 1.0
row_index[2] = 1, col_index[2] = 2, value[2] = 0.0;	// a[1,2] = 0.0
row_index[3] = 2, col_index[3] = 1, value[3] = 0.0;	// a[2,1] = 0.0
row_index[4] = 2, col_index[4] = 2, value[4] = 1.0;	// a[2,2] = 1.0
row_index[5] = 3, col_index[5] = 1, value[5] = 1.0;	// a[3,1] = 1.0
row_index[6] = 3, col_index[6] = 2, value[6] = 1.0;	// a[3,2] = 1.0

for (int i = 1; i < 7; i++) {
cout << value[i];
cout << ((i % 2 == 0) ? "\n" : "\t");
}

//into the problem object
glp_simplex(lp, NULL);						//calls the routine glp_simplex
//to solve LP problem
z = glp_get_obj_val(lp);					//obtains a computed value of the objective function
x1 = glp_get_col_prim(lp, 1);				//obtain computed values of structural variables (columns)
x2 = glp_get_col_prim(lp, 2);				//obtain computed values of structural variables (columns)

printf("\nEarnings(z) = %g; tutoring(x1) = %g; babysitting(x2) = %g;\n", z, x1, x2); //writes out the optimal solution
glp_delete_prob(lp);						//calls the routine glp_delete_prob, which frees all the memory
keep_window_open();							//leave this line out and run program with ctrl + F5 to keep window open
//that means you won't need std_lib_facilities.h
}
```
```Output:
1       0
0       1
1       1
GLPK Simplex Optimizer, v4.63
3 rows, 2 columns, 4 non-zeros
*     0: obj =         -nan(ind) inf =   0.000e+00 (2)
*     2: obj =         -nan(ind) inf =   0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND

Earnings(z) = 164; tutoring(x1) = 8; babysitting(x2) = 12;
Please enter a character to exit
```

simple linear programming example 2 – pancakes and waffle recipes [GLPK]

This example was found on linkedIn SlideShare Page 5:

Pancakes
3 cups Bisquick
1 cup Milk
2 Eggs
Serves 6

Waffles
2 cups Bisquick
2 cups Milk
2 Eggs
Serves 5

You have 24 cups of Biquick, 18 cups of milk, and 20
eggs. If you want to feed as many people as possible,
how many batches of each should you make?

p = number of batches of pancakes
w = number of batches of waffles

Optimisation equation: S(Servings)
S = 6 * p + 5 * w

Subject to:
3 * p + 2 * w <= 24 cups of Bisquick
1 * p + 2 * w <= 18 cups Milk
2 * p + 2 * w <= 20 Eggs

Also written as:
p = 3 * p + 2 * w
q = 1 * p + 2 * w
r = 2 * p + 2 * w

-inf < p <= 24 0 <= x1 < +inf
-inf < q <= 18 0 <= x2 < +inf
-inf < r <= 20 0 <= x2 < +inf

```//  Philipp Siedler
//  Linear Programming
//  Real Life Example 2

#include <stdio.h>
#include <stdlib.h>
#include <glpk.h>
#include <std_lib_facilities.h>

int main(void)
{
glp_prob *lp;
int row_index[1 + 1000];					//Row indices of each element
int	col_index[1 + 1000];					//column indices of each element
double value[1 + 1000];						//numerical values of corresponding elements
double z, x1, x2, x3;
lp = glp_create_prob();						//creates a problem object
glp_set_prob_name(lp, "sample");			//assigns a symbolic name to the problem object
glp_set_obj_dir(lp, GLP_MAX);				//calls the routine glp_set_obj_dir to set the
//omptimization direction flag,
//where GLP_MAX means maximization

//ROWS
//row 1
glp_set_row_name(lp, 1, "p");					//assigns name p to first row
glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 24.0);	//sets the type and bounds of the first row,
//where GLP_UP means that the row has an upper bound.
//-inf < p <= 24
//row 2
glp_set_row_name(lp, 2, "q");				//assigns name q to second row
glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 18.0);//-inf < q <= 18
//row 3
glp_set_row_name(lp, 3, "r");				//assigns name r to second row
glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 20.0);//-inf < r <= 20

//COLUMNS
//column 1
glp_set_col_name(lp, 1, "x1");				//assigns name x1 to first column
glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0);	//sets the type and bounds to the first column,
//where GLP_LO means that the column has an lower bound
glp_set_obj_coef(lp, 1, 6.0);				//sets the objective coefficient for thr first column
//S = 6 * p + 5 * w
//column 2
glp_set_col_name(lp, 2, "x2");				//assigns name x2 to first column
glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0);	//sets the type and bounds to the second column
glp_set_obj_coef(lp, 2, 5.0);				//sets the objective coefficient for thr second column

/*
p = 3 * p + 2 * w
q = 1 * p + 2 * w
r = 2 * p + 2 * w
*/

row_index[1] = 1, col_index[1] = 1, value[1] = 3.0;	// a[1,1] = 100000.0
row_index[2] = 1, col_index[2] = 2, value[2] = 2.0;	// a[1,2] = 200000.0
row_index[3] = 2, col_index[3] = 1, value[3] = 1.0;	// a[1,2] = 200000.0
row_index[4] = 2, col_index[4] = 2, value[4] = 2.0;	// a[2,1] = 100.0
row_index[5] = 3, col_index[5] = 1, value[5] = 2.0;	// a[2,2] = 75.0
row_index[6] = 3, col_index[6] = 2, value[6] = 2.0;	// a[2,2] = 75.0

for (int i = 1; i < 7; i++) {
cout << value[i];
cout << ((i % 2 == 0) ? "\n" : "\t");
}

//into the problem object
glp_simplex(lp, NULL);						//calls the routine glp_simplex
//to solve LP problem
z = glp_get_obj_val(lp);					//obtains a computed value of the objective function
x1 = glp_get_col_prim(lp, 1);				//obtain computed values of structural variables (columns)
x2 = glp_get_col_prim(lp, 2);				//obtain computed values of structural variables (columns)

printf("\nServings(z) = %g; pancakes(x1) = %g; waffles(x2) = %g;\n", z, x1, x2); //writes out the optimal solution
glp_delete_prob(lp);						//calls the routine glp_delete_prob, which frees all the memory
keep_window_open();							//leave this line out and run program with ctrl + F5 to keep window open
//that means you won't need std_lib_facilities.h
}
```
```Output:
3       2
1       2
2       2
GLPK Simplex Optimizer, v4.63
3 rows, 2 columns, 6 non-zeros
*     0: obj =  -0.000000000e+00 inf =   0.000e+00 (2)
*     2: obj =   5.400000000e+01 inf =   0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND

Servings(z) = 54; pancakes(x1) = 4; waffles(x2) = 6;
Please enter a character to exit
```

simple linear programming example – small and large vans [GLPK]

This example was found on linkedIn SlideShare Page 3:

The West Hartford Senior Center is trying to establish a
transportation system of small and large vans. It can
spend no more than \$100,000 for both sizes of vehicles
and no more than \$500 per month for maintenance. The
WHSC can purchase a small van, which carries up to 7
passengers
, for \$10,000 and maintain it for \$100 per
month
. The large vans, which carry up to 15
passengers
, cost \$20,000 each and can be maintained for
\$75 per month. How many of each type of van should
they purchase if they want to maximize the number of
passengers
?

s = small van
l = large van

optimisation equation:
z = 7 * s + 15 * l

subject to:
10.000 * s + 20.000 * l <= 100.000 //initial purchase costs
100 * s + 75 * l <= 500 //monthly maintenance

also written as:
p = 10.000 * s + 20.000 * l
q = 100 * s + 75 * l

-inf < p <= 100.000 0 <= x1 < +inf
-inf < q <= 500 0 <= x2 < +inf

```//  Philipp Siedler
//  Linear Programming
//  Real Life Example 1

#include <stdio.h>
#include <stdlib.h>
#include <glpk.h>
#include <std_lib_facilities.h>

int main(void)
{
glp_prob *lp;
int row_index[1 + 1000];					//Row indices of each element
int	col_index[1 + 1000];					//column indices of each element
double value[1 + 1000];						//numerical values of corresponding elements
double z, x1, x2;
lp = glp_create_prob();						//creates a problem object
glp_set_prob_name(lp, "sample");			//assigns a symbolic name to the problem object
glp_set_obj_dir(lp, GLP_MAX);				//calls the routine glp_set_obj_dir to set the
//omptimization direction flag,
//where GLP_MAX means maximization

//ROWS
//row 1
glp_set_row_name(lp, 1, "p");				//assigns name p to first row
glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 100000.0);//sets the type and bounds of the first row,
//where GLP_UP means that the row has an upper bound.
//-inf < p <= 100
//row 2
glp_set_row_name(lp, 2, "q");				//assigns name q to second row
glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 500.0);//-inf < q <= 600

//COLUMNS
//column 1
glp_set_col_name(lp, 1, "x1");				//assigns name x1 to first column
glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0);	//sets the type and bounds to the first column,
//where GLP_LO means that the column has an lower bound
glp_set_obj_coef(lp, 1, 7.0);				//sets the objective coefficient for thr first column
//z = 10 * x1 + 6 * x2 + 4 * x3
//column 2
glp_set_col_name(lp, 2, "x2");				//assigns name x2 to first column
glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0);	//sets the type and bounds to the second column
glp_set_obj_coef(lp, 2, 15.0);				//sets the objective coefficient for thr second column

/*
p = 10.000 * s + 20.000 * l
q = 100 * s + 75 * l
*/

row_index[1] = 1, col_index[1] = 1, value[1] = 10000.0;	// a[1,1] = 100000.0
row_index[2] = 1, col_index[2] = 2, value[2] = 20000.0;	// a[1,2] = 200000.0
row_index[3] = 2, col_index[3] = 1, value[3] = 100.0;	// a[2,1] = 100.0
row_index[4] = 2, col_index[4] = 2, value[4] = 75.0;	// a[2,2] = 75.0

for (int i = 1; i < 5; i++) {
cout << value[i];
cout << ((i % 2 == 0) ? "\n" : "\t");
}

//into the problem object
glp_simplex(lp, NULL);						//calls the routine glp_simplex
//to solve LP problem
z = glp_get_obj_val(lp);					//obtains a computed value of the objective function
x1 = glp_get_col_prim(lp, 1);				//obtain computed values of structural variables (columns)
x2 = glp_get_col_prim(lp, 2);				//obtain computed values of structural variables (columns)

printf("\nz = %g; x1 = %g; x2 = %g;\n", z, x1, x2); //writes out the optimal solution
glp_delete_prob(lp);						//calls the routine glp_delete_prob, which frees all the memory
keep_window_open();							//leave this line out and run program with ctrl + F5 to keep window open
//that means you won't need std_lib_facilities.h
}
```
```Output:
10000   20000
100     75
GLPK Simplex Optimizer, v4.63
2 rows, 2 columns, 4 non-zeros
*     0: obj =  -0.000000000e+00 inf =   0.000e+00 (2)
*     1: obj =   7.500000000e+01 inf =   0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND

z = 75; x1 = 0; x2 = 5;
Please enter a character to exit
```

star class colored [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 13 Exercise 19
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 13 Exercise 19

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>

using namespace Graph_lib;

ostream& operator<<(ostream& out, Point& a) {
out << "(" << a.x << "," << a.y << ")";
return out;
}

struct Star : Closed_polyline
{
{
s = (s < 3) ? segments : 3;
generate_points();
};
Star(Point origin, int radius, int segments)
{
s = (s < 3) ? segments : 3;
generate_points();
};

void generate_points();
void draw_lines() const;

private:
Point o;
int r;
int ir;
int s;
Fl_Color lc;
};

void Star::generate_points()
{
for (int i = 1; i < s + 1; i++) {
add(Point(r * sin(((2 * M_PI) / s) * i) + o.x, r * cos(((2 * M_PI) / s) * i) + o.y));
add(Point(ir * sin(((2 * M_PI) / s) * i + ((2 * M_PI) / (s * 2))) + o.x, ir * cos(((2 * M_PI) / s) * i + ((2 * M_PI) / (s * 2))) + o.y));
}
};

void Star::draw_lines() const
{
fl_color(lc);
Closed_polyline::draw_lines();
};

int main()
try
{
Point tl(100, 100);
Simple_window win(tl, 720, 400, "Simple Window");
Point center(win.x_max() / 2, win.y_max() / 2);

Star star1(center, 50, 20, 8, FL_RED);
star1.set_fill_color(Color::red);

Star star2(Point(100,300), 70, 20, 10, FL_RED);
star2.set_fill_color(Color::blue);

Star star3(Point(600, 200), 20, 100, 16, FL_RED);
star3.set_fill_color(Color::green);

win.attach(star1);
win.attach(star2);
win.attach(star3);

win.wait_for_button();
}
catch (exception& e) {
cout << e.what() << endl;
return 1;
}
catch (...) {
cout << "Exiting" << endl;
return 2;
}
```

polygon class point check [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 13 Exercise 18
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 13 Exercise 18

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>

using namespace Graph_lib;

ostream& operator<<(ostream& out, Point& a) {
out << "(" << a.x << "," << a.y << ")";
return out;
}

struct Poly : Closed_polyline
{
Poly(vector<Point> pts, Fl_Color linecolor)
: pts(pts), lc(linecolor)
{
if (pts.size() <= 2) {
error("Not enough points", pts.size());
}
else {
generate_points();
}
};

void generate_points();
void draw_lines() const;

private:
vector<Point> pts;
Fl_Color lc;
};

void Poly::generate_points()
{
for (int i = 0; i < pts.size(); i++) {
}
};

void Poly::draw_lines() const
{
fl_color(lc);
Closed_polyline::draw_lines();
};

int main()
try
{
Point tl(100, 100);
Simple_window win(tl, 720, 400, "Simple Window");
Point center(win.x_max() / 2, win.y_max() / 2);

vector<Point> pts = { Point(100, 100), Point(150, 200) };

Poly p(pts, FL_RED);

win.attach(p);
win.wait_for_button();
}
catch (exception& e) {
cout << e.what() << endl;
return 1;
}
catch (...) {
cout << "Exiting" << endl;
return 2;
}
```

hexagon tiling colored [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 13 Exercise 17
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 13 Exercise 17

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>

using namespace Graph_lib;

ostream& operator<<(ostream& out, Point& a) {
out << "(" << a.x << "," << a.y << ")";
return out;
}

struct Regular_hexagon : Closed_polyline
{
Regular_hexagon(Point origin, int radius, Fl_Color lc)
{
generate_points();
};

void generate_points();
void draw_lines() const;
vector<Point> get_pts() { return pts; };

private:
Fl_Color lc;
Point o;
vector<Point> pts;
int r;
};

void Regular_hexagon::generate_points()
{
int n = 6;
for (int i = 0; i < n; i++) {
pts.push_back(Point(o.x + r * cos(2 * M_PI * i / n), o.y + r * sin(2 * M_PI * i / n)));
}
};

void Regular_hexagon::draw_lines() const
{
fl_color(lc);
Closed_polyline::draw_lines();
};

struct rh_tiling : Shape
{
rh_tiling(Point basepoint, double radius, int num_xdir, int num_ydir)
{
nx = (num_xdir == 0) ? 1 : num_xdir;
ny = (num_ydir == 0) ? 1 : num_ydir;
generate_pts();
}

void generate_pts();
void draw_lines() const;

private:
vector<Point> pts;
Point bp;
double r;
int nx;
int ny;
};

void rh_tiling::generate_pts()
{
double triangle_h = sqrt(pow(r, 2) - pow(r / 2, 2));
cout << triangle_h << endl;
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
if (j % 2 == 0 || j == 0) {
pts.push_back(Point(bp.x + (r * 3) * i, bp.y + triangle_h * j));
}
else {
pts.push_back(Point(bp.x + (r * 3) * i + (1.5 * r), bp.y + j * triangle_h));
}
}
}
};

void rh_tiling::draw_lines() const
{
for (int i = 0; i < pts.size(); i++) {
Regular_hexagon(pts[i], r, Fl_Color(i)).draw_lines();
}
};

int main()
try
{
Point tl(100, 100);
Simple_window win(tl, 720, 400, "Simple Window");
Point center(win.x_max() / 2, win.y_max() / 2);

rh_tiling myTiling(Point(50, 100), 50, 5, 6);
myTiling.set_color(Color::red);

win.attach(myTiling);
win.wait_for_button();
}
catch (exception& e) {
cout << e.what() << endl;
return 1;
}
catch (...) {
cout << "Exiting" << endl;
return 2;
}
```

hexagon tiling again [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 13 Exercise 16
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).
For some reason Exercise 16 in Chapter 13 is exactly the same as Exercise 9, so here you go again: (except I missunderstood, if so please let me know)

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 13 Exercise 16

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>

using namespace Graph_lib;

ostream& operator<<(ostream& out, Point& a) {
out << "(" << a.x << "," << a.y << ")";
return out;
}

struct Regular_hexagon : Closed_polyline
{
{
generate_points();
};

void generate_points();
void draw_lines() const;
vector<Point> get_pts() { return pts; };

private:
Point o;
vector<Point> pts;
int r;
};

void Regular_hexagon::generate_points()
{
int n = 6;
for (int i = 0; i < n; i++) {
pts.push_back(Point(o.x + r * cos(2 * M_PI * i / n), o.y + r * sin(2 * M_PI * i / n)));
}
};

void Regular_hexagon::draw_lines() const
{
Closed_polyline::draw_lines();
};

struct rh_tiling : Shape
{
rh_tiling(Point basepoint, double radius, int num_xdir, int num_ydir)
{
nx = (num_xdir == 0) ? 1 : num_xdir;
ny = (num_ydir == 0) ? 1 : num_ydir;
generate_pts();
}

void generate_pts();
void draw_lines() const;

private:
vector<Point> pts;
Point bp;
double r;
int nx;
int ny;
};

void rh_tiling::generate_pts()
{
double triangle_h = sqrt(pow(r, 2) - pow(r / 2, 2));
cout << triangle_h << endl;
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
if (j % 2 == 0 || j == 0) {
pts.push_back(Point(bp.x + (r * 3) * i, bp.y + triangle_h * j));
}
else {
pts.push_back(Point(bp.x + (r * 3) * i + (1.5 * r), bp.y + j * triangle_h));
}
}
}
};

void rh_tiling::draw_lines() const
{
for (int i = 0; i < pts.size(); i++) {
Regular_hexagon(pts[i], r).draw_lines();
}
};

int main()
try
{
Point tl(100, 100);
Simple_window win(tl, 720, 400, "Simple Window");
Point center(win.x_max() / 2, win.y_max() / 2);

rh_tiling myTiling(Point(50,100),50,5,6);
myTiling.set_color(Color::red);

win.attach(myTiling);
win.wait_for_button();
}
catch (exception& e) {
cout << e.what() << endl;
return 1;
}
catch (...) {
cout << "Exiting" << endl;
return 2;
}
```

right triangle tiling [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 13 Exercise 15
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 13 Exercise 15

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>

using namespace Graph_lib;

ostream& operator<<(ostream& out, Point& a) {
out << "(" << a.x << "," << a.y << ")";
return out;
}

Point operator-(Point& p1, Point& p2) {
Point p3 = Point(p1.x - p2.x, p1.y - p2.y);
return p3;
}

Point operator+(Point& p1, Point& p2) {
Point p3 = Point(p1.x + p2.x, p1.y + p2.y);
return p3;
}

double pointVecMag(Point vec) {
return sqrt(pow(vec.x, 2) + pow(vec.y, 2));;
}

struct Regular_triangle : Closed_polyline
{
Regular_triangle(Point origin, int edge, int height, Fl_Color linecolor)
: o(origin), e(edge), h(height), lc(linecolor)
{
generate_points();
};

void generate_points();
void draw_lines() const;

private:
Point o;
int e;
int h;
Fl_Color lc;
};

void Regular_triangle::generate_points()
{
add(Point(o.x + e / 2, o.y - h));
};

void Regular_triangle::draw_lines() const
{
fl_color(lc);
Closed_polyline::draw_lines();
};

{
Point origin_Pt1 = Regular_triangle::point(0) - Regular_triangle::point(2);
Point origin_Pt2 = Regular_triangle::point(1) - Regular_triangle::point(2);

Regular_triangle::set_point(0, rotated_Pt1 + Regular_triangle::point(2));
Regular_triangle::set_point(1, rotated_Pt2 + Regular_triangle::point(2));
};

struct rt_tiling : Shape
{
rt_tiling(Point basepoint, int edge, int height, int xcount, int ycount)
:bp(basepoint), e(edge), h(height)
{
xc = (xcount == 0) ? 1 : xcount;
yc = (ycount == 0) ? 1 : ycount;
generate_pts();
}

void draw_lines() const;
void generate_pts();

private:
vector<Point> pts;
Point bp;
int e;
int h;
int xc;
int yc;
};

void rt_tiling::generate_pts() {
for (int i = 0; i < yc; i++) {
for (int j = 0; j < xc; j++) {
if (i % 2 == 0) {
if (j % 2 == 0) {
pts.push_back(Point(bp.x + (e / 2) * j, bp.y + h * i));
}
else {
pts.push_back(Point(bp.x + (e / 2) * j, bp.y + h * i + h));
}
}
else {
if (j % 2 == 0) {
pts.push_back(Point(bp.x + (e / 2) * j, bp.y + h * i + h));
}
else {
pts.push_back(Point(bp.x + (e / 2) * j, bp.y + h * i));
}
}
}
}
}

void rt_tiling::draw_lines() const
{
for (int i = 0; i < xc; i++) {
for (int j = 0; j < yc; j++) {
Regular_triangle rt(pts[i + j * xc], e, h, Color::red);
if (j % 2 == 0) {
if (i % 2 != 0 && j % 2 == 0) {
rt.rotate_triangle(M_PI);
}
}
else {
if (i % 2 == 0 && j % 2 != 0) {
rt.rotate_triangle(M_PI);
}
}
rt.draw_lines();
}
}
};

int main()
try
{
Point tl(100, 100);
Simple_window win(tl, 720, 400, "Simple Window");
Point center(win.x_max() / 2, win.y_max() / 2);

int edge = 50;
int height = 0.5 * (1 + sqrt(2.0)) * edge; //r = 1/2 * ( 1 + sqrt(2)) * s

rt_tiling myRtTiling(Point(10, 100), edge, height, 20, 5);

win.attach(myRtTiling);
win.wait_for_button();
}
catch (exception& e) {
cout << e.what() << endl;
return 1;
}
catch (...) {
cout << "Exiting" << endl;
return 2;
}
```

right triangle class octagon [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 13 Exercise 14
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 13 Exercise 14

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>

using namespace Graph_lib;

ostream& operator<<(ostream& out, Point& a) {
out << "(" << a.x << "," << a.y << ")";
return out;
}

Point operator-(Point& p1, Point& p2) {
Point p3 = Point(p1.x - p2.x, p1.y - p2.y);
return p3;
}

Point operator+(Point& p1, Point& p2) {
Point p3 = Point(p1.x + p2.x, p1.y + p2.y);
return p3;
}

double pointVecMag(Point vec) {
return sqrt(pow(vec.x, 2) + pow(vec.y, 2));;
}

struct Regular_triangle : Closed_polyline
{
Regular_triangle(Point origin, int edge, int height, Fl_Color linecolor)
: o(origin), e(edge), h(height), lc(linecolor)
{
generate_points();
};

void generate_points();
void draw_lines() const;

private:
Point o;
int e;
int h;
Fl_Color lc;
};

void Regular_triangle::generate_points()
{
add(Point(o.x + e / 2, o.y - h));
};

void Regular_triangle::draw_lines() const
{
fl_color(lc);
Closed_polyline::draw_lines();
};

{
Point origin_Pt1 = Regular_triangle::point(0) - Regular_triangle::point(2);
Point origin_Pt2 = Regular_triangle::point(1) - Regular_triangle::point(2);

Regular_triangle::set_point(0, rotated_Pt1 + Regular_triangle::point(2));
Regular_triangle::set_point(1, rotated_Pt2 + Regular_triangle::point(2));
};

int main()
try
{
Point tl(100, 100);
Simple_window win(tl, 720, 400, "Simple Window");
Point center(win.x_max() / 2, win.y_max() / 2);

int edge = 50;
int height = 0.5 * (1 + sqrt(2.0)) * edge; //r = 1/2 * ( 1 + sqrt(2)) * s

Vector_ref<Regular_triangle> rt;

for (int i = 0; i < 8; i++) {
rt.push_back(new Regular_triangle(center, edge, height, Fl_Color(i)));
rt[i].rotate_triangle(((2 * M_PI) / 8) * i);
win.attach(rt[i]);
}

win.wait_for_button();
}
catch (exception& e) {
cout << e.what() << endl;
return 1;
}
catch (...) {
cout << "Exiting" << endl;
return 2;
}
```

color matrix from 13.10 [fltk]

Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 13 Exercise 13
Using GUI library called FLTK (Fast Light Tool Kit, “full tick”).

```Output:

```
```//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 13 Exercise 13

#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>

using namespace Graph_lib;

ostream& operator<<(ostream& out, Point& a) {
out << "(" << a.x << "," << a.y << ")";
return out;
}

int main()
try
{
Point tl(100, 100);
Simple_window win(tl, 720, 400, "Simple Window");
Point center(win.x_max() / 2, win.y_max() / 2);

Vector_ref<Graph_lib::Rectangle> rect;
Graph_lib::Rectangle x(Point(100, 200), Point(200, 300));

rect.push_back(x);
rect.push_back(new Graph_lib::Rectangle(Point(50, 60), Point(80, 90)));

for (int i = 0; i < rect.size(); i++) rect[i].move(10, 10);

Vector_ref<Graph_lib::Rectangle> vr;
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
vr.push_back(new Graph_lib::Rectangle(Point(i * 20, j * 20), 20, 20));
vr[vr.size() - 1].set_fill_color(Color(i * 16 + j));
win.attach(vr[vr.size() - 1]);
}
}

win.wait_for_button();
}
catch (exception& e) {
cout << e.what() << endl;
return 1;
}
catch (...) {
cout << "Exiting" << endl;
return 2;
}
```