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