draw exception class hierarchy diagram [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 14 Exercise 17

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

using namespace Graph_lib;

struct boxRoundCorners : public Shape
{
	boxRoundCorners(Fl_Color boxColor, Point origin, int width, int height, int radius, Fl_Color textColor, string s)
		:
		bc(boxColor),		// box color
		o(origin),			// box origin
		w(width),			// box width
		h(height),			// box height
		r(radius),			// box corner radius
		tc(textColor),		// text color
		label(s)			// text
	{
		// defining points for box
		a1 = Point(o.x + r, o.y);
		a2 = Point(o.x, o.y + r);
		a3 = Point(o.x + r, o.y + r);

		b1 = Point(o.x + w - r, o.y);
		b2 = Point(o.x + w, o.y + r);
		b3 = Point(o.x + w - r, o.y + r);

		c1 = Point(o.x + w, o.y + h - r);
		c2 = Point(o.x + w - r, o.y + h);
		c3 = Point(o.x + w - r, o.y + h - r);

		d1 = Point(o.x + r, o.y + h);
		d2 = Point(o.x, o.y + h - r);
		d3 = Point(o.x + r, o.y + h - r);

		set_fill_color(Color::red);

		textPt = Point(o.x + r, o.y + h / 2 + r); // text point
		add(textPt);		// adding text point to shape
	};

	Point get_textPt() { return textPt; }
	Point get_north() { return Point(o.x + w / 2, o.y); }
	Point get_east() { return Point(o.x + w, o.y + h / 2); }
	Point get_south() { return Point(o.x + w / 2, o.y + h); }
	Point get_west() { return Point(o.x, o.y + h / 2); }

	int get_width() { return w; }
	int get_height() { return h; }

	void draw_lines() const {
		if (color().visibility()) {
			// DRAWING TEXT
			fl_color(tc);	// setting text color
			fl_draw(label.c_str(), point(0).x, point(0).y); // drawing text

															// DRAWING BOX
			fl_color(bc);	// setting box color

							/*
							// defining box lines
							fl_line(a1.x, a1.y, b1.x, b1.y);
							fl_line(b2.x, b2.y, c1.x, c1.y);
							fl_line(c2.x, c2.y, d1.x, d1.y);
							fl_line(d2.x, d2.y, a2.x, a2.y);
							// defining box arcs
							fl_arc(o.x, o.y, r + r, r + r, 90, 180);
							fl_arc(o.x + w - (r + r), o.y, r + r, r + r, 360, 90);
							fl_arc(o.x + w - (r + r), o.y + h - (r + r), r + r, r + r, 270, 360);
							fl_arc(o.x, o.y + h - (r + r), r + r, r + r, 180, 270);
							*/

			fl_begin_complex_polygon();
			fl_arc(o.x, o.y, r + r, r + r, 90, 180);
			fl_gap();
			fl_line(a1.x, a1.y, b1.x, b1.y);
			fl_gap();
			fl_arc(o.x + w - (r + r), o.y, r + r, r + r, 360, 90);
			fl_gap();
			fl_line(b2.x, b2.y, c1.x, c1.y);
			fl_gap();
			fl_arc(o.x + w - (r + r), o.y + h - (r + r), r + r, r + r, 270, 360);
			fl_gap();
			fl_line(c2.x, c2.y, d1.x, d1.y);
			fl_gap();
			fl_arc(o.x, o.y + h - (r + r), r + r, r + r, 180, 270);
			fl_gap();
			fl_line(d2.x, d2.y, a2.x, a2.y);
			fl_end_complex_polygon();
		}
	}

private:
	// BOX
	Point o;
	Point a1, a2, b1, b2, c1, c2, d1, d2;
	Point a3, b3, c3, d3;
	Point north, east, south, west;
	Fl_Color bc;
	int w, h, r;

	// LABEL
	Point textPt;
	string label; // label
	Fl_Color tc;
};


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);

	Fl_Color boxColor = Color::black;
	Fl_Color textColor = Color::black;
	Fl_Color arrowColor = Color::black;

	boxRoundCorners exc(boxColor, Point(20, win.y_max() / 2), 150, 30, 5, textColor, "exception <exception>");

	boxRoundCorners bad_cast(boxColor, Point(250, 20), 150, 30, 5, textColor, "bad_cast <typeinfo>");
	boxRoundCorners bad_typeid(boxColor, Point(250, 70), 150, 30, 5, textColor, "bad_typeid <typeinfo>");
	boxRoundCorners logic_error(boxColor, Point(250, 120), 150, 30, 5, textColor, "logic_eror <stdexcept>");
	boxRoundCorners bad_alloc(boxColor, Point(250, 170), 150, 30, 5, textColor, "bad_alloc <new>");
	boxRoundCorners Ios_base(boxColor, Point(250, 220), 150, 30, 5, textColor, "Ios_base::failure <ios>");
	boxRoundCorners runtime_error(boxColor, Point(250, 270), 200, 30, 5, textColor, "runtime_error <stdexcept>");
	boxRoundCorners bad_exception(boxColor, Point(250, 320), 200, 30, 5, textColor, "bad_exception <exception>");

	boxRoundCorners domain_error(boxColor, Point(500, 20), 200, 30, 5, textColor, "domain_error <stdexception>");
	boxRoundCorners invalid_argument(boxColor, Point(500, 70), 200, 30, 5, textColor, "invalid_argument <stdexcept>");
	boxRoundCorners length_error(boxColor, Point(500, 120), 200, 30, 5, textColor, "length_error <stdexcept>");
	boxRoundCorners out_of_range(boxColor, Point(500, 170), 200, 30, 5, textColor, "out_of_range <stdexcept>");
	boxRoundCorners range_error(boxColor, Point(500, 220), 200, 30, 5, textColor, "range_error <stdexcept>");
	boxRoundCorners overflow_error(boxColor, Point(500, 270), 200, 30, 5, textColor, "overflow_error <stdexcept>");
	boxRoundCorners underflow_error(boxColor, Point(500, 320), 200, 30, 5, textColor, "underflow_error <stdexcept>");

	Line l1(exc.get_east(), Point(exc.get_east().x + 30, exc.get_east().y));
	l1.set_color(Color::black);

	Line l2(Point(exc.get_east().x + 30, 35), Point(exc.get_east().x + 30, 335));
	l2.set_color(Color::black);

	Line l3(Point(exc.get_east().x + 30, 35), bad_cast.get_west());
	l3.set_color(Color::black);

	Line l4(Point(bad_typeid.get_west().x - 50, 85), bad_typeid.get_west());
	l4.set_color(Color::black);

	Line l5(Point(logic_error.get_west().x - 50, 135), logic_error.get_west());
	l5.set_color(Color::black);

	Line l6(Point(bad_alloc.get_west().x - 50, 185), bad_alloc.get_west());
	l6.set_color(Color::black);

	Line l7(Point(Ios_base.get_west().x - 50, 235), Ios_base.get_west());
	l7.set_color(Color::black);

	Line l8(Point(runtime_error.get_west().x - 50, 285), runtime_error.get_west());
	l8.set_color(Color::black);

	Line l9(Point(bad_exception.get_west().x - 50, 335), bad_exception.get_west());
	l9.set_color(Color::black);


	Line l10(Point(logic_error.get_east()), length_error.get_west());
	l10.set_color(Color::black);

	Line l11(Point(runtime_error.get_east()), overflow_error.get_west());
	l11.set_color(Color::black);

	Line l12(Point(domain_error.get_west().x - 30, domain_error.get_west().y), Point(out_of_range.get_west().x - 30, out_of_range.get_west().y));
	l12.set_color(Color::black);

	Line l13(Point(range_error.get_west().x - 30, range_error.get_west().y), Point(underflow_error.get_west().x - 30, underflow_error.get_west().y));
	l13.set_color(Color::black);

	Line l14(Point(domain_error.get_west().x - 30, domain_error.get_west().y), domain_error.get_west());
	l14.set_color(Color::black);

	Line l15(Point(invalid_argument.get_west().x - 30, invalid_argument.get_west().y), invalid_argument.get_west());
	l15.set_color(Color::black);

	Line l16(Point(length_error.get_west().x - 30, length_error.get_west().y), length_error.get_west());
	l16.set_color(Color::black);

	Line l17(Point(out_of_range.get_west().x - 30, out_of_range.get_west().y), out_of_range.get_west());
	l17.set_color(Color::black);

	Line l18(Point(range_error.get_west().x - 30, range_error.get_west().y), range_error.get_west());
	l18.set_color(Color::black);
	
	Line l19(Point(overflow_error.get_west().x - 30, overflow_error.get_west().y), overflow_error.get_west());
	l19.set_color(Color::black);

	Line l20(Point(underflow_error.get_west().x - 30, underflow_error.get_west().y), underflow_error.get_west());
	l20.set_color(Color::black);

	win.attach(exc);

	win.attach(bad_cast);
	win.attach(bad_typeid);
	win.attach(logic_error);
	win.attach(bad_alloc);
	win.attach(Ios_base);
	win.attach(runtime_error);
	win.attach(bad_exception);

	win.attach(domain_error);
	win.attach(invalid_argument);
	win.attach(length_error);
	win.attach(out_of_range);
	win.attach(range_error);
	win.attach(overflow_error);
	win.attach(underflow_error);

	win.attach(l1);
	win.attach(l2);
	win.attach(l3);
	win.attach(l4);
	win.attach(l5);
	win.attach(l6);
	win.attach(l7);
	win.attach(l8);
	win.attach(l9);

	win.attach(l10);
	win.attach(l11);
	win.attach(l12);
	win.attach(l13);
	win.attach(l14);
	win.attach(l15);
	win.attach(l16);
	win.attach(l17);
	win.attach(l18);
	win.attach(l19);
	win.attach(l20);

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

