-
Notifications
You must be signed in to change notification settings - Fork 123
/
Graph.h
377 lines (304 loc) · 9.51 KB
/
Graph.h
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
#ifndef GRAPH_GUARD
#define GRAPH_GUARD 1
#include "Point.h"
#include<vector>
//#include<string>
//#include<cmath>
#include "fltk.h"
//#include "std_lib_facilities.h"
namespace Graph_lib {
// defense against ill-behaved Linux macros:
#undef major
#undef minor
struct Color {
enum Color_type {
red=FL_RED, blue=FL_BLUE, green=FL_GREEN,
yellow=FL_YELLOW, white=FL_WHITE, black=FL_BLACK,
magenta=FL_MAGENTA, cyan=FL_CYAN, dark_red=FL_DARK_RED,
dark_green=FL_DARK_GREEN, dark_yellow=FL_DARK_YELLOW, dark_blue=FL_DARK_BLUE,
dark_magenta=FL_DARK_MAGENTA, dark_cyan=FL_DARK_CYAN
};
enum Transparency { invisible = 0, visible=255 };
Color(Color_type cc) :c(Fl_Color(cc)), v(visible) { }
Color(Color_type cc, Transparency vv) :c(Fl_Color(cc)), v(vv) { }
Color(int cc) :c(Fl_Color(cc)), v(visible) { }
Color(Transparency vv) :c(Fl_Color()), v(vv) { }
int as_int() const { return c; }
char visibility() const { return v; }
void set_visibility(Transparency vv) { v=vv; }
private:
unsigned char v; // 0 or 1 for now
Fl_Color c;
};
struct Line_style {
enum Line_style_type {
solid=FL_SOLID, // -------
dash=FL_DASH, // - - - -
dot=FL_DOT, // .......
dashdot=FL_DASHDOT, // - . - .
dashdotdot=FL_DASHDOTDOT, // -..-..
};
Line_style(Line_style_type ss) :s(ss), w(0) { }
Line_style(Line_style_type lst, int ww) :s(lst), w(ww) { }
Line_style(int ss) :s(ss), w(0) { }
int width() const { return w; }
int style() const { return s; }
private:
int s;
int w;
};
class Font {
public:
enum Font_type {
helvetica=FL_HELVETICA,
helvetica_bold=FL_HELVETICA_BOLD,
helvetica_italic=FL_HELVETICA_ITALIC,
helvetica_bold_italic=FL_HELVETICA_BOLD_ITALIC,
courier=FL_COURIER,
courier_bold=FL_COURIER_BOLD,
courier_italic=FL_COURIER_ITALIC,
courier_bold_italic=FL_COURIER_BOLD_ITALIC,
times=FL_TIMES,
times_bold=FL_TIMES_BOLD,
times_italic=FL_TIMES_ITALIC,
times_bold_italic=FL_TIMES_BOLD_ITALIC,
symbol=FL_SYMBOL,
screen=FL_SCREEN,
screen_bold=FL_SCREEN_BOLD,
zapf_dingbats=FL_ZAPF_DINGBATS
};
Font(Font_type ff) :f(ff) { }
Font(int ff) :f(ff) { }
int as_int() const { return f; }
private:
int f;
};
template<class T> class Vector_ref {
vector<T*> v;
vector<T*> owned;
public:
Vector_ref() {}
Vector_ref(T* a, T* b=0, T* c=0, T* d=0)
{
if (a) push_back(a);
if (b) push_back(b);
if (c) push_back(c);
if (d) push_back(d);
}
~Vector_ref() { for (int i=0; i<owned.size(); ++i) delete owned[i]; }
void push_back(T& s) { v.push_back(&s); }
void push_back(T* p) { v.push_back(p); owned.push_back(p); }
// ???void erase(???)
T& operator[](int i) { return *v[i]; }
const T& operator[](int i) const { return *v[i]; }
int size() const { return v.size(); }
};
typedef double Fct(double);
class Shape { // deals with color and style, and holds sequence of lines
protected:
Shape() { }
Shape(initializer_list<Point> lst); // add() the Points to this Shape
// Shape() : lcolor(fl_color()),
// ls(0),
// fcolor(Color::invisible) { }
void add(Point p){ points.push_back(p); }
void set_point(int i, Point p) { points[i] = p; }
public:
void draw() const; // deal with color and draw_lines
protected:
virtual void draw_lines() const; // simply draw the appropriate lines
public:
virtual void move(int dx, int dy); // move the shape +=dx and +=dy
void set_color(Color col) { lcolor = col; }
Color color() const { return lcolor; }
void set_style(Line_style sty) { ls = sty; }
Line_style style() const { return ls; }
void set_fill_color(Color col) { fcolor = col; }
Color fill_color() const { return fcolor; }
Point point(int i) const { return points[i]; }
int number_of_points() const { return int(points.size()); }
virtual ~Shape() { }
/*
struct Window* attached;
Shape(const Shape& a)
:attached(a.attached), points(a.points), line_color(a.line_color), ls(a.ls)
{
if (a.attached)error("attempt to copy attached shape");
}
*/
Shape(const Shape&) = delete;
Shape& operator=(const Shape&) = delete;
private:
vector<Point> points; // not used by all shapes
Color lcolor {fl_color()};
Line_style ls {0};
Color fcolor {Color::invisible};
// Shape(const Shape&);
// Shape& operator=(const Shape&);
};
struct Function : Shape {
// the function parameters are not stored
Function(Fct f, double r1, double r2, Point orig, int count = 100, double xscale = 25, double yscale = 25);
//Function(Point orig, Fct f, double r1, double r2, int count, double xscale = 1, double yscale = 1);
};
struct Fill {
Fill() :no_fill(true), fcolor(0) { }
Fill(Color c) :no_fill(false), fcolor(c) { }
void set_fill_color(Color col) { fcolor = col; }
Color fill_color() { return fcolor; }
protected:
bool no_fill;
Color fcolor;
};
struct Line : Shape {
Line(Point p1, Point p2) { add(p1); add(p2); }
};
struct Rectangle : Shape {
Rectangle(Point xy, int ww, int hh) :w{ ww }, h{ hh }
{
if (h<=0 || w<=0) error("Bad rectangle: non-positive side");
add(xy);
}
Rectangle(Point x, Point y) :w{ y.x - x.x }, h{ y.y - x.y }
{
if (h<=0 || w<=0) error("Bad rectangle: first point is not top left");
add(x);
}
void draw_lines() const;
// void set_fill_color(Color col) { fcolor = col; }
// Color fill_color() { return fcolor; }
int height() const { return h; }
int width() const { return w; }
private:
int h; // height
int w; // width
// Color fcolor; // fill color; 0 means "no fill"
};
bool intersect(Point p1, Point p2, Point p3, Point p4);
struct Open_polyline : Shape { // open sequence of lines
using Shape::Shape;
void add(Point p) { Shape::add(p); }
void draw_lines() const;
};
struct Closed_polyline : Open_polyline { // closed sequence of lines
using Open_polyline::Open_polyline;
void draw_lines() const;
// void add(Point p) { Shape::add(p); }
};
struct Polygon : Closed_polyline { // closed sequence of non-intersecting lines
using Closed_polyline::Closed_polyline;
void add(Point p);
void draw_lines() const;
};
struct Lines : Shape { // indepentdent lines
Lines() {}
Lines(initializer_list<Point> lst) : Shape{lst} { if (lst.size() % 2) error("odd number of points for Lines"); }
void draw_lines() const;
void add(Point p1, Point p2) { Shape::add(p1); Shape::add(p2); }
};
struct Text : Shape {
// the point is the bottom left of the first letter
Text(Point x, const string& s) : lab{ s } { add(x); }
void draw_lines() const;
void set_label(const string& s) { lab = s; }
string label() const { return lab; }
void set_font(Font f) { fnt = f; }
Font font() const { return Font(fnt); }
void set_font_size(int s) { fnt_sz = s; }
int font_size() const { return fnt_sz; }
private:
string lab; // label
Font fnt{ fl_font() };
int fnt_sz{ (14<fl_size()) ? fl_size() : 14 }; // at least 14 point
};
struct Axis : Shape {
// representation left public
enum Orientation { x, y, z };
Axis(Orientation d, Point xy, int length, int nummber_of_notches=0, string label = "");
void draw_lines() const;
void move(int dx, int dy);
void set_color(Color c);
Text label;
Lines notches;
// Orientation orin;
// int notches;
};
struct Circle : Shape {
Circle(Point p, int rr) // center and radius
:r{ rr } {
add(Point{ p.x - r, p.y - r });
}
void draw_lines() const;
Point center() const { return { point(0).x + r, point(0).y + r }; }
void set_radius(int rr) { r=rr; }
int radius() const { return r; }
private:
int r;
};
struct Ellipse : Shape {
Ellipse(Point p, int ww, int hh) // center, min, and max distance from center
:w{ ww }, h{ hh } {
add(Point{ p.x - ww, p.y - hh });
}
void draw_lines() const;
Point center() const { return{ point(0).x + w, point(0).y + h }; }
Point focus1() const { return{ center().x + int(sqrt(double(w*w - h*h))), center().y }; }
Point focus2() const { return{ center().x - int(sqrt(double(w*w - h*h))), center().y }; }
void set_major(int ww) { w=ww; }
int major() const { return w; }
void set_minor(int hh) { h=hh; }
int minor() const { return h; }
private:
int w;
int h;
};
/*
struct Mark : Text {
static const int dw = 4;
static const int dh = 4;
Mark(Point xy, char c) : Text(Point(xy.x-dw, xy.y+dh),string(1,c)) {}
};
*/
struct Marked_polyline : Open_polyline {
Marked_polyline(const string& m) :mark(m) { }
void draw_lines() const;
private:
string mark;
};
struct Marks : Marked_polyline {
Marks(const string& m) :Marked_polyline(m)
{ set_color(Color(Color::invisible)); }
};
struct Mark : Marks {
Mark(Point xy, char c) : Marks(string(1,c)) {add(xy); }
};
/*
struct Marks : Shape {
Marks(char m) : mark(string(1,m)) { }
void add(Point p) { Shape::add(p); }
void draw_lines() const;
private:
string mark;
};
*/
struct Bad_image : Fl_Image {
Bad_image(int h, int w) : Fl_Image(h,w,0) { }
void draw(int x,int y, int, int, int, int) { draw_empty(x,y); }
};
struct Suffix {
enum Encoding { none, jpg, gif, bmp };
};
Suffix::Encoding get_encoding(const string& s);
struct Image : Shape {
Image(Point xy, string s, Suffix::Encoding e = Suffix::none);
~Image() { delete p; }
void draw_lines() const;
void set_mask(Point xy, int ww, int hh) { w=ww; h=hh; cx=xy.x; cy=xy.y; }
void move(int dx,int dy) { Shape::move(dx,dy); p->draw(point(0).x,point(0).y); }
private:
int w,h,cx,cy; // define "masking box" within image relative to position (cx,cy)
Fl_Image* p;
Text fn;
};
}
#endif