exploring the window class [fltk]

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

Output:

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

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

// layout
constexpr int xmax = 600;
constexpr int ymax = 400;

struct My_window : Window {
	My_window(Point xy, int w, int h, const string& title)
		: Window(xy, w, h, title),
		next_button_pushed(false),
		next_button(Point(x_max() - 140, 0), 70, 20, "Next", cb_next),
		quit_button_pushed(false),
		quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit)
	{
		attach(next_button);
		attach(quit_button);
	}

	void wait_for_button()
		// modified event loop
		// handle all events (as per default), but quit when button_pushed becomes true
		// this allows graphics without control inversion
	{
		while (!next_button_pushed) Fl::wait();
		next_button_pushed = false;
		Fl::redraw();
	}

	Button next_button;
	Button quit_button;

private:
	bool next_button_pushed;
	bool quit_button_pushed;

	static void cb_next(Address, Address addr) // callback for next_button
											   //	{ reference_to<Simple_window>(addr).next(); }
	{
		reference_to<My_window>(addr).next();
	}

	static void cb_quit(Address, Address addr) // callback for quit_button
											   //	{ reference_to<Simple_window>(addr).quit(); }
	{
		reference_to<My_window>(addr).quit();
	}

	void next() { next_button_pushed = true; }
	void quit() { hide(); }
};