virtual controller class [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 14 Exercise 16

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

using namespace Graph_lib;

class Controller
{
public:
	virtual void set_on() = 0;
	virtual void set_off() = 0;
	virtual void set_level(int l) = 0;
	virtual void show() = 0;
protected:
	bool on;
	bool off;
	int level;
};

class Controller_test : public Controller
{
public:
	void set_on();
	void set_off();
	void set_level(int l);
	void show();
};

void Controller_test::set_on()
{
	on = true;
	off = false;
}

void Controller_test::set_off()
{
	on = false;
	off = true;
}

void Controller_test::set_level(int l)
{
	level = l;
}

void Controller_test::show()
{
	cout << "on = " << on << ", off = " << off << ", level = " << level << endl;
}

class Controller_shape : public Controller
{
public:
	Controller_shape(Shape& shape) :s(shape) {};
	void set_on();
	void set_off();
	void set_level(int l);
	void show();

private:
	Shape& s;
};

void Controller_shape::set_on()
{
	s.set_color(Color::visible);
	on = true;
	off = false;
}

void Controller_shape::set_off()
{
	s.set_color(Color::invisible);
	on = false;
	off = true;
}

void Controller_shape::set_level(int l)
{
	s.set_style(Line_style(l));
}

void Controller_shape::show()
{
	s.set_fill_color(Color::cyan);
}

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);
	
	Controller_test ct;
	ct.set_on();
	ct.set_level(5);
	ct.show();

	Graph_lib::Rectangle r(Point(200, 200), Point(400, 300));

	Controller_shape cs(r);
	cs.set_on();
	cs.show();
	cs.set_level(1);
	
	win.attach(r);
	win.wait_for_button();
}
catch (exception& e) {
	cout << e.what() << endl;
	return 1;
}
catch (...) {
	cout << "Exiting" << endl;
	return 2;
}
Output:
on = 1, off = 0, level = 5

