PPP2 Chapter 15 Exercise 3

Exercise Specifications:
3. Modify Fct from the previous exercise to take an extra argument to con-
trol precision or whatever. Make the type of that argument a template
parameter for extra flexibility.


Previous exercise (which I've done):
2. Define a class Fct that is just like Function except that it stores its constructor arguments. Provide Fct with “reset” operations, so that you can
use it repeatedly for different ranges, different functions, etc.
I just had to name the class "Fct2" because naming it "Fct" gave me compiler errors since there's already a typedef called "Fct" in Graph.h.

My code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Osman Zakir
// 6 / 26 / 2017
// Bjarne Stroustrup: Programming: Principles and Practice Using C++ 2nd Edition
// Chapter 15 Exercise 2
// chapter15ex2.cpp
// Exercise Specifications:
/**
 * Define a class Fct that is just like Function except that it stores its 
 * constructor arguments. Provide Fct with “reset” operations, so that you can
 * use it repeatedly for different ranges, different functions, etc.
 */

#include "../../Graph.h"
#include "../../Window.h"

double one(double);
double slope(double x);
double square(double x);

namespace Graph_lib
{
	struct Fct2 : Shape
	{
		typedef double Funct(double);
		Fct2(Funct f, double r1, double r2, Point orig, int count = 100, double xscale = 25, double yscale = 25);
		Point orig() const { return m_orig; };
		double r1() const { return m_r1; }
		double r2() const { return m_r2; }
		int count() const { return m_count; }
		double xscale() const { return m_xscale; }
		double yscale() const { return m_yscale; }
		void set_orig(const Point &orig) { m_orig = orig; }
		void set_r1(const double r1) { m_r1 = r1; }
		void set_r2(const double r2) { m_r2 = r2; }
		void set_count(const int count) { m_count = count; }
		void set_xscale(const double xscale) { m_xscale = xscale; }
		void set_yscale(const double yscale) { m_yscale = yscale; }
	private:
		Funct m_f;
		Point m_orig;
		double m_r1;
		double m_r2;
		int m_count;
		double m_xscale;
		double m_yscale;
	};
}

int main()
{
	using namespace Graph_lib;

	constexpr int xmax = 600;		// window size
	constexpr int ymax = 400;
	Graph_lib::Window win{ Point{ 100, 100 }, xmax, ymax, "Function graphing" };

	constexpr int x_orig = xmax / 2;	// position of (0,0) is center of window
	constexpr int y_orig = ymax / 2;
	const Point orig{ x_orig, y_orig };

	constexpr int r_min = -10;	 // range [-10:11]
	constexpr int r_max = 11;

	constexpr int n_points = 400;	// number of points in usage

	constexpr int x_scale = 30;		// scaling factors
	constexpr int y_scale = 30;

	Fct2 s{ one, r_min, r_max, orig, n_points, x_scale, y_scale };
	Fct2 s2{ slope, r_min, r_max, orig, n_points, x_scale, y_scale };
	Fct2 s3{ square, r_min, r_max, orig, n_points, x_scale, y_scale };

	s.set_color(Color::black);
	s2.set_color(Color::black);
	s3.set_color(Color::black);

	Text ts{ Point{ 100, y_orig - 40 }, "one" };
	Text ts2{ Point{ 100, y_orig + y_orig / 2 - 20 }, "x/2" };
	Text ts3{ Point{ x_orig - 100, 20 }, "x*x" };

	ts.set_color(Color::black);
	ts2.set_color(Color::black);
	ts3.set_color(Color::black);

	constexpr int xlength = xmax - 40;		// make the axis a bit smaller than the window
	constexpr int ylength = ymax - 40;

	Axis x{ Axis::x, Point{ 20, y_orig }, xlength,
		xlength / static_cast<int>(x_scale), "one notch == 1" };
	Axis y{ Axis::y, Point{ x_orig, ylength + 20 }, ylength,
		ylength / static_cast<int>(y_scale), "one notch == 1" };

	x.set_color(Color::red);
	y.set_color(Color::red);

	win.attach(ts);
	win.attach(ts2);
	win.attach(ts3);
	win.attach(s);
	win.attach(s2);
	win.attach(s3);
	win.attach(x);
	win.attach(y);

	gui_main();
}

Graph_lib::Fct2::Fct2(Funct f, double r1, double r2, Point orig, int count, double xscale, double yscale)
	:m_r1{r1}, m_r2{r2}, m_orig{orig}, m_count{count}, m_xscale{xscale}, m_yscale{yscale}
// graph f(x) for x in [r1:r2) using count line segments with (0,0) displayed at xy
// x coordinates are scaled by xscale and y coordinates scaled by yscale
{
	if (r2 - r1 <= 0)
	{
		error("bad graphing range");
	}
	if (count <= 0)
	{
		error("non-positive graphing count");
	}
	double dist = (r2 - r1) / count;
	double r = r1;
	for (int i = 0; i < count; ++i) 
	{
		add(Point(orig.x + int(r * xscale), orig.y - int(f(r) * yscale)));
		r += dist;
	}
}

double one(double)
{
	return 1;
}

double slope(double x)
{
	return x / 2;
}

double square(double x)
{
	return x * x;
}


My problem here is that I don't know what Dr. Stroustrup means by "precision" here. Precision of what?
Topic archived. No new replies allowed.