int main()
try
{
	My_window win(Point(100, 100), xmax, ymax, "quit+next");
	return gui_main();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

line drawing program + color & linestyle menu [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Drill 4

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

// layout
constexpr int xmax = 600;
constexpr int ymax = 400;

struct Lines_window : Window {
	Lines_window(Point xy, int w, int h, const string& title);
private:
	// data
	Open_polyline lines;

	// widgets
	Button next_button;	// add (next_x, next_y) to lines
	Button quit_button;	// end program
	In_box next_x;
	In_box next_y;
	Out_box xy_out;

	// color menu
	Menu color_menu;
	Button color_menu_button;
	void change_color(Color c) { lines.set_color(c); }
	void hide_color_menu() { color_menu.hide(); color_menu_button.show(); }

	// line style menu
	Menu line_style_menu;
	Button line_style_menu_button;
	void change_line_style(Line_style ls) { lines.set_style(ls); }
	void hide_line_style_menu() { line_style_menu.hide(); line_style_menu_button.show(); }

	// actions invoked by callbacks
	// color menu
	void red_pressed() { change_color(Color::red); hide_color_menu(); }
	void blue_pressed() { change_color(Color::blue); hide_color_menu(); }
	void black_pressed() { change_color(Color::black); hide_color_menu(); }
	void color_menu_pressed() { color_menu_button.hide(); color_menu.show(); }

	// line style menu
	void solid_pressed() { change_line_style(Line_style::solid); hide_line_style_menu(); }
	void dashed_pressed() { change_line_style(Line_style::dash); hide_line_style_menu(); }
	void dotted_pressed() { change_line_style(Line_style::dot); hide_line_style_menu(); }
	void line_style_menu_pressed() { line_style_menu_button.hide(); line_style_menu.show(); }

	void next();
	void quit();

	// callback functions
	// color
	static void cb_red(Address, Address);
	static void cb_blue(Address, Address);
	static void cb_black(Address, Address);
	static void cb_color_menu(Address, Address);

	// line style
	static void cb_solid(Address, Address);
	static void cb_dash(Address, Address);
	static void cb_dot(Address, Address);
	static void cb_line_style_menu(Address, Address);

	static void cb_next(Address, Address);
	static void cb_quit(Address, Address);
};

Lines_window::Lines_window(Point xy, int w, int h, const string& title)
	:Window(xy, w, h, title),
	next_button(Point(x_max() - 150, 0), 70, 20, "Next point", cb_next),
	quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit),
	next_x(Point(x_max() - 310, 0), 50, 20, "next x:"),
	next_y(Point(x_max() - 210, 0), 50, 20, "next y:"),
	xy_out(Point(100, 0), 100, 20, "current (x,y):"),
	color_menu(Point(x_max() - 70, 30), 70, 20, Menu::vertical, "color"),
	color_menu_button(Point(x_max() - 80, 30), 80, 20, "color menu", cb_color_menu),
	line_style_menu(Point(x_max() - 70, 90), 70, 20, Menu::vertical, "line style"),
	line_style_menu_button(Point(x_max() - 80, 90), 80, 20, "style menu", cb_line_style_menu)
{
	attach(next_button);
	attach(quit_button);
	attach(next_x);
	attach(next_y);
	attach(xy_out);

	// initialize out box and line color
	xy_out.put("no point");
	lines.set_color(Color::black);

	color_menu.attach(new Button(Point(0, 0), 0, 0, "red", cb_red));
	color_menu.attach(new Button(Point(0, 0), 0, 0, "blue", cb_blue));
	color_menu.attach(new Button(Point(0, 0), 0, 0, "black", cb_black));

	line_style_menu.attach(new Button(Point(0, 0), 0, 0, "solid", cb_solid));
	line_style_menu.attach(new Button(Point(0, 0), 0, 0, "dashed", cb_dash));
	line_style_menu.attach(new Button(Point(0, 0), 0, 0, "dotted", cb_dot));

	attach(color_menu);
	attach(line_style_menu);

	color_menu.hide();
	line_style_menu.hide();

	attach(line_style_menu_button);
	attach(color_menu_button);
	attach(lines);
}

void Lines_window::next()
{
	int x = next_x.get_int();
	int y = next_y.get_int();

	lines.add(Point(x, y));

	// update current position readout
	ostringstream ss;
	ss << '(' << x << ',' << y << ')';
	xy_out.put(ss.str());

	redraw();
}

void Lines_window::quit()
{
	hide();
}

// color callback
void Lines_window::cb_red(Address, Address pw)
{
	reference_to<Lines_window>(pw).red_pressed();
}

void Lines_window::cb_blue(Address, Address pw)
{
	reference_to<Lines_window>(pw).blue_pressed();
}

void Lines_window::cb_black(Address, Address pw)
{
	reference_to<Lines_window>(pw).black_pressed();
}

void Lines_window::cb_color_menu(Address, Address pw)
{
	reference_to<Lines_window>(pw).color_menu_pressed();
}

// line style callback
void Lines_window::cb_solid(Address, Address pw)
{
	reference_to<Lines_window>(pw).solid_pressed();
}

void Lines_window::cb_dash(Address, Address pw)
{
	reference_to<Lines_window>(pw).dashed_pressed();
}

void Lines_window::cb_dot(Address, Address pw)
{
	reference_to<Lines_window>(pw).dotted_pressed();
}

void Lines_window::cb_line_style_menu(Address, Address pw)
{
	reference_to<Lines_window>(pw).line_style_menu_pressed();
}

// next + quit callback
void Lines_window::cb_next(Address, Address pw)
{
	reference_to<Lines_window>(pw).next();
}

void Lines_window::cb_quit(Address, Address pw)
{
	reference_to<Lines_window>(pw).quit();
}

int main()
try
{
	Lines_window win(Point(100, 100), xmax, ymax, "lines");
	return gui_main();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

line drawing program + color menu [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Drill 3

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

// layout
constexpr int xmax = 600;
constexpr int ymax = 400;

struct Lines_window : Window {
	Lines_window(Point xy, int w, int h, const string& title);
private:
	// data
	Open_polyline lines;

	// widgets
	Button next_button;	// add (next_x, next_y) to lines
	Button quit_button;	// end program
	In_box next_x;
	In_box next_y;
	Out_box xy_out;
	Menu color_menu;
	Button menu_button;

	void change(Color c) { lines.set_color(c); }

	void hide_menu() { color_menu.hide(); menu_button.show(); }

	// actions invoked by callbacks
	void red_pressed() { change(Color::red); hide_menu(); }
	void blue_pressed() { change(Color::blue); hide_menu(); }
	void black_pressed() { change(Color::black); hide_menu(); }
	void menu_pressed() { menu_button.hide(); color_menu.show(); }
	void next();
	void quit();

	// callback functions
	static void cb_red(Address, Address);
	static void cb_blue(Address, Address);
	static void cb_black(Address, Address);
	static void cb_menu(Address, Address);
	static void cb_next(Address, Address);
	static void cb_quit(Address, Address);
};

Lines_window::Lines_window(Point xy, int w, int h, const string& title)
	:Window(xy, w, h, title),
	next_button(Point(x_max() - 150, 0), 70, 20, "Next point", cb_next),
	quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit),
	next_x(Point(x_max() - 310, 0), 50, 20, "next x:"),
	next_y(Point(x_max() - 210, 0), 50, 20, "next y:"),
	xy_out(Point(100, 0), 100, 20, "current (x,y):"),
	color_menu(Point(x_max() - 70, 30), 70, 20, Menu::vertical, "color"),
	menu_button(Point(x_max() - 80, 30), 80, 20, "color menu", cb_menu)
{
	attach(next_button);
	attach(quit_button);
	attach(next_x);
	attach(next_y);
	attach(xy_out);
	xy_out.put("no point");
	color_menu.attach(new Button(Point(0, 0), 0, 0, "red", cb_red));
	color_menu.attach(new Button(Point(0, 0), 0, 0, "blue", cb_blue));
	color_menu.attach(new Button(Point(0, 0), 0, 0, "black", cb_black));
	attach(color_menu);
	color_menu.hide();
	attach(menu_button);
	attach(lines);
}

void Lines_window::next()
{
	int x = next_x.get_int();
	int y = next_y.get_int();

	lines.add(Point(x, y));

	// update current position readout
	ostringstream ss;
	ss << '(' << x << ',' << y << ')';
	xy_out.put(ss.str());

	redraw();
}

void Lines_window::quit()
{
	hide();
}

void Lines_window::cb_red(Address, Address pw)
{
	reference_to<Lines_window>(pw).red_pressed();
}

void Lines_window::cb_blue(Address, Address pw)
{
	reference_to<Lines_window>(pw).blue_pressed();
}

void Lines_window::cb_black(Address, Address pw)
{
	reference_to<Lines_window>(pw).black_pressed();
}

void Lines_window::cb_menu(Address, Address pw)
{
	reference_to<Lines_window>(pw).menu_pressed();
}

void Lines_window::cb_next(Address, Address pw)
{
	reference_to<Lines_window>(pw).next();
}

void Lines_window::cb_quit(Address, Address pw)
{
	reference_to<Lines_window>(pw).quit();
}

int main()
try
{
	Lines_window win(Point(100, 100), xmax, ymax, "lines");
	return gui_main();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

line drawing program [fltk]

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

Output:

//  Philipp Siedler
//  Bjarne Stroustrup's PP
//  Chapter 16 Drill 2

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

// layout
constexpr int xmax = 600;
constexpr int ymax = 400;

struct Lines_window : Window {
	Lines_window(Point xy, int w, int h, const string& title);
private:
	// data
	Open_polyline lines;

	// widgets
	Button next_button;	// add (next_x, next_y) to lines
	Button quit_button;	// end program
	In_box next_x;
	In_box next_y;
	Out_box xy_out;

	// actions invoked by callbacks
	void next();
	void quit();

	// callback functions
	static void cb_next(Address, Address);
	static void cb_quit(Address, Address);
};

Lines_window::Lines_window(Point xy, int w, int h, const string& title)
	:Window(xy, w, h, title),
	next_button(Point(x_max() - 150, 0), 70, 20, "Next point", cb_next),
	quit_button(Point(x_max() - 70, 0), 70, 20, "Quit", cb_quit),
	next_x(Point(x_max() - 310, 0), 50, 20, "next x:"),
	next_y(Point(x_max() - 210, 0), 50, 20, "next y:"),
	xy_out(Point(100, 0), 100, 20, "current (x,y):")
{
	attach(next_button);
	attach(quit_button);
	attach(next_x);
	attach(next_y);
	attach(xy_out);
	xy_out.put("no point");
	lines.set_color(Color::black);
	attach(lines);
}

void Lines_window::next()
{
	int x = next_x.get_int();
	int y = next_y.get_int();

	lines.add(Point(x, y));

	// update current position readout
	ostringstream ss;
	ss << '(' << x << ',' << y << ')';
	xy_out.put(ss.str());

	redraw();
}

void Lines_window::quit()
{
	hide();
}

void Lines_window::cb_next(Address, Address pw)
{
	reference_to<Lines_window>(pw).next();
}

void Lines_window::cb_quit(Address, Address pw)
{
	reference_to<Lines_window>(pw).quit();
}

int main()
try
{
	Lines_window win(Point(100, 100), xmax, ymax, "lines");
	return gui_main();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

Average temperature data of Cambridge, England and Cambridge, Massachusetts graphing [fltk]

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

Output:

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

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

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

// layout
constexpr int xmax = 600;
constexpr int ymax = 600;

constexpr int x_orig = xmax / 2;
constexpr int y_orig = ymax / 2;
Point orig(x_orig, y_orig);

constexpr int r_min = -10;
constexpr int r_max = 10;

constexpr int n_points = 400;

constexpr int x_scale = 2;
constexpr int y_scale = 2;

constexpr int xoffset = 100;
constexpr int yoffset = 100;

constexpr int xspace = 100;
constexpr int yspace = 100;

constexpr int xlength = xmax - xoffset - xspace;
constexpr int ylength = ymax - yoffset - yspace;


int main()
try
{
	Point tl(100, 100);
	Simple_window win(tl, xmax, ymax, "Function graphs");

	// x axis
	Axis x(Axis::x, Point(xoffset, ymax - yoffset), xlength, 12,
		"month    Jan  Feb   Mar  Apr  May  Jun   Jul    Aug  Sep  Oct  Nov   Dec");
	x.set_color(Color::black);
	x.label.move(-100, 0);
	win.attach(x);

	// y axis
	Axis y(Axis::y, Point(yoffset, ymax - yoffset), ylength, 20, "temperature in 0 - 20 C");
	y.set_color(Color::black);
	win.attach(y);

	// data
	// Cambridge, England monthly normal weather 2016
	vector<double> camb_eng_temp = { 
		3.7,
		3.8,
		6.1,
		8.0,
		11.4,
		14.3,
		16.8,
		16.9,
		14.1,
		10.5,
		6.5,
		4.7
	};

	// Cambridge, Massachusetts monthly normal weather 2016
	vector<double> camb_mas_temp = {
		-1.9,
		-0.9,
		3.7,
		8.9,
		14.6,
		19.8,
		23.1,
		22.2,
		18.2,
		12.7,
		7.4,
		0.9
	};

	// graph
	Open_polyline cet; // Cambridge, England
	Open_polyline cmt; // Cambridge, Massachusetts

	for (int i = 0; i < 12; i++) {
		cet.add(Point(xoffset + i * (xlength / 12), (yspace + ylength) - camb_eng_temp[i] * 20));
		cmt.add(Point(xoffset + i * (xlength / 12), (yspace + ylength) - camb_mas_temp[i] * 20));
	}

	cet.set_color(Color::red);
	win.attach(cet);

	cmt.set_color(Color::blue);
	win.attach(cmt);

	win.wait_for_button();
	keep_window_open();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

labeled points data graphing [fltk]

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

Output:

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

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

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

// layout
constexpr int xmax = 600;
constexpr int ymax = 600;

constexpr int x_orig = xmax / 2;
constexpr int y_orig = ymax / 2;
Point orig(x_orig, y_orig);

constexpr int r_min = -10;
constexpr int r_max = 10;

constexpr int n_points = 400;

constexpr int x_scale = 2;
constexpr int y_scale = 2;

constexpr int xoffset = 100;
constexpr int yoffset = 100;

constexpr int xspace = 100;
constexpr int yspace = 100;

constexpr int xlength = xmax - xoffset - xspace;
constexpr int ylength = ymax - yoffset - yspace;

class bar_graph : public Shape
{
public:
	bar_graph(Point origin, vector<Point>& data, int x_scale, int r1_min, int r1_max, int y_scale, int r2_min, int r2_max, Color col, string label);

	void draw_lines() const;

	vector<Point>& get_data() { return data; }

private:
	Point origin;
	vector<Point>& data;

	int x_scale;
	int r1_min;
	int r1_max;

	int y_scale;
	int r2_min;
	int r2_max;

	int bar_width;

	Color col;
	string label;
};

bar_graph::bar_graph(Point origin, vector<Point>& data, int x_scale, int r1_min, int r1_max, int y_scale, int r2_min, int r2_max, Color col, string label)
	: origin(origin),
	data(data),
	x_scale(x_scale),
	r1_min(r1_min),
	r1_max(r1_max),
	y_scale(y_scale),
	r2_min(r2_min),
	r2_max(r2_max),
	bar_width(bar_width),
	col(col),
	label(label)
{

}

void bar_graph::draw_lines() const
{
	int ds = data.size();
	cout << ds << endl;


	for (int i = 0; i < data.size(); i++) {

		int h = data[i].x;
		int c = data[i].y;

		// scale factor
		double sx = (xlength / 2.0) / (r1_max - r1_min);
		double sy = (ylength / 2.0) / (r2_max - r2_min);

		// draw point
		Point p(origin.x + (h - r1_min) * sx, origin.y - (c - r2_min) * sy);
		cout << p << endl;

		Graph_lib::Circle crcl(p, 3);
		crcl.set_color(col);
		crcl.set_fill_color(col);
		crcl.draw();

		// draw label
		string point_label = "(" + to_string(data[i].x) + "," + to_string(data[i].y) + ")";
		Text l(p, point_label);
		l.set_color(Color::red);

		l.draw();

	}

	// graph label
	Text gl(Point(origin.x - 90, origin.y + 15), label);
	gl.set_color(col);

	gl.draw();
}

int main()
try
{
	Point tl(100, 100);
	Simple_window win(tl, xmax, ymax, "Function graphs.");

	int r1_min = 170;
	int r1_max = 180;

	int r2_min = 7;
	int r2_max = 23;

	// notch label x
	string x_notch = "1 == " + to_string((r1_max - r1_min) / 10);

	// notch label y
	ostringstream strs;
	strs << setprecision(2) << (r2_max - r2_min) / 10.0;
	string y_notch = "1 == " + strs.str();

	// x axis
	Axis x(Axis::x, Point(orig.x - 200, orig.y), 400, 20, x_notch);
	x.set_color(Color::black);
	win.attach(x);

	// y axis
	Axis y(Axis::y, Point(orig.x, orig.y + 200), 400, 20, y_notch);
	y.set_color(Color::black);
	win.attach(y);

	// people height data
	vector<Point> d = {
		Point(170, 7),
		Point(175, 9),
		Point(180, 23),
		Point(173, 8),
		Point(178, 20),
		Point(177, 15),
		Point(171, 10),
		Point(174, 19)
	};

	// bar graph
	bar_graph bg(orig, d, x_scale, r1_min, r1_max, y_scale, r2_min, r2_max, Color::blue, "labeled points");
	win.attach(bg);

	win.wait_for_button();
	keep_window_open();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

bar graph – group of people height data graphing [fltk]

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

Output:

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

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

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

// layout
constexpr int xmax = 600;
constexpr int ymax = 600;

constexpr int x_orig = xmax / 2;
constexpr int y_orig = ymax / 2;
Point orig(x_orig, y_orig);

constexpr int r_min = -10;
constexpr int r_max = 10;

constexpr int n_points = 400;

constexpr int x_scale = 2;
constexpr int y_scale = 2;

constexpr int xoffset = 100;
constexpr int yoffset = 100;

constexpr int xspace = 100;
constexpr int yspace = 100;

constexpr int xlength = xmax - xoffset - xspace;
constexpr int ylength = ymax - yoffset - yspace;

struct ppl_height
{
	ppl_height(double height, int count)
		:height(height), count(count) {	}
	double height;
	int count;
};

void read_data(string location, vector<ppl_height>& v)
{
	ifstream ist(location);
	if (!ist) { error("no such file exists", location); }

	char comma;
	double height;
	int count;

	while (ist >> height >> comma >> count)
	{
		if (ist.eof()) {
			break;
		}
		v.push_back(ppl_height(height, count));
	}

}

class bar_graph : public Shape
{
public:
	bar_graph(Point origin, vector<ppl_height>& data, int x_scale, int r1_min, int r1_max, int y_scale, int r2_min, int r2_max, int bar_width, Color col, string label);

	void draw_lines() const;

	vector<ppl_height>& get_data() { return data; }

private:
	Point origin;
	vector<ppl_height>& data;

	int x_scale;
	int r1_min;
	int r1_max;

	int y_scale;
	int r2_min;
	int r2_max;

	int bar_width;

	Color col;
	string label;
};

bar_graph::bar_graph(Point origin, vector<ppl_height>& data, int x_scale, int r1_min, int r1_max, int y_scale, int r2_min, int r2_max, int bar_width, Color col, string label)
	:	origin(origin),
		data(data),
		x_scale(x_scale),
		r1_min(r1_min),
		r1_max(r1_max),
		y_scale(y_scale),
		r2_min(r2_min),
		r2_max(r2_max),
		bar_width(bar_width),
		col(col),
		label(label)
{

}

void bar_graph::draw_lines() const
{
	int ds = data.size();


	for (int i = 0; i < data.size(); i++) {

		double w = double(bar_width / 2);
		int h = data[i].height;
		int c = data[i].count;

		// scale factor
		double sx = (xlength / 2.0) / (r1_max - r1_min);
		double sy = (ylength / 2.0) / (r2_max - r2_min);
		
		Point p0(origin.x + (h - r1_min) * sx - w, origin.y - c * sy);
		Point p1(origin.x + (h - r1_min) * sx + w, origin.y);

		Graph_lib::Rectangle r(p0, p1);

		r.set_color(col);
		r.set_fill_color(col);

		r.draw();

		// bar labels
		string hl = to_string((int)data[i].height);
		Text height_label(Point(p1.x - bar_width, p1.y + 15), hl);
		height_label.set_color(col);
		height_label.draw();
		
		string cl = to_string((int)data[i].count);
		Text count_label(Point(p0.x, p0.y - 10), cl);
		count_label.set_color(col);
		count_label.draw();

	}

	// graph label
	Text gl(Point(origin.x - 70, origin.y + 15), label);
	gl.set_color(col);

	gl.draw();
}

int main()
try
{
	Point tl(100, 100);
	Simple_window win(tl, xmax, ymax, "Function graphs.");

	int r1_min = 160;
	int r1_max = 200;

	int r2_min = 5;
	int r2_max = 30;

	int bar_width = 15;
	
	// notch label x
	string x_notch = "1 == " + to_string((r1_max - r1_min) / 10);

	// notch label y
	ostringstream strs;
	strs << setprecision(2) << (r2_max - r2_min) / 10.0;
	string y_notch = "1 == " + strs.str();

	// x axis
	Axis x(Axis::x, Point(orig.x - 200, orig.y), 400, 20, x_notch);
	x.set_color(Color::black);
	win.attach(x);

	// y axis
	Axis y(Axis::y, Point(orig.x, orig.y + 200), 400, 20, y_notch);
	y.set_color(Color::black);
	win.attach(y);

	// people height data
	vector<ppl_height> d = {	ppl_height(170, 7),
								ppl_height(175, 9),
								ppl_height(180, 23),
								ppl_height(185, 17),
								ppl_height(190, 6),
								ppl_height(195, 1)
	};

	// stream data from file
	vector<ppl_height> dff;
	string location = "input/height_data.txt";
	read_data(location, dff);

	// bar graph
	bar_graph bg(orig, dff, x_scale, r1_min, r1_max, y_scale, r2_min, r2_max, bar_width, Color::blue, "bar graph");
	win.attach(bg);

	win.wait_for_button();
	keep_window_open();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

elaborated bar graph class [fltk]

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

Output:

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

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

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

// layout
constexpr int xmax = 600;
constexpr int ymax = 600;

constexpr int x_orig = xmax / 2;
constexpr int y_orig = ymax / 2;
Point orig(x_orig, y_orig);

constexpr int r_min = -10;
constexpr int r_max = 10;

constexpr int n_points = 400;

constexpr int x_scale = 20;
constexpr int y_scale = 20;

constexpr int xoffset = 100;
constexpr int yoffset = 100;

constexpr int xspace = 100;
constexpr int yspace = 100;

constexpr int xlength = xmax - xoffset - xspace;
constexpr int ylength = ymax - yoffset - yspace;

// bar graph class

class bar_graph : public Shape
{
public:
	bar_graph(Point origin, vector<double> data, int bar_width, int gap_width, Color col, string label);

	void draw_lines() const;

	vector<double> get_data() { return data; }

private:
	Point origin;
	vector<double> data;

	int bar_width;
	int gap_width;

	Color col;

	string label;
};

bar_graph::bar_graph(Point origin, vector<double> data, int bar_width, int gap_width, Color col, string label)
	: origin(origin), data(data), bar_width(bar_width), gap_width(gap_width), col(col), label(label)
{

}

void bar_graph::draw_lines() const
{
	int ds = data.size();


	for (int i = 0; i < data.size(); i++) {
		Point p0(origin.x + i * (bar_width + gap_width), origin.y);
		Point p1(origin.x + i * (bar_width + gap_width) + bar_width, origin.y);
		Point p2(origin.x + i * (bar_width + gap_width) + bar_width, origin.y - data[i]);
		Point p3(origin.x + i * (bar_width + gap_width), origin.y - data[i]);

		Closed_polyline cp;
		cp.add(p0);
		cp.add(p1);
		cp.add(p2);
		cp.add(p3);

		cp.set_color(col);
		cp.set_fill_color(col);

		cp.draw();

		// bar label
		ostringstream strs;
		strs << data[i];
		string d = strs.str();

		Text bl(Point(p3.x, p3.y - 5), d);
		bl.set_color(col);

		bl.draw();

	}

	// graph label
	Text gl(Point(origin.x, origin.y + 15), label);
	gl.set_color(col);

	gl.draw();

}

int main()
try
{
	Point tl(100, 100);
	Simple_window win(tl, xmax, ymax, "Function graphs.");

	Axis x(Axis::x, Point(orig.x - 200, orig.y), 400, 20, "1 == 20");
	x.set_color(Color::black);
	win.attach(x);

	Axis y(Axis::y, Point(orig.x, orig.y + 200), 400, 20, "1 == 20");
	y.set_color(Color::black);
	win.attach(y);

	vector<double> d = { 120, 123, 115, 110, 55 };

	bar_graph bg(orig, d, 10, 20, Color::blue, "bar graph");

	win.attach(bg);

	win.wait_for_button();
	keep_window_open();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

bar graph class [fltk]

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

Output:

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

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

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

// layout
constexpr int xmax = 600;
constexpr int ymax = 600;

constexpr int x_orig = xmax / 2;
constexpr int y_orig = ymax / 2;
Point orig(x_orig, y_orig);

constexpr int r_min = -10;
constexpr int r_max = 10;

constexpr int n_points = 400;

constexpr int x_scale = 20;
constexpr int y_scale = 20;

constexpr int xoffset = 100;
constexpr int yoffset = 100;

constexpr int xspace = 100;
constexpr int yspace = 100;

constexpr int xlength = xmax - xoffset - xspace;
constexpr int ylength = ymax - yoffset - yspace;

// bar graph class

class bar_graph : public Shape
{
public:
	bar_graph(Point origin, vector<double> data, int bar_width, int gap_width, Color col);
		
	void draw_lines() const;

	vector<double> get_data() { return data; }

private:
	Point origin;
	vector<double> data;

	int bar_width;
	int gap_width;

	Color col;
};

bar_graph::bar_graph(Point origin, vector<double> data, int bar_width, int gap_width, Color col)
	: origin(origin), data(data), bar_width(bar_width), gap_width(gap_width), col(col)
{

}

void bar_graph::draw_lines() const
{
	int ds = data.size();

	
	for (int i = 0; i < data.size(); i++) {
		Point p0(origin.x + i * (bar_width + gap_width), origin.y);
		Point p1(origin.x + i * (bar_width + gap_width) + bar_width, origin.y);
		Point p2(origin.x + i * (bar_width + gap_width) + bar_width, origin.y - data[i]);
		Point p3(origin.x + i * (bar_width + gap_width), origin.y - data[i]);

		Closed_polyline cp;
		cp.add(p0);
		cp.add(p1);
		cp.add(p2);
		cp.add(p3);
		
		cp.set_color(col);
		cp.set_fill_color(col);

		cp.draw();
	}
	
}

int main()
try
{
	Point tl(100, 100);
	Simple_window win(tl, xmax, ymax, "Function graphs.");

	Axis x(Axis::x, Point(orig.x - 200, orig.y), 400, 20, "1 == 20");
	x.set_color(Color::black);
	win.attach(x);

	Axis y(Axis::y, Point(orig.x, orig.y + 200), 400, 20, "1 == 20");
	y.set_color(Color::black);
	win.attach(y);

	vector<double> d = { 120, 123, 115, 110, 55};
	
	bar_graph bg(orig, d, 10, 20, Color::red);

	win.attach(bg);

	win.wait_for_button();
	keep_window_open();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}

animating leipniz’s series [fltk]

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

Output:

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

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

int fac_recursive(int n) { return n > 1 ? n * fac_recursive(n - 1) : 1; } // factorial n!

// layout
constexpr int xmax = 600;
constexpr int ymax = 600;

constexpr int x_orig = xmax / 2;
constexpr int y_orig = ymax / 2;
Point orig(x_orig, y_orig);

constexpr int r_min = -10;
constexpr int r_max = 10;

constexpr int n_points = 400;

constexpr int x_scale = 20;
constexpr int y_scale = 20;

constexpr int xoffset = 100;
constexpr int yoffset = 100;

constexpr int xspace = 100;
constexpr int yspace = 100;

constexpr int xlength = xmax - xoffset - xspace;
constexpr int ylength = ymax - yoffset - yspace;

// Leibniz Series graphing functions

/*
double exp0(double x) { return 1; }
double exp1(double x) { return 1 - 1/3 + 1/5; }
double exp2(double x) { return 1 - 1/3 + 1/5 - 1/7 + 1/9; }
*/

double expe(double n)
{
	double sum = 0;
	int denom = 1;
	int sign = 1;
	for (int i = 1; i <= n; i++)
	{
		sum += sign * 4.0 / denom;
		denom += 2;
		sign *= -1;
	}
	return sum;
}

int main()
try
{
	Point tl(100, 100);
	Simple_window win(tl, xmax, ymax, "Function graphs.");

	Axis x(Axis::x, Point(orig.x - 200, orig.y), 400, 20, "1 == 20");
	x.set_color(Color::black);
	win.attach(x);

	Axis y(Axis::y, Point(orig.x, orig.y + 200), 400, 20, "1 == 20");
	y.set_color(Color::black);
	win.attach(y);

	Function real_exp(exp, r_min, r_max, orig, 200, x_scale, y_scale);
	real_exp.set_color(Color::blue);

	Open_polyline poly;
	poly.add(orig);
	win.attach(poly);

	
	for (int n = 1; n < 50; ++n)
	{
		ostringstream ss;
		ss << "exp approximation, n == " << n;
		win.set_label(ss.str());
		//get next approximation:
		Function e(expe, r_min, r_max, orig, n, x_scale, y_scale);
		e.set_color(Color::red);
		win.attach(e);
		win.wait_for_button();
		win.detach(e);
	}
	
	keep_window_open();
}
catch (exception& e) {
	cerr << "error: " << e.what() << '\n';
	keep_window_open();
	return 1;
}

catch (...) {
	cerr << "Unknown exception!\n";
	keep_window_open();
	return 2;
}