list and vector iterator [fltk]

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

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 14 Exercise 15

#include "std_lib_facilities.h"

class Base_iterator
{
public:
	virtual double* next() = 0;
protected:
	int count;
};

//------------------------VECTOR ITERATOR

class Vector_iterator : public Base_iterator
{
public:
	Vector_iterator(vector<double>& v);
	double* next();
private:
	vector<double> vec;
};

Vector_iterator::Vector_iterator(vector<double>& v)
{
	vec = v;
	count = 0;
}

double* Vector_iterator::next()
{
	if (vec.size() > 0 && count < vec.size()) {
		
		count++;
		return &vec[count - 1];
	}
	else {
		return 0;
	}
}

//------------------------LIST ITERATOR

class List_iterator : public Base_iterator
{
public:
	List_iterator(list<double>& l);
	double* next();
private:
	list<double> lis;
	list<double>::iterator pointer;
};

List_iterator::List_iterator(list<double>& l)
{
	lis = l;
	pointer = lis.begin();
}

double* List_iterator::next() {
	double* p;

	if (lis.size() && lis.size() > distance(lis.begin(), pointer)) {
		p = &*pointer;
		pointer++;
		return p;
	}
	else return 0;
}

void print(Base_iterator& iterator)
{
	double* pointer;
	pointer = iterator.next();

	while (pointer != 0) {
		cout << *pointer << endl;
		pointer = iterator.next();
	}
}

int main()
try
{
	vector<double> v;
	v.push_back(2.0);
	v.push_back(2.1);
	v.push_back(2.2);
	v.push_back(2.3);

	list<double> l;
	l.push_back(2.0);
	l.push_back(2.1);
	l.push_back(2.2);
	l.push_back(2.3);

	Vector_iterator vi(v);
	print(vi);

	List_iterator li(l);
	print(li);

	keep_window_open();
}
catch (exception& e) {
	cout << e.what() << endl;
	return 1;
}
catch (...) {
	cout << "Exiting" << endl;
	return 2;
}
Output:
2
2.1
2.2
2.3
2
2.1
2.2
2.3
Please enter a character to exit

draw a binary tree, node identification labels [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 14 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;
}

//-----------------------ARROW CLASS--------------------------------

struct MyArrow : public Shape
{
	MyArrow(Point start, Point end, bool s, bool e, int size, Color col);
	~MyArrow() {}

	void draw_lines() const;
	double pointVecMag(Point vec);

private:
	//Line
	Point start;
	Point end;

	//Arrowhead at start
	Point c;
	Point cUnit;
	Point cTrans;
	Point cPerp;
	double cMag;

	Point arrowhead01;
	Point arrowhead02;

	//Arrowhead at end
	Point d;
	Point dUnit;
	Point dTrans;
	Point dPerp;
	double dMag;

	Point arrowhead03;
	Point arrowhead04;

	bool s;
	bool e;
	int size;

	Color flc;
};

MyArrow::MyArrow(Point start, Point end, bool s, bool e, int size, Color col)
	:start(start), end(end), s(s), e(e), size(size), flc(col)
{
	if (s) {
		//end-start vector: c
		c = Point(end.x - start.x, end.y - start.y);
		cMag = pointVecMag(c);
		cUnit = Point(c.x / cMag * size, c.y / cMag * size);
		cTrans = Point(cUnit.x, cUnit.y);

		//Arrow Head Start
		cPerp = Point(-cTrans.y, cTrans.x);
		arrowhead01 = Point(start.x + cPerp.x + cTrans.x, start.y + cPerp.y + cTrans.y);
		arrowhead02 = Point(start.x - cPerp.x + cTrans.x, start.y - cPerp.y + cTrans.y);
	}
	if (e) {
		//start-end vector: d
		d = Point(start.x - end.x, start.y - end.y);
		dMag = pointVecMag(d);
		dUnit = Point(d.x / dMag * size, d.y / dMag * size);
		dTrans = Point(dUnit.x, dUnit.y);

		//Arrow Head End
		dPerp = Point(-dTrans.y, dTrans.x);
		arrowhead03 = Point(end.x + dPerp.x + dTrans.x, end.y + dPerp.y + dTrans.y);
		arrowhead04 = Point(end.x - dPerp.x + dTrans.x, end.y - dPerp.y + dTrans.y);
	}
}

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

void MyArrow::draw_lines() const {

	fl_color(flc.as_int());
	if (color().visibility()) {
		//Line
		fl_line(start.x, start.y, end.x, end.y);
		//Arrowhead at start
		if (s) {
			fl_line(start.x, start.y, arrowhead01.x, arrowhead01.y);
			fl_line(start.x, start.y, arrowhead02.x, arrowhead02.y);
		}
		//Arrowhead at end
		if (e) {
			fl_line(end.x, end.y, arrowhead03.x, arrowhead03.y);
			fl_line(end.x, end.y, arrowhead04.x, arrowhead04.y);
		}
	}
}

//-----------------------BINARY TREE CLASS--------------------------------

enum line_type { arrow_up = 0, arrow_down, arrow_both_ways, line };

class Binary_tree : public Shape
{
public:
	Binary_tree(Point root, int levels, line_type line_type, Color col)
		:r(root), l(levels), lt(line_type), col(col)
	{
		initialize_nodes();
	}
	~Binary_tree() {}

	void initialize_nodes();
	void draw_lines() const;

private:
	Point r;
	int l;
	vector<Point> node_points;
	line_type lt;

	Color col;
	vector<string> labels;
};

void Binary_tree::initialize_nodes()
{
	double nodes = 1.0;
	bool left = true;	
	double tree_w = l * 130;
	int y = 0;

	for (int i = 0; i < l; i++) {		
		for (double j = -(nodes / 2); j < (nodes / 2); j++) {
			cout << i << ", " << y << endl;
			if (i == 0) {
				node_points.push_back(Point(r.x + j, r.y + i * 50));
				labels.push_back("lr");
			}
			else {				
				node_points.push_back(Point(r.x + (double(tree_w / nodes) / 2) + (j * double(tree_w / nodes)), r.y + i * 50));

				if (left) {
					labels.push_back(labels[y] + "l");
					left = false;
				}
				else {
					labels.push_back(labels[y] + "r");
					left = true;
					y++;
				}				
			}			
		}
		nodes *= 2;
	}
}

void Binary_tree::draw_lines() const
{
	// draw nodes
	for (int i = 0; i < node_points.size(); i++) {
		Circle c(node_points[i], 2);		
		c.set_style(Line_style(Line_style::solid, 2));
		c.draw();

		Text t(Point(node_points[i].x + 5, node_points[i].y + 5), labels[i]);
		t.set_color(Color::blue);
		t.draw();
	}

	// draw connecting lines
	int node = 2;
	string l = labels[0];

	for (int i = 0; i < node_points.size() - ((node_points.size() + 1) / 2); i++) {
		for (int j = 1; j < 3; j++) {

			Point from(node_points[i].x, node_points[i].y + 5);
			Point to(node_points[i * node + j].x, node_points[i * node + j].y - 5);

			//enum line_type { arrow_up, arrow_down, arrow_both_ways, line };
			switch (lt)
			{
			case arrow_up:
				MyArrow(from, to, true, false, 5, col).draw_lines();
				break;
			case arrow_down:
				MyArrow(from, to, false, true, 5, col).draw_lines();
				break;
			case arrow_both_ways:
				MyArrow(from, to, true, true, 5, col).draw_lines();
				break;
			case line:
				Line l(from, to);
				l.set_color(col);
				l.draw();
				break;
			}
		}
	}
}

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);

	Binary_tree tree(Point(center.x, 20), 5, line_type::line, Color::blue);
	tree.set_color(Color::red);

	win.attach(tree);

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

draw a binary tree, arrow node connection [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 14 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;
}

//-----------------------ARROW CLASS--------------------------------

struct MyArrow : public Shape
{
	MyArrow(Point start, Point end, bool s, bool e, int size, Color col);
	~MyArrow() {}

	void draw_lines() const;
	double pointVecMag(Point vec);

private:
	//Line
	Point start;
	Point end;

	//Arrowhead at start
	Point c;
	Point cUnit;
	Point cTrans;
	Point cPerp;
	double cMag;

	Point arrowhead01;
	Point arrowhead02;

	//Arrowhead at end
	Point d;
	Point dUnit;
	Point dTrans;
	Point dPerp;
	double dMag;

	Point arrowhead03;
	Point arrowhead04;

	bool s;
	bool e;
	int size;

	Color flc;
};

MyArrow::MyArrow(Point start, Point end, bool s, bool e, int size, Color col)
	:start(start), end(end), s(s), e(e), size(size), flc(col)
{
	if (s) {
		//end-start vector: c
		c = Point(end.x - start.x, end.y - start.y);
		cMag = pointVecMag(c);
		cUnit = Point(c.x / cMag * size, c.y / cMag * size);
		cTrans = Point(cUnit.x, cUnit.y);

		//Arrow Head Start
		cPerp = Point(-cTrans.y, cTrans.x);
		arrowhead01 = Point(start.x + cPerp.x + cTrans.x, start.y + cPerp.y + cTrans.y);
		arrowhead02 = Point(start.x - cPerp.x + cTrans.x, start.y - cPerp.y + cTrans.y);
	}
	if (e) {
		//start-end vector: d
		d = Point(start.x - end.x, start.y - end.y);
		dMag = pointVecMag(d);
		dUnit = Point(d.x / dMag * size, d.y / dMag * size);
		dTrans = Point(dUnit.x, dUnit.y);

		//Arrow Head End
		dPerp = Point(-dTrans.y, dTrans.x);
		arrowhead03 = Point(end.x + dPerp.x + dTrans.x, end.y + dPerp.y + dTrans.y);
		arrowhead04 = Point(end.x - dPerp.x + dTrans.x, end.y - dPerp.y + dTrans.y);
	}
}

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

void MyArrow::draw_lines() const {

	fl_color(flc.as_int());
	if (color().visibility()) {
		//Line
		fl_line(start.x, start.y, end.x, end.y);
		//Arrowhead at start
		if (s) {
			fl_line(start.x, start.y, arrowhead01.x, arrowhead01.y);
			fl_line(start.x, start.y, arrowhead02.x, arrowhead02.y);
		}
		//Arrowhead at end
		if (e) {
			fl_line(end.x, end.y, arrowhead03.x, arrowhead03.y);
			fl_line(end.x, end.y, arrowhead04.x, arrowhead04.y);
		}
	}
}

//-----------------------BINARY TREE CLASS--------------------------------

enum line_type { arrow_up = 0, arrow_down, arrow_both_ways, line };

class Binary_tree : public Shape
{
public:
	Binary_tree(Point root, int levels, line_type line_type, Color col)
		:r(root), l(levels), lt(line_type), col(col)
	{
		initialize_nodes();
	}
	~Binary_tree() {}

	void initialize_nodes();
	void draw_lines() const;

private:
	Point r;
	int l;
	vector<Point> node_points;
	line_type lt;

	Color col;
};

void Binary_tree::initialize_nodes()
{
	double nodes = 1.0;

	double tree_w = l * 100;

	for (int i = 0; i < l; i++) {
		for (double j = -(nodes / 2); j < (nodes / 2); j++) {
			if (i == 0) {
				node_points.push_back(Point(r.x + j, r.y + i * 30));
			}
			else {
				node_points.push_back(Point(r.x + (double(tree_w / nodes) / 2) + (j * double(tree_w / nodes)), r.y + i * 30));
			}
		}
		nodes *= 2;
	}
}

void Binary_tree::draw_lines() const
{
	// draw nodes
	for (int i = 0; i < node_points.size(); i++) {
		Circle c(node_points[i], 5);
		c.set_style(Line_style(Line_style::solid, 2));
		c.draw();
	}

	// draw connecting lines
	int node = 2;

	for (int i = 0; i < node_points.size() - ((node_points.size() + 1) / 2); i++) {
		for (int j = 1; j < 3; j++) {

			Point from(node_points[i].x, node_points[i].y + 5);
			Point to(node_points[i * node + j].x, node_points[i * node + j].y - 5);
			
			//enum line_type { arrow_up, arrow_down, arrow_both_ways, line };
			switch (lt)
			{
			case arrow_up:
				MyArrow(from, to, true, false, 5, col).draw_lines();
				break;
			case arrow_down:
				MyArrow(from, to, false, true, 5, col).draw_lines();
				break;
			case arrow_both_ways:
				MyArrow(from, to, true, true, 5, col).draw_lines();
				break;
			case line:
				Line l(from, to);
				l.set_color(col);
				l.draw();
				break;

			}
		}
	}
}

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);

	Binary_tree tree(Point(center.x, 20), 7, line_type::arrow_down, Color::blue);
	tree.set_color(Color::red);

	win.attach(tree);

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

draw a binary tree, triangle node virtual function override [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 14 Exercise 12

#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 rotate_triangle(double rad);
	void draw_lines() const;

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

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

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

void Regular_triangle::rotate_triangle(double rad)
{
	Point origin_Pt1 = Regular_triangle::point(0) - Regular_triangle::point(2);
	Point origin_Pt2 = Regular_triangle::point(1) - Regular_triangle::point(2);

	Point rotated_Pt1 = Point(cos(rad) * origin_Pt1.x - sin(rad) * origin_Pt1.y, sin(rad) * origin_Pt1.x + cos(rad) * origin_Pt1.y);
	Point rotated_Pt2 = Point(cos(rad) * origin_Pt2.x - sin(rad) * origin_Pt2.y, sin(rad) * origin_Pt2.x + cos(rad) * origin_Pt2.y);

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

class Binary_tree : public Shape
{
public:
	Binary_tree(Point root, int levels)
		:r(root), l(levels)
	{
		initialize_nodes();
	}
	~Binary_tree() {}

	void initialize_nodes();
	virtual void draw_lines() const;
	
	vector<Point> get_node_points() const { return node_points;  }


private:
	Point r;
	int l;
	vector<Point> node_points;

};

void Binary_tree::initialize_nodes()
{
	double nodes = 1.0;

	double tree_w = l * 100;

	for (int i = 0; i < l; i++) {
		for (double j = -(nodes / 2); j < (nodes / 2); j++) {
			if (i == 0) {
				node_points.push_back(Point(r.x + j, r.y + i * 30));
			}
			else {
				node_points.push_back(Point(r.x + (double(tree_w / nodes) / 2) + (j * double(tree_w / nodes)), r.y + i * 30));
			}
		}
		nodes *= 2;
	}
}

void Binary_tree::draw_lines() const
{
	// draw nodes
	for (int i = 0; i < node_points.size(); i++) {
		Circle c(node_points[i], 5);
		c.set_style(Line_style(Line_style::solid, 2));
		c.draw();
	}

	// draw connecting lines
	int node = 2;

	for (int i = 0; i < node_points.size() - ((node_points.size() + 1) / 2); i++) {
		for (int j = 1; j < 3; j++) {

			Point from(node_points[i].x, node_points[i].y + 5);
			Point to(node_points[i * node + j].x, node_points[i * node + j].y - 5);

			Line(from, to).draw();
		}
	}
}

class Binary_tree_triangle_nodes : public Binary_tree
{
public:
	Binary_tree_triangle_nodes(Point root, int levels)
		:Binary_tree(root, levels) {}
	~Binary_tree_triangle_nodes() {}

	void draw_lines() const override;
};

void Binary_tree_triangle_nodes::draw_lines() const
{
	vector<Point> node_points = Binary_tree::get_node_points();

	// draw nodes
	for (int i = 0; i < node_points.size(); i++) {

		Point origin(node_points[i].x - 5, node_points[i].y + 5);
		Regular_triangle t(origin, 10, 10, Fl_Color(0));
		t.set_style(Line_style(Line_style::solid, 2));
		t.draw();
	}

	// draw connecting lines
	int node = 2;

	for (int i = 0; i < node_points.size() - ((node_points.size() + 1) / 2); i++) {
		for (int j = 1; j < 3; j++) {

			Point from(node_points[i].x, node_points[i].y + 5);
			Point to(node_points[i * node + j].x, node_points[i * node + j].y - 5);

			Line(from, to).draw();
		}
	}
}

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);

	//Binary_tree tree(Point(center.x, 20), 7);

	Binary_tree_triangle_nodes tree(Point(center.x, 20), 7);
	
	tree.set_color(Color::red);

	win.attach(tree);

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

draw a binary tree [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 14 Exercise 11

#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;
}

class Binary_tree : public Shape
{
public:
	Binary_tree(Point root, int levels)
		:r(root), l(levels)
	{
		initialize_nodes();
	}
	~Binary_tree() {}

	void initialize_nodes();
	void draw_lines() const;

	

private:
	Point r;
	int l;
	vector<Point> node_points;

};

void Binary_tree::initialize_nodes()
{
	double nodes = 1.0;

	double tree_w = l * 100;

	for (int i = 0; i < l; i++) {
		for (double j = -(nodes / 2); j < (nodes / 2); j++) {
			if (i == 0) {
				node_points.push_back(Point(r.x + j, r.y + i * 30));
			}
			else {
				node_points.push_back(Point(r.x + (double(tree_w / nodes) / 2) + (j * double(tree_w / nodes)), r.y + i * 30));
			}			
		}
		nodes *= 2;
	}
}

void Binary_tree::draw_lines() const
{
	// draw nodes
	for (int i = 0; i < node_points.size(); i++) {		
		Circle c(node_points[i], 5);
		c.set_style(Line_style(Line_style::solid, 2));
		c.draw();
	}

	// draw connecting lines
	int node = 2;

	for (int i = 0; i < node_points.size() - ((node_points.size() + 1) / 2); i++) {
		for (int j = 1; j < 3; j++) {

			Point from(node_points[i].x, node_points[i].y + 5);
			Point to(node_points[i * node + j].x, node_points[i * node + j].y - 5);

			Line(from, to).draw();
		}
	}
}

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);

	Binary_tree tree(Point(center.x, 20), 7);
	tree.set_color(Color::red);
	
	win.attach(tree);

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

pseudo window class [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 14 Exercise 10

#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 Pseudo_window : public Shape
{
	Pseudo_window(Point origin, int width, int height, int radius, string label, string content_location)
	: o(origin), w(width), h(height), r(radius), l(label), content_location(content_location)
	{
		initialize_outline();
		initialize_label_bar();
	};

	void draw_lines() const;
	void initialize_outline();
	void initialize_label_bar();

private:
	Point o;
	Point a1, a2, b1, b2, c1, c2, d1, d2;
	Point a3, b3, c3, d3;
	int w, h, r;
	string l;

	Point bar_line_s; // label bar line start
	Point bar_line_e; // label bar line end

	Point bar_close_s;
	Point bar_close_e;

	Point bar_extend_s;
	Point bar_extend_e;

	Point bar_minimize_s;
	Point bar_minimize_e;

	string content_location;
};

void Pseudo_window::initialize_outline()
{
	a1 = Point(o.x + r, o.y);
	b1 = Point(o.x + w - r, o.y);
	b2 = Point(o.x + w, o.y + r);
	c1 = Point(o.x + w, o.y + h - r);
	c2 = Point(o.x + w - r, o.y + h);
	d1 = Point(o.x + r, o.y + h);
	d2 = Point(o.x, o.y + h - r);
	a2 = Point(o.x, o.y + r);

	a3 = Point(o.x + r, o.y + r);
	b3 = Point(o.x + w - r, o.y + r);
	c3 = Point(o.x + w - r, o.y + h - r);
	d3 = Point(o.x + r, o.y + h - r);
}

void Pseudo_window::initialize_label_bar()
{
	// add point for label text
	add(Point(o.x + 10, o.y + 17));

	// add points for label bar line
	bar_line_s = Point(o.x + 3, o.y + 23);
	bar_line_e = Point(o.x + w - 3, o.y + 23);

	// add label bar buttons
	bar_close_s = Point(o.x + w - 20, o.y + 7);
	bar_close_e = Point(o.x + w - 10, o.y + 17);

	bar_extend_s = Point(o.x + w - 40, o.y + 7);
	bar_extend_e = Point(o.x + w - 30, o.y + 17);

	bar_minimize_s = Point(o.x + w - 60, o.y + 7);
	bar_minimize_e = Point(o.x + w - 50, o.y + 17);
}

void Pseudo_window::draw_lines() const
{
	// buttons
	Graph_lib::Rectangle close(bar_close_s, bar_close_e);
	Graph_lib::Rectangle extend(bar_extend_s, bar_extend_e);
	Graph_lib::Rectangle minimize(bar_minimize_s, bar_minimize_e);

	close.set_fill_color(Color::red);
	extend.set_fill_color(Color::green);
	minimize.set_fill_color(Color::yellow);

	// image content
	Image image0(Point(o.x + 10, o.y + 33), content_location);
	image0.set_mask(Point(o.x + 100, o.y + 300), w - 20, h - 20 - 23);

	// content window
	Graph_lib::Rectangle content_rect(Point(o.x + 10, o.y + 33), Point(o.x + w - 10, o.y + h - 10));

	if (color().visibility()) {
		// draw label bar text
		fl_draw(l.c_str(), point(0).x, point(0).y);

		// draw label bar line
		fl_line(bar_line_s.x, bar_line_s.y, bar_line_e.x, bar_line_e.y);

		// draw buttons
		close.draw();
		extend.draw();
		minimize.draw();

		// draw content image
		image0.draw();

		// draw content rectangle
		content_rect.draw();
				
		fl_line(a1.x, a1.y, b1.x, b1.y);
		fl_line(b2.x, b2.y, c1.x, c1.y);
		fl_line(c2.x, c2.y, d1.x, d1.y);
		fl_line(d2.x, d2.y, a2.x, a2.y);

		fl_arc(o.x, o.y, r + r, r + r, 90, 180);
		fl_arc(o.x + w - (r + r), o.y, r + r, r + r, 360, 90);
		fl_arc(o.x + w - (r + r), o.y + h - (r + r), r + r, r + r, 270, 360);
		fl_arc(o.x, o.y + h - (r + r), r + r, r + r, 180, 270);
	}
}

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);
	
	Pseudo_window p_win(Point(60, 50), 600, 300, 10, "pseudowin", "Input/Original-JPG-Image_large.jpg");
	p_win.set_color(Color::black);

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

using a group class container to draw checkers board with movable piece [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 14 Exercise 9

#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 Group : Shape
{
	void add_board_shape(Shape& shape) { b.push_back(shape); }
	void add_piece_shape(Shape& shape) { p.push_back(shape); }

	void draw_lines() const;
	void move_piece(int index, int dx, int dy);
		
	Vector_ref<Shape> shapes() { return b; }

private:
	Vector_ref<Shape> b;
	Vector_ref<Shape> p;
};

void Group::draw_lines() const
{
	for (int i = 0; i < b.size(); ++i) {
		b[i].draw();		
	}
	for (int i = 0; i < p.size(); ++i) {
		p[i].draw();
	}

}

void Group::move_piece(int index, int fieldx, int fieldy)
{
	int dx = fieldx * 100;
	int dy = fieldy * 100;
	p[index].move(dx, dy);
}

void initialize_checkers_board(Group& group, Vector_ref<Graph_lib::Rectangle>& board)
{
	for (int i = 0; i < 8; i++) {
		for (int j = 0; j < 8; j++) {
			// pushback to vector_ref
			board.push_back(new Graph_lib::Rectangle(Point(j * 100, i * 100), Point(j * 100 + 100, i * 100 + 100)));

			// setup color of checkers_board
			if (i % 2 == 0) {
				if (((i * 8) + j) % 2 == 0) {
					board[i * 8 + j].set_fill_color(Color::black);
				}
				else {
					board[i * 8 + j].set_fill_color(Color::white);
				}
			}
			else {
				if (((i * 8) + j) % 2 == 0) {
					board[i * 8 + j].set_fill_color(Color::white);
				}
				else {
					board[i * 8 + j].set_fill_color(Color::black);
				}
			}

			// add rectangle to checkers_board Group
			group.add_board_shape(board[i * 8 + j]);
		}
	}
}

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

	Group checkers_board;
	Vector_ref<Graph_lib::Rectangle> board;
	Vector_ref<Graph_lib::Circle> pieces;
	initialize_checkers_board(checkers_board, board);

	pieces.push_back(new Graph_lib::Circle(Point(50, 50), 40));
	pieces[0].set_color(Color::black);
	pieces[0].set_fill_color(Color::white);
	checkers_board.add_piece_shape(pieces[0]);

	win.attach(checkers_board);
	win.wait_for_button();

	checkers_board.move_piece(0, 3, 4);
	win.attach(checkers_board);
	
	win.wait_for_button();
}
catch (exception& e) {
	cout << e.what() << endl;
	return 1;
}
catch (...) {
	cout << "Exiting" << endl;
	return 2;
}

testing all octagon class methods [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 14 Exercise 8

#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_octagon : Closed_polyline
{
	Regular_octagon(Point origin, int radius)
		: o(origin), r(radius)
	{
		set_color(Color::red);
		generate_points();
	};

	void draw_lines() const;
	
private:
	Point o;
	vector<Point> pts;
	int r;

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

};

void Regular_octagon::generate_points()
{
	int n = 8;
	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)));
		Closed_polyline::add(pts[i]);
	}
};

void Regular_octagon::draw_lines() const
{
	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);

	Regular_octagon o(center, 50);

	// add();
	// o.add(); // function inaccesible
	
	// color();
	cout << o.color().as_int() << endl; // Output: 88
	cout << o.color().black << endl; // Output: 56
	cout << o.color().blue << endl; // Output: 216
	cout << o.color().cyan << endl; // Output: 223
	cout << o.color().dark_blue << endl; // Output: 136
	cout << o.color().dark_cyan << endl; // Output: 140
	cout << o.color().dark_green << endl; // Output: 60
	cout << o.color().dark_magenta << endl; // Output: 152
	cout << o.color().dark_red << endl; // Output: 72
	cout << o.color().dark_yellow << endl; // Output: 76
	cout << o.color().green << endl; // Output: 63
	cout << o.color().invisible << endl; // Output: 0
	cout << o.color().magenta << endl; // Output: 248
	cout << o.color().red << endl; // Output: 88
	o.color().set_visibility(Color::Transparency(0));
	o.color().visibility();

	// draw();
	o.draw();

	// draw_lines();
	o.draw_lines();

	// fill_color();
	cout << o.fill_color().as_int() << endl; // Output: 88
	cout << o.fill_color().black << endl; // Output: 56
	cout << o.fill_color().blue << endl; // Output: 216
	cout << o.fill_color().cyan << endl; // Output: 223
	cout << o.fill_color().dark_blue << endl; // Output: 136
	cout << o.fill_color().dark_cyan << endl; // Output: 140
	cout << o.fill_color().dark_green << endl; // Output: 60
	cout << o.fill_color().dark_magenta << endl; // Output: 152
	cout << o.fill_color().dark_red << endl; // Output: 72
	cout << o.fill_color().dark_yellow << endl; // Output: 76
	cout << o.fill_color().green << endl; // Output: 63
	cout << o.fill_color().invisible << endl; // Output: 0
	cout << o.fill_color().magenta << endl; // Output: 248
	cout << o.fill_color().red << endl; // Output: 88
	o.fill_color().set_visibility(Color::Transparency::invisible);
	o.fill_color().set_visibility(Color::Transparency::visible);
	o.fill_color().visibility();

	// move();
	o.move(100, -100);

	// number_of_points();
	cout << o.number_of_points() << endl; // Output: 8

	// Open_polyline
	//o.Open_polyline.add(Point(100, 100)); // typename is not allowed
	
	// point();
	cout << o.point(0) << endl; // Output: (510,100)

	// set_color();
	o.set_color(Color::red); // sets color to red
	
	// set_fill_color();
	o.set_fill_color(Color::cyan); // sets fill_color to cyan

	// set_style();
	o.set_style(Line_style(Line_style::dash, 5)); // sets line style: dashed, 5 width

	// Shape
	//o.Shape // typename is not allowed

	// style();
	cout << o.style().dash << endl; // Output: 1
	cout << o.style().dashdot << endl; // Output: 3
	cout << o.style().dashdotdot << endl; // Output: 4
	cout << o.style().dot << endl; // Output: 2
	cout << o.style().solid << endl; // Output: 0
	cout << o.style().style() << endl; // Output: 1
	cout << o.style().width() << endl; // Output: 5

	// ~Shape
	//o.~Shape // invalid destructor name for type "Regular_octagon"

	win.attach(o);
	win.wait_for_button();
}
catch (exception& e) {
	cout << e.what() << endl;
	return 1;
}
catch (...) {
	cout << "Exiting" << endl;
	return 2;
}
Output:
88
56
216
223
136
140
60
152
72
76
63
0
248
88
0
56
216
223
136
140
60
152
72
76
63
0
248
88
8
(510,100)
1
3
4
2
0
1
5