Lesson of 7 July 2008¶
Overloading and template
An example of overloading
:open:
1/*
2// Example of overloading
3//
4*/
5
6#include <iostream>
7#include <algorithm>
8
9using namespace std ;
10
11// this function order a vector of integer
12
13void
14sort( int size, int v[] ) {
15 cout << "Order the vector of integer with bubble sort\n" ;
16 for ( int i = 0 ; i < size-1 ; ++i )
17 // find minimum of v[i]...v[size-1] ;
18 for ( int j = i+1 ; j < size ; ++j )
19 if ( v[i] > v[j] )
20 swap(v[i],v[j]) ; // uso swap function of STL algorithm
21}
22
23// this function order a vector of double
24
25void
26sort( int size, double v[] ) {
27 cout << "Order the vector of double with bubble sort\n" ;
28 for ( int i = 0 ; i < size-1 ; ++i )
29 // find minimum of v[i]...v[size-1] ;
30 for ( int j = i+1 ; j < size ; ++j )
31 if ( v[i] > v[j] )
32 swap(v[i],v[j]) ; // uso swap function of STL algorithm
33}
34
35int v[] = {4,5,2, -1, 3, 0, -23, 123 } ;
36int sv = sizeof(v) / sizeof(v[0]) ;
37 // size in byte of v / size in bite of first element
38
39double rv[] = {-0.1, 4.1, 5.3,2.2, -1.1, 3.2234, 0.0213, -23.1, 123. } ;
40int srv = sizeof(rv) / sizeof(rv[0]) ;
41
42int
43main() {
44 sort( sv, v ) ;
45 for ( int i = 0 ; i < sv ; ++i )
46 cout << "v[" << i << "] = " << v[i] << "\n" ;
47
48 sort( srv, rv ) ;
49 for ( int i = 0 ; i < sv ; ++i )
50 cout << "rv[" << i << "] = " << rv[i] << "\n" ;
51 return 0 ;
52}
An example of template function
File example_template.cc
:open:
1/*
2// Example of overloading
3//
4*/
5
6#include <iostream>
7#include <algorithm>
8
9using namespace std ;
10
11// this function order a vector of type Type
12
13template <typename Type>
14void
15sort( int size, Type v[] ) {
16 cout << "Order the vector with bubble sort\n" ;
17 for ( int i = 0 ; i < size-1 ; ++i )
18 // find minimum of v[i]...v[size-1] ;
19 for ( int j = i+1 ; j < size ; ++j )
20 if ( v[i] > v[j] )
21 swap(v[i],v[j]) ; // uso swap function of STL algorithm
22}
23
24int v[] = {4,5,2, -1, 3, 0, -23, 123 } ;
25int sv = sizeof(v) / sizeof(v[0]) ;
26 // size in byte of v / size in bite of first element
27
28double rv[] = {-0.1, 4.1, 5.3,2.2, -1.1, 3.2234, 0.0213, -23.1, 123. } ;
29int srv = sizeof(rv) / sizeof(rv[0]) ;
30
31
32int
33main() {
34 sort( sv, v ) ;
35 for ( int i = 0 ; i < sv ; ++i )
36 cout << "v[" << i << "] = " << v[i] << "\n" ;
37
38 sort( srv, rv ) ;
39 for ( int i = 0 ; i < sv ; ++i )
40 cout << "rv[" << i << "] = " << rv[i] << "\n" ;
41 return 0 ;
42}
Splitting template on multiple files
:open:
1/*
2// Example of overloading
3//
4*/
5
6#include <iostream>
7#include <algorithm>
8
9using namespace std ;
10
11// declare the function sort to order a vector
12// it is a template function
13template <typename Type>
14void
15sort( int size, Type v[] ) ;
16
17int v[] = {4,5,2, -1, 3, 0, -23, 123 } ;
18int sv = sizeof(v) / sizeof(v[0]) ;
19 // size in byte of v / size in bite of first element
20
21double rv[] = {-0.1, 4.1, 5.3,2.2, -1.1, 3.2234, 0.0213, -23.1, 123. } ;
22int srv = sizeof(rv) / sizeof(rv[0]) ;
23
24float fv[] = {-0.1, 4.1, 5.3,2.2, -1.1, 3.2234, 0.0213, -23.1, 123. } ;
25int sfv = sizeof(fv) / sizeof(fv[0]) ;
26
27
28int
29main() {
30 sort( sv, v ) ;
31 for ( int i = 0 ; i < sv ; ++i )
32 cout << "v[" << i << "] = " << v[i] << "\n" ;
33
34 sort( srv, rv ) ;
35 for ( int i = 0 ; i < srv ; ++i )
36 cout << "rv[" << i << "] = " << rv[i] << "\n" ;
37
38 sort( sfv, fv ) ;
39 for ( int i = 0 ; i < sfv ; ++i )
40 cout << "fv[" << i << "] = " << fv[i] << "\n" ;
41
42 return 0 ;
43}
:open:
1/*
2// Example of overloading
3//
4*/
5
6#include <iostream>
7#include <algorithm>
8
9using namespace std ;
10
11// define the function sort that order a vector
12template <typename Type>
13void
14sort( int size, Type v[] ) {
15 cout << "Order the vector with bubble sort\n" ;
16 for ( int i = 0 ; i < size-1 ; ++i )
17 // find minimum of v[i]...v[size-1] ;
18 for ( int j = i+1 ; j < size ; ++j )
19 if ( v[i] > v[j] )
20 swap(v[i],v[j]) ; // uso swap function of STL algorithm
21}
22
23// tell the compiler to generate code for Type = int, float and double
24template void sort<int> ( int size, int v[] ) ;
25template void sort<float> ( int size, float v[] ) ;
26template void sort<double>( int size, double v[] ) ;
Using sort of STL
File example_template3.cc
:open:
1/*
2// Example of overloading
3//
4*/
5
6#include <iostream>
7#include <algorithm>
8
9using namespace std ;
10
11int v[] = {4,5,2, -1, 3, 0, -23, 123 } ;
12int sv = sizeof(v) / sizeof(v[0]) ;
13 // size in byte of v / size in bite of first element
14
15double rv[] = {-0.1, 4.1, 5.3,2.2, -1.1, 3.2234, 0.0213, -23.1, 123. } ;
16int srv = sizeof(rv) / sizeof(rv[0]) ;
17
18float fv[] = {-0.1, 4.1, 5.3,2.2, -1.1, 3.2234, 0.0213, -23.1, 123. } ;
19int sfv = sizeof(fv) / sizeof(fv[0]) ;
20
21int
22main() {
23 sort( v, v + sv ) ; // call the STL sort routine
24 for ( int i = 0 ; i < sv ; ++i )
25 cout << "v[" << i << "] = " << v[i] << "\n" ;
26
27 sort( rv, rv + srv ) ;
28 for ( int i = 0 ; i < srv ; ++i )
29 cout << "rv[" << i << "] = " << rv[i] << "\n" ;
30
31 sort( fv, fv + sfv ) ;
32 for ( int i = 0 ; i < sfv ; ++i )
33 cout << "fv[" << i << "] = " << fv[i] << "\n" ;
34
35 return 0 ;
36}
Class template and STL
A simple example of class template
File class_template.cc
:open:
1/*
2// Example of template of a class
3//
4*/
5
6#include <iostream>
7#include <algorithm>
8
9using namespace std ;
10
11// define the generic class PointXY
12template <typename Type>
13class PointXY {
14 Type x, y ;
15public:
16
17} ;
18
19int
20main() {
21 PointXY<int> p1 ; // instatiate the class PointXY with type int
22 PointXY<double> p2 ; // instatiate the class PointXY with type double
23 return 0 ;
24}
An example using vector of STL
File vector_example.cc
:open:
1/*
2// Example of use of tempatye class vector
3//
4*/
5
6#include <iostream>
7#include <algorithm>
8#include <vector>
9
10using namespace std ;
11/*
12// Example of overloading
13//
14*/
15
16#include <iostream>
17#include <algorithm>
18
19/*
20// Common methos for neal all containers
21//
22// begin() return an iterator pointing to the first element
23// end() return an iterator pointing to past to last element
24// operator ++ move the iterator forward by an element
25// operator -- move the iterator backward by an element
26// front() equivalent to *begin()
27// back() near equivalent to *(end()-1)
28//
29// push_back(element) add an element to the tail of the container
30//
31// size() return the number of element of the container
32//
33//
34// resize(new_size) (for vector like container)
35//
36// insert (various way, see documentation)
37//
38// for more documentation see e.g. http://www.sgi.com/tech/stl/
39//
40*/
41
42using namespace std ;
43
44int
45main() {
46 vector<double> v ;
47
48 v . push_back(-0.1) ;
49 v . push_back(4.1) ;
50 v . push_back(5.3) ;
51 v . push_back(2.2) ;
52 v . push_back(-1.1) ;
53 v . push_back(3.2234 ) ;
54 v . push_back(0.0213 ) ;
55 v . push_back(-23.1) ;
56 v . push_back(123.) ;
57
58 sort( v . begin(), // iterator pointing to the first element
59 v . end() ) ; // iterator pointing to past to the last element
60
61 // loop to the elements of vector (old way)
62 for ( int i = 0 ; i < v.size() ; ++i )
63 cout << "v[" << i << "] = " << v[i] << "\n" ;
64
65 vector<double>::iterator iv ;
66 for ( iv = v.begin() ; iv != v.end() ; ++iv ) {
67 cout << *iv << "\n" ;
68 }
69 return 0 ;
70}
Using STL in an old example
The prime number calculation with vector of STL
File 16.cc
:open:
1/*
2 Example to print first N prime numbers,
3 */
4
5#include <iostream>
6#include <iomanip>
7#include <vector>
8
9using namespace std ;
10
11// define N as a preprocess variable, will be substitued
12// by the preprocessing phase
13#define N 1000
14
15template <typename IntType>
16bool // boolean type, store true or false value only
17// check if candidate is a prime number respect to the vector primes
18// return true if primes[i] do not divide candidate for each i
19checkPrime( vector<IntType> const & primes, IntType const & candidate ) {
20 typename vector<IntType>::const_iterator i ;
21 for ( i = primes . begin() ; i != primes.end() ; ++i ) {
22 if ( ( candidate % (*i) ) == 0 ) // if remainder is 0 it is not a prime!
23 return false ;
24 }
25 return true ;
26}
27
28template <typename IntType>
29void // void type, nothing to return!
30addPrime( vector<IntType> & primes ) {
31 IntType candidate = primes . back() + 1 ;
32 // ! is the negation operator ! true = false.
33 while ( ! checkPrime( primes, candidate) ) ++candidate ;
34 primes . push_back(candidate) ;
35}
36
37template <typename IntType>
38void
39printNumbers( ostream & s,
40 vector<IntType> const & primes ) {
41 int kk = 0 ;
42 typename vector<IntType>::const_iterator i ;
43 for ( i = primes . begin() ; i != primes.end() ; ++i ) {
44 // print the number to the file fd (can be stdout)
45 // no new line or others amenity
46 s << setw(5) << *i ;
47 ++kk ; // increment the counter
48
49 // decide if to use comma of newline
50 if ( (kk%10) == 0 ) s << "\n" ;
51 else s << ", " ;
52 }
53 s << "\n" ;
54}
55
56int
57main ()
58{
59 vector<long int> primes ;
60 primes . push_back(2) ;
61 primes . push_back(3) ;
62 primes . push_back(5) ;
63 primes . push_back(7) ;
64
65 do {
66 addPrime( primes ) ;
67 } while ( primes . size() < N ) ; // chech if it must cycle again
68
69 printNumbers( cout, primes ) ; // print the result to standard output
70
71 return 0 ;
72}
A generic graphics driver with a postscript driver
Declaration of Gr::Driver
class
File GrDriver.hh
:open:
1#ifndef GR_DRIVER_H
2#define GR_DRIVER_H
3
4#include <string>
5
6namespace Gr {
7
8 using namespace std ;
9
10 typedef double valueType ;
11 typedef int indexType ;
12
13 typedef enum { GR_TIMES=0,
14 GR_HELVETICA,
15 GR_COURIER } FontType ;
16
17 typedef enum { GR_NORMAL=0,
18 GR_BOLD,
19 GR_OBLIQUE,
20 GR_BOLDOBLIQUE } FontFace ;
21
22 typedef enum { GR_ALIGN_UP_LEFT=0,
23 GR_ALIGN_UP_CENTER,
24 GR_ALIGN_UP_RIGHT,
25 GR_ALIGN_LEFT,
26 GR_ALIGN_CENTER,
27 GR_ALIGN_RIGHT,
28 GR_ALIGN_DOWN_LEFT,
29 GR_ALIGN_DOWN_CENTER,
30 GR_ALIGN_DOWN_RIGHT } FontAlign ;
31
32 typedef enum { GR_ARROW_SIMPLE=0,
33 GR_ARROW_EMPTY,
34 GR_ARROW_FILL,
35 GR_ARROW_SIMPLE_EMPTY,
36 GR_ARROW_SIMPLE_FILL } ArrowType ;
37
38 class RgbGolor {
39
40 valueType r, g, b ;
41
42 public:
43
44 RgbGolor() ;
45 RgbGolor( valueType rr, valueType gg, valueType bb ) ;
46
47 void
48 operator () ( valueType rr,
49 valueType gg,
50 valueType bb )
51 { r = rr ; g = gg ; b = bb ; }
52
53 valueType red() const { return r ; }
54 valueType green() const { return g ; }
55 valueType blue() const { return b ; }
56 } ;
57
58 #define GR_DRIVER_INTERFACE(PV) \
59 virtual void window( valueType xm, \
60 valueType xM, \
61 valueType ym, \
62 valueType yM ) PV ; \
63 \
64 virtual void clip ( valueType x1, \
65 valueType y1, \
66 valueType x2, \
67 valueType y2 ) PV ; \
68 \
69 virtual void setFont( FontType, FontFace, indexType size ) PV ; \
70 \
71 virtual void rgbColor( valueType r, valueType g, valueType b ) PV ; \
72 virtual void hsbColor( valueType r, valueType g, valueType b ) PV ; \
73 \
74 virtual void setLineWidth( valueType w ) PV ; \
75 virtual void setLineStyle( string const & s ) PV ; \
76 virtual void setLineStyle( int s ) PV ; \
77 virtual void line( valueType x1, \
78 valueType y1, \
79 valueType x2, \
80 valueType y2 ) PV ; \
81 \
82 virtual void box( valueType x1, \
83 valueType y1, \
84 valueType x2, \
85 valueType y2, \
86 bool fill = false) PV ; \
87 \
88 virtual void roundBox( valueType x1, \
89 valueType y1, \
90 valueType x2, \
91 valueType y2, \
92 valueType r, \
93 bool fill = false) PV ; \
94 \
95 virtual void circle( valueType x, \
96 valueType y, \
97 valueType r, \
98 bool fill = false) PV ; \
99 \
100 virtual void ellipse( valueType x, \
101 valueType y, \
102 valueType r1, \
103 valueType r2, \
104 bool fill = false) PV ; \
105 \
106 virtual void poly( indexType n, \
107 valueType const x[], \
108 valueType const y[], \
109 bool close = false, \
110 bool fill = false) PV ; \
111 \
112 virtual void polyOffset( indexType n, \
113 valueType const x[], \
114 valueType const y[], \
115 valueType dx = 0, \
116 valueType dy = 0, \
117 bool close = false, \
118 bool fill = false) PV ; \
119 \
120 virtual void bezier( valueType x1, valueType y1, \
121 valueType x2, valueType y2, \
122 valueType x3, valueType y3, \
123 valueType x4, valueType y4) PV ; \
124 \
125 virtual void arc( valueType cx, \
126 valueType cy, \
127 valueType r, \
128 valueType t1, \
129 valueType t2, \
130 bool fill = false) PV ; \
131 \
132 virtual void drawText( valueType x, \
133 valueType y, \
134 string const & str, \
135 FontAlign align, \
136 valueType angle ) PV ; \
137 \
138 virtual void arrow( valueType x, \
139 valueType y, \
140 valueType dx, \
141 valueType dy, \
142 ArrowType at) ; \
143 \
144 virtual void square( valueType x, \
145 valueType y, \
146 valueType r, \
147 bool fill = false) ; \
148 \
149 virtual void diamond( valueType x, \
150 valueType y, \
151 valueType r, \
152 bool fill = false) ; \
153 \
154 virtual void plus( valueType x, \
155 valueType y, \
156 valueType r ) ; \
157 \
158 virtual void cross( valueType x, \
159 valueType y, \
160 valueType r ) ; \
161 \
162 virtual void star( valueType x, \
163 valueType y, \
164 valueType r, \
165 bool fill = false )
166
167 class Driver {
168 public:
169 Driver() {} ;
170 ~Driver() {} ;
171
172 GR_DRIVER_INTERFACE(=0);
173
174 void rgbColor( RgbGolor const & c)
175 { rgbColor(c.red(),c.green(),c.blue()) ; }
176
177 void red() { rgbColor(1,0,0) ; }
178 void green() { rgbColor(0,1,0) ; }
179 void blue() { rgbColor(0,0,1) ; }
180 void yellow() { rgbColor(1,1,0) ; }
181 void pink() { rgbColor(1,0,1) ; }
182 void cyan() { rgbColor(0,1,1) ; }
183 void white() { rgbColor(0.9,0.9,0.9) ; }
184 void black() { rgbColor(0,0,0) ; }
185
186 } ;
187}
188
189#endif
Definition of Gr::Driver class
File GrDriver.cc
:open:
1#include "GrDriver.hh"
2
3namespace Gr {
4
5 RgbGolor::RgbGolor()
6 : r(0), g(0), b(0)
7 {}
8
9 RgbGolor::RgbGolor( valueType rr,
10 valueType gg,
11 valueType bb )
12 : r(rr), g(gg), b(bb)
13 {}
14
15 static valueType xf[8] = { 0, 0.8, 0.8, 1, 0.8, 0.8, 0, 0.8} ;
16 static valueType yf[8] = { -0.025, -0.025, -0.1, 0, 0.1, 0.025, 0.025, 0 } ;
17
18 void
19 Driver::arrow( valueType xx,
20 valueType yy,
21 valueType dx,
22 valueType dy,
23 ArrowType at ) {
24
25 valueType x[8], y[8] ;
26
27 for ( int i=0 ; i < 8 ; i++ ) {
28 x[i] = xx+(dx*xf[i]-dy*yf[i]) ;
29 y[i] = yy+(dy*xf[i]+dx*yf[i]) ;
30 }
31
32 switch (at) {
33 case GR_ARROW_SIMPLE:
34 line(xx,yy,x[3],y[3]) ;
35 line(x[3],y[3],x[2],y[2]) ;
36 line(x[3],y[3],x[4],y[4]) ;
37 break ;
38
39 case GR_ARROW_EMPTY:
40 poly(7,x,y,true,false) ;
41 break ;
42
43 case GR_ARROW_FILL:
44 poly(7,x,y,true,true) ;
45 break ;
46
47 case GR_ARROW_SIMPLE_EMPTY:
48 line(xx,yy,x[7],y[7]) ;
49 poly(3,x+2,y+2,true,false) ;
50 break ;
51
52 case GR_ARROW_SIMPLE_FILL:
53 line(xx,yy,x[7],y[7]) ;
54 poly(3,x+2,y+2,true,true) ;
55 break ;
56 }
57 } ;
58
59 void
60 Driver::square( valueType x,
61 valueType y,
62 valueType r,
63 bool fill ) {
64 box(x-r,y-r,x+r,y+r,fill) ;
65 } ;
66
67 void
68 Driver::diamond( valueType xx,
69 valueType yy,
70 valueType r,
71 bool fill ) {
72 valueType x[4], y[4] ;
73 x[0] = xx ; y[0] = yy-r ;
74 x[1] = xx+r ; y[1] = yy ;
75 x[2] = xx ; y[2] = yy+r ;
76 x[3] = xx-r ; y[3] = yy ;
77 poly(4,x,y,true,fill) ;
78 }
79
80 void
81 Driver::plus( valueType x, valueType y, valueType r ) {
82 line(x,y-r,x,y+r) ;
83 line(x-r,y,x+r,y) ;
84 }
85
86 void
87 Driver::cross( valueType x, valueType y, valueType r ) {
88 line(x-r,y-r,x+r,y+r) ;
89 line(x+r,y-r,x-r,y+r) ;
90 }
91
92 void
93 Driver::star( valueType xx, valueType yy, valueType r, bool fill ) {
94 valueType x[10], y[10] ;
95 x[0] = xx ; y[0] = yy + r ;
96 x[1] = xx - 0.196 * r ; y[1] = yy + 0.27 * r ;
97 x[2] = xx - 0.95 * r ; y[2] = yy + 0.31 * r ;
98 x[3] = xx - 0.32 * r ; y[3] = yy - 0.103 * r ;
99 x[4] = xx - 0.59 * r ; y[4] = yy - 0.81 * r ;
100 x[5] = xx ; y[5] = yy - 0.33333* r ;
101 x[6] = xx + 0.59 * r ; y[6] = yy - 0.81 * r ;
102 x[7] = xx + 0.32 * r ; y[7] = yy - 0.103 * r ;
103 x[8] = xx + 0.95 * r ; y[8] = yy + 0.31 * r ;
104 x[9] = xx + 0.196 * r ; y[9] = yy + 0.27 * r ;
105 poly(10,x,y,true,fill) ;
106 }
107
108}
Declaration of Gr::PsDriver
(the postscript driver class)
File PsDriver.hh
:open:
1#ifndef PSDRV_H
2#define PSDRV_H
3
4#include <fstream>
5#include "GrDriver.hh"
6
7namespace Gr {
8
9 using namespace std ;
10
11 class PsDriver : public Driver {
12
13 ofstream psf ;
14 bool blackandwhite ;
15 valueType width, height ;
16
17 void moveto(valueType x, valueType y) ;
18 void rmove(valueType x, valueType y) ;
19 void lineto(valueType x, valueType y) ;
20 void rline(valueType x, valueType y) ;
21 void outstr(const char str[]) ;
22 void translate(valueType tx, valueType ty) ;
23 void rotate(valueType angle) ;
24 void rotate(valueType dx, valueType dy) ;
25 void scale(valueType sx, valueType sy) ;
26 void arcto(valueType x1, valueType y1, valueType x2, valueType y2, valueType r) ;
27 void newpath() ;
28 void closepath() ;
29 void stroke() ;
30 void close_fill(bool c, bool f) ;
31
32 public:
33
34 PsDriver( string const & of, valueType w, valueType h, bool bw, bool ls) ;
35 ~PsDriver() ;
36
37 void setLineCap(indexType i) ;
38 void setLineJoin(indexType i) ;
39 void setLineMiterLimit(valueType d) ;
40
41 GR_DRIVER_INTERFACE() ;
42
43 } ;
44}
45
46#endif
Definition of Gr::PsDriver
(the postscript driver class)
File PsDriver.cc
:open:
1#include "PsDriver.hh"
2#include <cmath>
3#include <iostream>
4
5using namespace std ;
6
7namespace Gr {
8
9 static char *ps_macros[] = {
10 "/dl{2 mul} bind def",
11 "/M {moveto} bind def",
12 "/L {lineto} bind def",
13 "/R {rmoveto} bind def",
14 "/V {rlineto} bind def",
15 "/TT {translate} bind def",
16 "/RR {rotate} bind def",
17 "/SS {scale} bind def",
18 "/VV {gsave newpath 0 0 M (o) true charpath",
19 " flattenpath pathbbox grestore",
20 " exch pop exch pop exch pop} def",
21 "/HH {dup stringwidth pop} def",
22 "/showAT {/posy exch def /posx exch def gsave TT RR newpath 0 0 M",
23 " HH posx mul VV posy mul R show stroke grestore} def",
24 "/LDshowAT {-1 -1 showAT} def",
25 "/RDshowAT {0 -1 showAT} def",
26 "/CDshowAT {-0.5 -1 showAT} def",
27 "/LCshowAT {-1 -0.5 showAT} def",
28 "/RCshowAT {0 -0.5 showAT} def",
29 "/CCshowAT {-0.5 -0.5 showAT} def",
30 "/LUshowAT {-1 0 showAT} def",
31 "/RUshowAT {0 0 showAT} def",
32 "/CUshowAT {-0.5 0 showAT} def",
33 "/SAVE {/cmtx matrix currentmatrix def} def",
34 "/CHVIEW {/ty exch def /tx exch def /dy exch def /dx exch def /ndy {dy neg} def",
35 " SAVE [dx dy ndy dx tx ty] concat} def",
36 "/RESTORE {cmtx setmatrix} def",
37 "/ELL {gsave SAVE TT SS newpath 0 0 1 0 360 arc RESTORE closepath stroke grestore} def",
38 "/ELLF{gsave SAVE TT SS newpath 0 0 1 0 360 arc RESTORE closepath fill grestore} def",
39 "/BOX {gsave SAVE TT SS newpath 0 0 M 1 0 L 1 1 L 0 1 L 0 0 L RESTORE closepath stroke grestore} def",
40 "/BOXF{gsave SAVE TT SS newpath 0 0 M 1 0 L 1 1 L 0 1 L 0 0 L RESTORE closepath fill grestore} def",
41 "/LINE{newpath M L stroke} def",
42 "/ARPATH {newpath 0 -0.025 M 0.8 -0.025 L 0.8 -0.1 L 1 0 L 0.8 0.1 L 0.8 0.025 L 0 0.025 L closepath} def",
43 "/ARPATHB {newpath 0 0 M 0.8 0 L 0.8 -0.1 L 1 0 L 0.8 0.1 L 0.8 0 L closepath} def",
44 "/ARS {CHVIEW newpath 0 0 M 1 0 L 0.8 0.025 M 0 1 L 0.8 -0.025 L",
45 " RESTORE stroke grestore} def",
46 "/ARE {gsave CHVIEW ARPATH RESTORE stroke grestore} def",
47 "/ARF {gsave CHVIEW ARPATH RESTORE fill grestore} def",
48 "/ARSE {gsave CHVIEW ARPATHB RESTORE stroke grestore} def",
49 "/ARSF {gsave CHVIEW ARPATHB RESTORE fill grestore} def",
50 "/SE {gsave SAVE TT dup SS newpath -1 -1 M 1 -1 L 1 1 L -1 1 L RESTORE closepath stroke grestore} def",
51 "/SF {gsave SAVE TT dup SS newpath -1 -1 M 1 -1 L 1 1 L -1 1 L RESTORE closepath fill grestore} def",
52 "/DE {gsave SAVE TT dup SS newpath 0 -1 M 1 0 L 0 1 L -1 0 L RESTORE closepath stroke grestore} def",
53 "/DF {gsave SAVE TT dup SS newpath 0 -1 M 1 0 L 0 1 L -1 0 L RESTORE closepath fill grestore} def",
54 "/P {gsave SAVE TT dup SS newpath 0 -1 M 0 1 L -1 0 M 1 0 L RESTORE stroke grestore} def",
55 "/C {gsave SAVE TT dup SS newpath -1 -1 M 1 1 L -1 1 M 1 -1 L RESTORE stroke grestore} def",
56 "/SPATH {newpath 0 1 M -0.196 0.27 L -0.95 0.31 L -0.32 -0.103 L",
57 " -0.59 -0.81 L 0 -0.333333 L 0.59 -0.81 L 0.32 -0.103 L",
58 " 0.95 0.31 L 0.196 0.27 L closepath} def",
59 "/STARE { gsave SAVE TT dup SS SPATH RESTORE stroke grestore} def",
60 "/STARF { gsave SAVE TT dup SS SPATH RESTORE fill grestore} def",
61 "/TR {/size exch def /Times-Roman findfont size scalefont setfont} def",
62 "/TRB {/size exch def /Times-Bold findfont size scalefont setfont} def",
63 "/TRO {/size exch def /Times-Italic findfont size scalefont setfont} def",
64 "/TRBO {/size exch def /Times-BoldItalic findfont size scalefont setfont} def",
65 "/HE {/size exch def /Helvetica findfont size scalefont setfont} def",
66 "/HEB {/size exch def /Helvetica-Bold findfont size scalefont setfont} def",
67 "/HEO {/size exch def /Helvetica-Oblique findfont size scalefont setfont} def",
68 "/HEBO {/size exch def /Helvetica-BoldOblique size findfont scalefont setfont} def",
69 "/CO {/size exch def /Courier findfont size scalefont setfont} def",
70 "/COB {/size exch def /Courier-Bold findfont size scalefont setfont} def",
71 "/COO {/size exch def /Courier-Oblique findfont size scalefont setfont} def",
72 "/COBO {/size exch def /Courier-BoldOblique findfont size scalefont setfont} def",
73 NULL } ;
74
75 PsDriver::PsDriver( string const & of,
76 valueType w,
77 valueType h,
78 bool bw,
79 bool landscape )
80 : width(w)
81 , height(h)
82 , blackandwhite(bw) {
83 psf.open(of.c_str()) ;
84 psf << "%%!PS-Adobe-2.0 EPSF-2.0\n"
85 << "%%Creator: EasyGraph\n"
86 << "%%Title: " << of << "\n"
87 << "%%CreationDate: no date\n"
88 << "%%%%BoundingBox: -1 -1 " << width+1 << " " << height+1 << "\n"
89 << "%%%%EndComments\n"
90 << "%%%%EndProlog\n" ;
91
92 for ( char **ppstr = ps_macros ; *ppstr != NULL ; ppstr++ )
93 psf << *ppstr << endl ;
94
95 psf << "24 TR" << endl
96 << "gsave" << endl
97 << (landscape?"-90 RR\n":"\n") ;
98 }
99
100 PsDriver::~PsDriver() {
101 psf << "showpage grestore\n%%%%Trailer\n" ;
102 psf.close() ;
103 }
104
105 void
106 PsDriver::moveto(valueType x, valueType y) {
107 psf << " " << x << " " << y << " M" ;
108 }
109
110 void
111 PsDriver::rmove (valueType x, valueType y) {
112 psf << " " << x << " " << y << " R" ;
113 }
114
115 void
116 PsDriver::lineto(valueType x, valueType y) {
117 psf << " " << x << " " << y << " L" ;
118 }
119
120 void
121 PsDriver::rline (valueType x, valueType y) {
122 psf << " " << x << " " << y << " V" ;
123 }
124
125 void
126 PsDriver::arcto( valueType x1, valueType y1,
127 valueType x2, valueType y2,
128 valueType r) {
129 psf << " " << x1 << " " << y1 << " " << x2 << " " << y2 << " " << r << " arcto" ;
130 }
131
132 void
133 PsDriver::translate(valueType tx, valueType ty) {
134 psf << " " << tx << " " << ty << " TT" ;
135 }
136
137 void
138 PsDriver::rotate(valueType angle) {
139 psf << " " << angle << " RR" ;
140 }
141
142 void
143 PsDriver::rotate(valueType dx, valueType dy) {
144 psf << " " << dy << " " << dx << " atan RR" ;
145 }
146
147 void
148 PsDriver::scale(valueType sx, valueType sy) {
149 psf << " " << sx << " " << sy << " SS" ;
150 }
151
152 void
153 PsDriver::newpath() {
154 psf << " newpath" ;
155 }
156
157 void
158 PsDriver::closepath() {
159 psf << " closepath" ;
160 }
161
162 void
163 PsDriver::close_fill(bool c, bool f) {
164 psf << (c?" closepath":"") << ( f? " fill" : " stroke") << endl ;
165 }
166
167 void PsDriver::stroke() {
168 psf << " stroke" ;
169 }
170
171 void
172 PsDriver::outstr(const char *s) {
173 psf << " (" ;
174 for ( const char *pc = s ; *pc != 0 ; ++pc ) {
175 psf << ( ( *pc == '(' || *pc == ')' || *pc == '\\' ) ? "\\" : "" ) << *pc ;
176 }
177 psf << ") " ;
178 }
179
180 void
181 PsDriver::window(valueType xm, valueType xM, valueType ym, valueType yM) {
182 translate(xm,ym) ;
183 scale(width/(xM-xm),height/(yM-ym)) ;
184 psf << "\n" ;
185 }
186
187 void
188 PsDriver::clip(valueType x1, valueType y1, valueType x2, valueType y2) {
189 newpath() ;
190 moveto(x1,y1) ;
191 lineto(x1,y2) ;
192 lineto(x2,y2) ;
193 lineto(x2,y1) ;
194 psf << " closepath clip\n" ;
195 }
196
197 void
198 PsDriver::setFont(FontType f, FontFace fa, indexType size) {
199 psf << " " << size ;
200 switch (f) {
201 case GR_TIMES: psf << " TR" ; break ;
202 case GR_HELVETICA: psf << " HE" ; break ;
203 case GR_COURIER: psf << " CO" ; break ;
204 }
205
206 switch (fa) {
207 case GR_NORMAL: psf << "\n" ; break ;
208 case GR_BOLD: psf << "B\n" ; break ;
209 case GR_OBLIQUE: psf << "O\n" ; break ;
210 case GR_BOLDOBLIQUE: psf << "BO\n" ; break ;
211 }
212 }
213
214 static char *align_show[] = {" LUshowAT", " CUshowAT", " RUshowAT",
215 " LCshowAT", " CCshowAT", " RCshowAT",
216 " LDshowAT", " CDshowAT", " RDshowAT" } ;
217
218 void
219 PsDriver::drawText( valueType x,
220 valueType y,
221 string const & s,
222 FontAlign align,
223 valueType angle ) {
224 outstr(s.c_str()) ;
225 psf << angle << " " << x << " " << y << align_show[align] << "\n" ;
226 }
227
228 void
229 PsDriver::rgbColor(valueType r, valueType g, valueType b) {
230 if (blackandwhite)
231 psf << " " << (3*r+2*g+b)/6 << " setgray\n" ;
232 else
233 psf << " " << r << " " << g << " " << b << " setrgbcolor\n" ;
234 }
235
236 void
237 PsDriver::hsbColor(valueType h, valueType s, valueType l) {
238 if (blackandwhite)
239 psf << " " << l << " setgray\n" ;
240 else
241 psf << " " << h << " " << s << " " << l << " sethsbcolor\n" ;
242 }
243
244 // lcap, 0= butt, 1=round, 2=projecting square
245 void
246 PsDriver::setLineCap(indexType i) {
247 psf << i << " setlinecap\n" ;
248 }
249
250 void
251 PsDriver::setLineJoin(indexType i) {
252 psf << i << " setlinejoin\n" ;
253 }
254
255 void
256 PsDriver::setLineMiterLimit(valueType d) {
257 psf << d << " setmiterlimit\n" ;
258 }
259
260 void
261 PsDriver::setLineWidth(valueType w) {
262 psf << w << " setlinewidth\n" ;
263 }
264
265 void
266 PsDriver::setLineStyle( string const & s ) {
267 psf << "[" << s << "] 0 setdash\n" ;
268 }
269
270 void
271 PsDriver::setLineStyle(indexType i) {
272 static char *defline[] = {
273 "", "1 dl 2 dl", "4 dl 2 dl", "2 dl 3 dl",
274 "1 dl 1.5 dl", "5 dl 2 dl 1 dl 2 dl", "4 dl 3 dl 1 dl 3 dl",
275 "2 dl 2 dl 2 dl 4 dl", "2 dl 2 dl 2 dl 2 dl 2 dl 4 dl",
276 "2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 4 dl"} ;
277 setLineStyle(defline[i<0 ? 0 : ( i>9 ? 9 : i)]) ;
278 }
279
280 void
281 PsDriver::line(valueType x1, valueType y1, valueType x2, valueType y2) {
282 psf << " " << x1 << " " << y1
283 << " " << x2 << " " << y2
284 << " LINE\n" ;
285 }
286
287 void
288 PsDriver::box(valueType x1, valueType y1, valueType x2, valueType y2, bool fill) {
289 psf << " " << x2-x1 << " " << y2-y1
290 << " " << x1 << " " << y1
291 << (fill?" BOXF\n":" BOX\n") ;
292 }
293
294 void
295 PsDriver::roundBox( valueType x1,
296 valueType y1,
297 valueType x2,
298 valueType y2,
299 valueType r,
300 bool fill ) {
301 newpath() ;
302 moveto(x2-r,y1) ;
303 arcto(x2,y1,x2,y1+r,r) ;
304 lineto(x2,y2-r) ;
305 arcto(x2,y2,x2-r,y2,r) ;
306 lineto(x1+r,y2) ;
307 arcto(x1,y2,x1,y2-r,r) ;
308 lineto(x1,y1+r) ;
309 arcto(x1,y1,x1+r,y1,r) ;
310 lineto(x2-r,y1) ;
311 close_fill(true,fill) ;
312 }
313
314 void
315 PsDriver::circle(valueType x, valueType y, valueType r, bool fill) {
316 ellipse(x,y,r,r,fill) ;
317 }
318
319 void
320 PsDriver::ellipse(valueType x, valueType y, valueType r1, valueType r2, bool fill) {
321 psf << " " << r1 << " " << r2
322 << " " << x << " " << y
323 << (fill? " ELLF\n" : " ELL\n") ;
324 }
325
326 void
327 PsDriver::poly( indexType n,
328 valueType const x[],
329 valueType const y[],
330 bool close,
331 bool fill) {
332 newpath() ;
333 moveto(x[0],y[0]) ;
334 for (int i=1 ; i < n ; i++ )
335 { lineto(x[i],y[i]) ; if ( (i%6) == 0 ) psf << "\n" ; }
336 close_fill(close,fill) ;
337 }
338
339 void
340 PsDriver::polyOffset( indexType n,
341 valueType const x[],
342 valueType const y[],
343 valueType dx,
344 valueType dy,
345 bool close,
346 bool fill) {
347 newpath() ;
348 moveto(dx+x[0],dy+y[0]) ;
349 for (int i=1 ; i < n ; i++ )
350 { lineto(dx+x[i],dy+y[i]) ; if ( (i%6) == 0 ) psf << "\n" ; }
351 close_fill(close,fill) ;
352 }
353
354 void
355 PsDriver::arc( valueType cx,
356 valueType cy,
357 valueType r,
358 valueType t1,
359 valueType t2,
360 bool fill ) {
361 newpath() ;
362 if ( fill) moveto(cx,cy) ;
363 psf << " " << cx << " " << cy << " " << r
364 << " " << t1 << " " << t2 << " arc" ;
365 close_fill(fill,fill) ;
366 }
367
368 void
369 PsDriver::bezier( valueType x1, valueType y1,
370 valueType x2, valueType y2,
371 valueType x3, valueType y3,
372 valueType x4, valueType y4) {
373 newpath() ;
374 moveto(x1,y1) ;
375 psf << " " << x2 << " " << y2
376 << " " << x3 << " " << y3
377 << " " << x4 << " " << y4
378 << " curveto stroke"<< endl ;
379 }
380
381 static char *artype[] = { " ARS", " ARE", " ARF", " ARSE", " ARSF" } ;
382
383 void
384 PsDriver::arrow( valueType xx,
385 valueType yy,
386 valueType dx,
387 valueType dy,
388 ArrowType at ) {
389 psf << " " << dx << " " << dy
390 << " " << xx << " " << yy
391 << artype[at] << "\n" ;
392 } ;
393
394 void
395 PsDriver::square(valueType x, valueType y, valueType r, bool fill) {
396 psf << " " << r << " " << x << " " << y << (fill?" SF\n":" SE\n") ;
397 }
398
399 void
400 PsDriver::diamond(valueType x, valueType y, valueType r, bool fill) {
401 psf << " " << r << " " << x << " " << y << (fill?" DF\n":" DE\n") ;
402 }
403
404 void
405 PsDriver::plus(valueType x, valueType y, valueType r) {
406 psf << " " << r << " " << x << " " << y << " P\n" ;
407 }
408
409 void PsDriver::cross(valueType x, valueType y, valueType r) {
410 psf << " " << r << " " << x << " " << y << " C\n" ;
411 }
412
413 void
414 PsDriver::star(valueType x, valueType y, valueType r, bool fill) {
415 psf << " " << r << " " << x << " " << y << (fill?" STARF\n":" STARE\n") ;
416 }
417
418}
Declaration of Gr::Object
class
File GrObject.hh
:open:
1#ifndef GR_OBJ_H
2#define GR_OBJ_H
3
4#include "GrDriver.hh"
5#include <string>
6
7namespace Gr {
8
9 using namespace std ;
10
11 typedef struct { valueType x, y ; } GrXY ;
12 typedef struct { GrXY min, max ; } Bbox ;
13
14 /*
15 // ___ _ _ _
16 // / _ \| |__ (_) ___ ___| |_
17 // | | | | '_ \| |/ _ \/ __| __|
18 // | |_| | |_) | | __/ (__| |_
19 // \___/|_.__// |\___|\___|\__|
20 // |__/
21 */
22
23 class Object {
24 protected:
25 Bbox bb ; // bounding box
26 void setbb( valueType xm, valueType ym, valueType xM, valueType yM ) ;
27
28 public:
29 Object() ;
30 Object( valueType _cx, valueType _cy, valueType _hdx, valueType _hdy ) ;
31
32 virtual ~Object() {} ;
33 virtual void draw(Driver *gr) = 0 ;
34
35 valueType wx() const { return bb.max.x-bb.min.x ; }
36 valueType wy() const { return bb.max.y-bb.min.y ; }
37 valueType cx() const { return (bb.max.x+bb.min.x)/2 ; }
38 valueType cy() const { return (bb.max.y+bb.min.y)/2 ; }
39 } ;
40
41 /*
42 // ____ _ _
43 // | _ \ ___ ___| |_ __ _ _ __ __ _| | ___
44 // | |_) / _ \/ __| __/ _` | '_ \ / _` | |/ _ \
45 // | _ < __/ (__| || (_| | | | | (_| | | __/
46 // |_| \_\___|\___|\__\__,_|_| |_|\__, |_|\___|
47 // |___/
48 */
49 class Rectangle : public Object {
50 bool filled ;
51 public:
52 Rectangle( valueType xm, valueType ym,
53 valueType xM, valueType yM,
54 bool e) ;
55 virtual void draw(Driver *gr) ;
56 } ;
57
58 /*
59 // ____ _ ____ _ _
60 // | _ \ ___ _ _ _ __ __| | _ \ ___ ___| |_ __ _ _ __ __ _| | ___
61 // | |_) / _ \| | | | '_ \ / _` | |_) / _ \/ __| __/ _` | '_ \ / _` | |/ _ \
62 // | _ < (_) | |_| | | | | (_| | _ < __/ (__| || (_| | | | | (_| | | __/
63 // |_| \_\___/ \__,_|_| |_|\__,_|_| \_\___|\___|\__\__,_|_| |_|\__, |_|\___|
64 // |___/
65 */
66 class RoundRectangle : public Object {
67 bool filled ;
68 valueType ray ;
69 public:
70 RoundRectangle( valueType xm, valueType ym,
71 valueType xM, valueType yM,
72 valueType r, bool e) ;
73 virtual void draw(Driver *gr) ;
74 } ;
75
76 /*
77 // _____ _ _ _
78 // | ____| | (_)_ __ ___ ___
79 // | _| | | | | '_ \/ __|/ _ \
80 // | |___| | | | |_) \__ \ __/
81 // |_____|_|_|_| .__/|___/\___|
82 // |_|
83 */
84 class Ellipse : public Object {
85 bool filled ;
86 valueType ray1, ray2 ;
87 public:
88 Ellipse( valueType x, valueType y,
89 valueType r1, valueType r2,
90 bool e) ;
91 virtual void draw(Driver *gr) ;
92 } ;
93
94 /*
95 // ____ _ _
96 // / ___| _ _ _ __ ___ | |__ ___ | |
97 // \___ \| | | | '_ ` _ \| '_ \ / _ \| |
98 // ___) | |_| | | | | | | |_) | (_) | |
99 // |____/ \__, |_| |_| |_|_.__/ \___/|_|
100 // |___/
101 */
102 class Symbol : public Object {
103 public:
104 Symbol(valueType _cx, valueType _cy, valueType _hdx, valueType _hdy) ;
105 virtual ~Symbol() {} ;
106 void move(valueType xx, valueType yy);
107 } ;
108
109 /*
110 // ____
111 // / ___| __ _ _ _ __ _ _ __ ___
112 // \___ \ / _` | | | |/ _` | '__/ _ \
113 // ___) | (_| | |_| | (_| | | | __/
114 // |____/ \__, |\__,_|\__,_|_| \___|
115 // |_|
116 */
117 class Square : public Symbol {
118 bool filled ;
119 public:
120 Square(valueType x, valueType y, valueType r, bool e) ;
121 virtual void draw(Driver *gr) ;
122 } ;
123
124 /*
125 // ____ _ _
126 // / ___(_)_ __ ___| | ___
127 // | | | | '__/ __| |/ _ \
128 // | |___| | | | (__| | __/
129 // \____|_|_| \___|_|\___|
130 */
131 class Circle : public Symbol {
132 valueType ray ;
133 bool filled ;
134 public:
135 Circle(valueType x, valueType y, valueType r, bool e) ;
136 virtual void draw(Driver *gr) ;
137 } ;
138
139 /*
140 // _____ ____ _ _
141 // | ___| _ _ __ _ __ _ _ / ___(_)_ __ ___| | ___
142 // | |_ | | | | '_ \| '_ \| | | | | | | '__/ __| |/ _ \
143 // | _|| |_| | | | | | | | |_| | |___| | | | (__| | __/
144 // |_| \__,_|_| |_|_| |_|\__, |\____|_|_| \___|_|\___|
145 // |___/
146 */
147 class FunnyCircle : public Symbol {
148 valueType ray ;
149 public:
150 FunnyCircle(valueType x, valueType y, valueType r) ;
151 virtual void draw(Driver *gr) ;
152 } ;
153
154 /*
155 // ____ _ _
156 // | _ \(_) __ _ _ __ ___ ___ _ __ __| |
157 // | | | | |/ _` | '_ ` _ \ / _ \| '_ \ / _` |
158 // | |_| | | (_| | | | | | | (_) | | | | (_| |
159 // |____/|_|\__,_|_| |_| |_|\___/|_| |_|\__,_|
160 */
161 class Diamond : public Symbol {
162 bool filled ;
163 public:
164 Diamond( valueType _x, valueType _y, valueType _r, bool _e ) ;
165 virtual void draw(Driver *gr) ;
166 } ;
167
168 /*
169 // ____ _
170 // / ___|| |_ __ _ _ __
171 // \___ \| __/ _` | '__|
172 // ___) | || (_| | |
173 // |____/ \__\__,_|_|
174 */
175 class Star : public Symbol {
176 bool filled ;
177 public:
178 Star(valueType _x, valueType _y, valueType _r, bool _e ) ;
179 virtual void draw(Driver *gr) ;
180 } ;
181
182 /*
183 // ____ _
184 // | _ \| |_ _ ___
185 // | |_) | | | | / __|
186 // | __/| | |_| \__ \
187 // |_| |_|\__,_|___/
188 */
189 class Plus : public Symbol {
190 public:
191 Plus(valueType x, valueType y, valueType r) ;
192 virtual void draw(Driver *gr) ;
193 } ;
194
195 /*
196 // ____
197 // / ___|_ __ ___ ___ ___
198 // | | | '__/ _ \/ __/ __|
199 // | |___| | | (_) \__ \__ \
200 // \____|_| \___/|___/___/
201 */
202 class Cross : public Symbol {
203 public:
204 Cross(valueType x, valueType y, valueType r) ;
205 virtual void draw(Driver *gr) ;
206 } ;
207
208 /*
209 // ____ _ ____
210 // | _ \| |_ _ ___ / ___|_ __ ___ ___ ___
211 // | |_) | | | | / __| | | '__/ _ \/ __/ __|
212 // | __/| | |_| \__ \ |___| | | (_) \__ \__ \
213 // |_| |_|\__,_|___/\____|_| \___/|___/___/
214 */
215 class PlusCross : public Symbol {
216 public:
217 PlusCross(valueType x, valueType y, valueType r) ;
218 virtual void draw(Driver *gr) ;
219 } ;
220
221 /*
222 // _
223 // / \ _ __ _ __ _____ __
224 // / _ \ | '__| '__/ _ \ \ /\ / /
225 // / ___ \| | | | | (_) \ V V /
226 // /_/ \_\_| |_| \___/ \_/\_/
227 */
228 class Arrow : public Object {
229 ArrowType artype ;
230 valueType x, y, dx, dy ;
231 public:
232 Arrow( valueType _x,
233 valueType _y,
234 valueType _dx,
235 valueType _dy,
236 ArrowType at = GR_ARROW_SIMPLE) ;
237 virtual void draw(Driver *gr) ;
238 } ;
239
240 /*
241 // _____ _
242 // |_ _|____ _| |_
243 // | |/ _ \ \/ / __|
244 // | | __/> <| |_
245 // |_|\___/_/\_\\__|
246 */
247 class Text : public Object {
248 FontAlign align ;
249 FontType font ;
250 FontFace face ;
251 indexType size ;
252 valueType angle ;
253 string str ;
254 public:
255
256 Text( valueType x,
257 valueType y,
258 string const & _str,
259 FontType _font,
260 FontFace _face,
261 indexType _size,
262 FontAlign _align,
263 valueType _angle = 0) ;
264
265 void setText( string const & s ) { str = s ; }
266 virtual void draw(Driver *gr) ;
267
268 } ;
269
270}
271
272#endif
Definition of Gr::Object
classfile
File GrObject.cc
:open:
1#include "GrObject.hh"
2
3namespace Gr {
4
5 /*
6 // ___ _ _ _
7 // / _ \| |__ (_) ___ ___| |_
8 // | | | | '_ \| |/ _ \/ __| __|
9 // | |_| | |_) | | __/ (__| |_
10 // \___/|_.__// |\___|\___|\__|
11 // |__/
12 */
13
14 Object::Object()
15 {} ;
16
17 Object::Object( valueType _cx,
18 valueType _cy,
19 valueType _hdx,
20 valueType _hdy)
21 { setbb(_cx-_hdx,_cy-_hdy,_cx+_hdy,_cy+_hdy) ; }
22
23 void
24 Object::setbb( valueType xm,
25 valueType ym,
26 valueType xM,
27 valueType yM ) {
28 bb.min.x = xm ;
29 bb.max.x = xM ;
30 bb.min.y = ym ;
31 bb.max.y = yM ;
32 }
33
34 /*
35 // ____ _ _
36 // | _ \ ___ ___| |_ __ _ _ __ __ _| | ___
37 // | |_) / _ \/ __| __/ _` | '_ \ / _` | |/ _ \
38 // | _ < __/ (__| || (_| | | | | (_| | | __/
39 // |_| \_\___|\___|\__\__,_|_| |_|\__, |_|\___|
40 // |___/
41 */
42
43 Rectangle::Rectangle( valueType xm,
44 valueType ym,
45 valueType xM,
46 valueType yM,
47 bool e )
48 : filled(e)
49 { setbb(xm, ym, xM, yM) ; }
50
51 void
52 Rectangle::draw(Driver *gr) {
53 gr -> box(bb.min.x,bb.min.y,bb.max.x,bb.max.y,filled) ;
54 } ;
55
56 /*
57 // ____ _ ____ _ _
58 // | _ \ ___ _ _ _ __ __| | _ \ ___ ___| |_ __ _ _ __ __ _| | ___
59 // | |_) / _ \| | | | '_ \ / _` | |_) / _ \/ __| __/ _` | '_ \ / _` | |/ _ \
60 // | _ < (_) | |_| | | | | (_| | _ < __/ (__| || (_| | | | | (_| | | __/
61 // |_| \_\___/ \__,_|_| |_|\__,_|_| \_\___|\___|\__\__,_|_| |_|\__, |_|\___|
62 // |___/
63 */
64
65 RoundRectangle::RoundRectangle( valueType xm,
66 valueType ym,
67 valueType xM,
68 valueType yM,
69 valueType r,
70 bool e )
71 : ray(r)
72 , filled(e)
73 { setbb(xm, ym, xM, yM) ; }
74
75 void
76 RoundRectangle::draw(Driver *gr) {
77 gr -> roundBox(bb.min.x,bb.min.y,bb.max.x,bb.max.y,ray,filled) ;
78 } ;
79
80 /*
81 // _____ _ _ _
82 // | ____| | (_)_ __ ___ ___
83 // | _| | | | | '_ \/ __|/ _ \
84 // | |___| | | | |_) \__ \ __/
85 // |_____|_|_|_| .__/|___/\___|
86 // |_|
87 */
88
89 Ellipse::Ellipse( valueType x, valueType y,
90 valueType r1, valueType r2,
91 bool e )
92 : Object(x,y,r1,r2)
93 , ray1(r1)
94 , ray2(r2)
95 , filled(e)
96 {}
97
98 void
99 Ellipse::draw(Driver *gr) {
100 gr -> ellipse(cx(),cy(),ray1,ray2,filled) ;
101 } ;
102
103 /*
104 // ____ _ _
105 // / ___| _ _ _ __ ___ | |__ ___ | |
106 // \___ \| | | | '_ ` _ \| '_ \ / _ \| |
107 // ___) | |_| | | | | | | |_) | (_) | |
108 // |____/ \__, |_| |_| |_|_.__/ \___/|_|
109 // |___/
110 */
111
112 Symbol::Symbol( valueType _cx,
113 valueType _cy,
114 valueType _hdx,
115 valueType _hdy )
116 : Object(_cx,_cy,_hdx,_hdy)
117 {}
118
119 void
120 Symbol::move( valueType xx, valueType yy ) {
121 valueType tx = xx - cx(), ty = yy - cy() ;
122 bb.min.x += tx ; bb.max.x += tx ;
123 bb.min.y += ty ; bb.max.y += ty ;
124 }
125
126 /*
127 // ____
128 // / ___| __ _ _ _ __ _ _ __ ___
129 // \___ \ / _` | | | |/ _` | '__/ _ \
130 // ___) | (_| | |_| | (_| | | | __/
131 // |____/ \__, |\__,_|\__,_|_| \___|
132 // |_|
133 */
134
135 Square::Square( valueType x,
136 valueType y,
137 valueType r,
138 bool e )
139 : Symbol(x,y,r,r)
140 , filled(e)
141 {}
142
143 void
144 Square::draw(Driver *gr) {
145 gr -> box(bb.min.x,bb.min.y,bb.max.x,bb.max.y,filled) ;
146 }
147
148 /*
149 // ____ _ _
150 // / ___(_)_ __ ___| | ___
151 // | | | | '__/ __| |/ _ \
152 // | |___| | | | (__| | __/
153 // \____|_|_| \___|_|\___|
154 */
155
156 Circle::Circle( valueType x,
157 valueType y,
158 valueType r,
159 bool e )
160 : Symbol(x,y,r,r)
161 , ray(r)
162 , filled(e)
163 {}
164
165 void
166 Circle::draw(Driver *gr) {
167 gr -> circle(cx(),cy(),ray,filled) ;
168 }
169
170 /*
171 // _____ ____ _ _
172 // | ___| _ _ __ _ __ _ _ / ___(_)_ __ ___| | ___
173 // | |_ | | | | '_ \| '_ \| | | | | | | '__/ __| |/ _ \
174 // | _|| |_| | | | | | | | |_| | |___| | | | (__| | __/
175 // |_| \__,_|_| |_|_| |_|\__, |\____|_|_| \___|_|\___|
176 // |___/
177 */
178
179 FunnyCircle::FunnyCircle( valueType x,
180 valueType y,
181 valueType r )
182 : Symbol(x,y,r,r)
183 , ray(r)
184 {}
185
186 void
187 FunnyCircle::draw(Driver *gr) {
188 gr -> arc(cx(),cy(),ray,-45,45,true) ;
189 gr -> arc(cx(),cy(),ray,90-45,90+45,false) ;
190 gr -> arc(cx(),cy(),ray,180-45,180+45,true) ;
191 gr -> arc(cx(),cy(),ray,270-45,270+45,false) ;
192 }
193
194 /*
195 // ____ _ _
196 // | _ \(_) __ _ _ __ ___ ___ _ __ __| |
197 // | | | | |/ _` | '_ ` _ \ / _ \| '_ \ / _` |
198 // | |_| | | (_| | | | | | | (_) | | | | (_| |
199 // |____/|_|\__,_|_| |_| |_|\___/|_| |_|\__,_|
200 */
201
202 Diamond::Diamond( valueType _x,
203 valueType _y,
204 valueType _r,
205 bool _e )
206 : Symbol(_x,_y,_r,_r)
207 , filled(_e)
208 {}
209
210 void
211 Diamond::draw(Driver *gr) {
212 gr -> diamond(cx(),cy(),bb.max.x-cx(),filled) ;
213 }
214
215 /*
216 // ____ _
217 // / ___|| |_ __ _ _ __
218 // \___ \| __/ _` | '__|
219 // ___) | || (_| | |
220 // |____/ \__\__,_|_|
221 */
222
223 Star::Star( valueType _x,
224 valueType _y,
225 valueType _r,
226 bool _e )
227 : Symbol(_x,_y,_r,_r)
228 , filled(_e)
229 {}
230
231 void
232 Star::draw(Driver *gr) {
233 gr -> star(cx(),cy(),bb.max.x-cx(),filled) ;
234 }
235
236 /*
237 // ____ _
238 // | _ \| |_ _ ___
239 // | |_) | | | | / __|
240 // | __/| | |_| \__ \
241 // |_| |_|\__,_|___/
242 */
243
244 Plus::Plus( valueType x, valueType y, valueType r )
245 : Symbol(x,y,r,r)
246 {}
247
248 void
249 Plus::draw(Driver *gr) {
250 gr -> plus(cx(),cy(),bb.max.x-cx()) ;
251 }
252
253 /*
254 // ____
255 // / ___|_ __ ___ ___ ___
256 // | | | '__/ _ \/ __/ __|
257 // | |___| | | (_) \__ \__ \
258 // \____|_| \___/|___/___/
259 */
260
261 Cross::Cross( valueType x, valueType y, valueType r )
262 : Symbol(x,y,r,r)
263 {}
264
265 void
266 Cross::draw(Driver *gr) {
267 gr -> cross(cx(),cy(),bb.max.x-cx()) ;
268 }
269
270 /*
271 // ____ _ ____
272 // | _ \| |_ _ ___ / ___|_ __ ___ ___ ___
273 // | |_) | | | | / __| | | '__/ _ \/ __/ __|
274 // | __/| | |_| \__ \ |___| | | (_) \__ \__ \
275 // |_| |_|\__,_|___/\____|_| \___/|___/___/
276 */
277
278 PlusCross::PlusCross( valueType x, valueType y, valueType r )
279 : Symbol(x,y,r,r)
280 {}
281
282 void
283 PlusCross::draw(Driver *gr) {
284 gr -> plus(cx(),cy(),bb.max.x-cx()) ;
285 gr -> cross(cx(),cy(),bb.max.x-cx()) ;
286 }
287
288 /*
289 // _
290 // / \ _ __ _ __ _____ __
291 // / _ \ | '__| '__/ _ \ \ /\ / /
292 // / ___ \| | | | | (_) \ V V /
293 // /_/ \_\_| |_| \___/ \_/\_/
294 */
295
296 Arrow::Arrow( valueType _x,
297 valueType _y,
298 valueType _dx,
299 valueType _dy,
300 ArrowType at )
301 : x(_x)
302 , y(_y)
303 , dx(_dx)
304 , dy(_dy)
305 , artype(at)
306 , Gr::Object(_x+0.5*_dx, _y+0.5*_dy, 0.5*(_dx>0?_dx:-_dx), 0.5*(_dy>0?_dy:-_dy))
307 {}
308
309 void
310 Arrow::draw(Driver *gr) {
311 gr->arrow(x,y,dx,dy,artype) ;
312 }
313
314 /*
315 // _____ _
316 // |_ _|____ _| |_
317 // | |/ _ \ \/ / __|
318 // | | __/> <| |_
319 // |_|\___/_/\_\\__|
320 */
321
322 Text::Text( valueType x,
323 valueType y,
324 string const & _str,
325 FontType _font,
326 FontFace _face,
327 indexType _size,
328 FontAlign _align,
329 valueType _angle )
330 : font(_font)
331 , face(_face)
332 , size(_size)
333 , align(_align)
334 , angle(_angle)
335 {
336 setText(_str) ;
337 Gr::Object::setbb(x,y,x,y) ;
338 }
339
340 void
341 Text::draw(Driver *gr) {
342 gr -> setFont(font,face,size) ;
343 gr -> drawText(bb.min.x,bb.min.y,str.c_str(),align,angle) ;
344 }
345}
Declaration of Gr::Graph
class
File GrGraph.hh
:open:
1#ifndef GR_GRAPH_H
2#define GR_GRAPH_H
3
4#include "GrObject.hh"
5#include <list>
6#include <vector>
7
8namespace Gr {
9
10 using namespace std ;
11
12 typedef struct { valueType xvalue, yvalue ; } Point2D ;
13
14 typedef struct {
15 string name ;
16 list<Point2D> pnts ;
17 RgbGolor color ;
18 Symbol * symbol ;
19 valueType width ;
20 indexType lineStyle ;
21 } GraphItem ;
22
23 typedef struct {
24 FontType font ;
25 FontFace face ;
26 indexType size ;
27 indexType position ;
28 } Legend ;
29
30 class Graph : public Object {
31 bool drawAxes, drawGrid ;
32
33 Text *Title, *subTitle, *xLabel, *yLabel ;
34 Legend legend ;
35
36 valueType title_space, subtitle_space, label_space, item_sep ;
37
38 Bbox gbb, gc ;
39 GrXY step ;
40 string fmtx, fmty ;
41
42 vector<GraphItem> items ;
43
44 bool xlog, ylog ;
45 GrXY tras, scale ;
46 valueType X(valueType x) { return (x+tras.x)*scale.x ; }
47 valueType Y(valueType y) { return (y+tras.y)*scale.y ; }
48
49 public:
50
51 Graph(valueType x, valueType y, valueType dx, valueType dy) ;
52 virtual ~Graph() ;
53
54 void setTitle ( string const & s ) ;
55 void setSubTitle ( string const & s ) ;
56 void setXlabel ( string const & s ) ;
57 void setYlabel ( string const & s ) ;
58
59 void xRange(valueType _xmin, valueType _xmax) ;
60 void yRange(valueType _ymin, valueType _ymax) ;
61
62 void setXstep(valueType _xstep) { step.x = _xstep ; }
63 void setYstep(valueType _ystep) { step.y = _ystep ; }
64
65 void setFormatX(string const & s) { fmtx = s ; }
66 void setFormatY(string const & s) { fmty = s ; }
67
68 void setAxesLogarithmic(bool _xlog, bool _ylog) { xlog = _xlog ; ylog = _ylog ; }
69 void setAxesVisible(bool _axes) { drawAxes = _axes ; }
70 void setGridVisible(bool _grid) { drawGrid = _grid ; }
71
72 void setLegendPosition(indexType pos) { legend.position = pos ; } ;
73
74 void newCurve( string const & name,
75 Symbol * sy,
76 valueType w,
77 indexType st,
78 valueType r,
79 valueType g,
80 valueType b ) ;
81
82 void addPoint(valueType x, valueType y) ;
83 void addToCurve(indexType i, valueType x, valueType y) ;
84
85 void drawTics(Driver *gr) ;
86 void drawCurves(Driver *gr) ;
87 void drawLegend(Driver *gr) ;
88
89 virtual void draw(Driver *gr) ;
90 } ;
91}
92
93# endif
Definition of Gr::Graph
class
File GrGraph.cc
:open:
1#include <cmath>
2#include <iostream>
3#include "GrGraph.hh"
4
5namespace Gr {
6
7 using namespace std ;
8
9 indexType TITLE_SIZE = 18 ;
10 indexType SUBTITLE_SIZE = 14 ;
11 indexType LABEL_SIZE = 12 ;
12
13 indexType LEGEND_SIZE = 12 ;
14 FontType LEGEN_FONT = GR_HELVETICA ;
15 FontFace LEGEND_FACE = GR_NORMAL ;
16
17 indexType TICS_LEN = 3 ;
18 indexType ITEM_SEP = 3 ;
19
20 valueType LINE_WIDTH = 0.6 ;
21 indexType LINE_STYLE = 0 ;
22
23 Graph::Graph(valueType x, valueType y, valueType x1, valueType y1)
24 : Title(NULL)
25 , subTitle(NULL)
26 , xLabel(NULL)
27 , yLabel(NULL)
28 , xlog(false)
29 , ylog(false)
30 , drawAxes(false)
31 , drawGrid(false)
32 {
33 setbb(x,y,x1,y1) ;
34 title_space = TITLE_SIZE+4 ;
35 subtitle_space = SUBTITLE_SIZE+4 ;
36 label_space = 2*LABEL_SIZE+4 ;
37 item_sep = ITEM_SEP ;
38 legend.size = LEGEND_SIZE ;
39 legend.font = LEGEN_FONT ;
40 legend.face = LEGEND_FACE ;
41 legend.position = 0 ;
42
43 gc.min.x = gbb.min.x = bb.min.x+label_space ;
44 gc.min.y = gbb.min.y = bb.min.y+label_space ;
45 gc.max.x = gbb.max.x = bb.max.x-label_space ;
46 gc.max.y = gbb.max.y = bb.max.y-title_space-subtitle_space ;
47
48 tras.x = tras.y = 0 ;
49 scale.x = scale.y = 1 ;
50 step.x = step.y = .2 ;
51 fmtx = fmty = "%.2lg" ;
52 } ;
53
54 Graph::~Graph() {
55 if ( Title != NULL ) delete Title ;
56 if ( subTitle != NULL ) delete subTitle ;
57 if ( xLabel != NULL ) delete xLabel ;
58 if ( yLabel != NULL ) delete yLabel ;
59 } ;
60
61 void
62 Graph::setTitle( string const & s ) {
63 if ( Title == NULL ) {
64 Title = new Text(cx(),
65 bb.max.y-title_space/2,
66 s,
67 GR_HELVETICA,
68 GR_BOLD,
69 TITLE_SIZE,
70 GR_ALIGN_CENTER) ;
71 } else {
72 Title -> setText(s) ;
73 }
74 } ;
75
76 void
77 Graph::setSubTitle( string const & s ) {
78 if ( subTitle == NULL ) {
79 subTitle = new Text(cx(),
80 bb.max.y-title_space-subtitle_space/2,
81 s,
82 GR_HELVETICA,
83 GR_NORMAL,
84 SUBTITLE_SIZE,
85 GR_ALIGN_CENTER) ;
86 } else {
87 subTitle->setText(s) ;
88 }
89 }
90
91 void
92 Graph::setXlabel( string const & s ) {
93 if ( xLabel == NULL ) {
94 xLabel = new Text( cx(),
95 bb.min.y+LABEL_SIZE/2+1,
96 s,
97 GR_HELVETICA,
98 GR_NORMAL,
99 LABEL_SIZE,
100 GR_ALIGN_CENTER ) ;
101 } else {
102 xLabel -> setText(s) ;
103 }
104 }
105
106 void
107 Graph::setYlabel( string const & s ) {
108 if ( yLabel == NULL ) {
109 yLabel = new Text( bb.min.x+LABEL_SIZE/2+1,
110 cy(),
111 s,
112 GR_HELVETICA,
113 GR_NORMAL,
114 LABEL_SIZE,
115 GR_ALIGN_CENTER,90 ) ;
116 } else {
117 yLabel -> setText(s) ;
118 }
119 }
120
121 void
122 Graph::xRange( valueType _xmin, valueType _xmax ) {
123 gc.min.x = _xmin ;
124 gc.max.x = _xmax ;
125 scale.x = (gbb.max.x-gbb.min.x)/(_xmax-_xmin) ;
126 tras.x = - _xmin + gbb.min.x/scale.x ;
127 }
128
129 void
130 Graph::yRange( valueType _ymin, valueType _ymax ) {
131 gc.min.y = _ymin ;
132 gc.max.y = _ymax ;
133 scale.y = (gbb.max.y-gbb.min.y)/(_ymax-_ymin) ;
134 tras.y = - _ymin + gbb.min.y/scale.y ;
135 }
136
137 void
138 Graph::newCurve( string const & n,
139 Symbol * sy,
140 valueType w,
141 indexType st,
142 valueType r,
143 valueType g,
144 valueType b ) {
145 GraphItem bf_item ;
146
147 bf_item.name = n ;
148 bf_item.color = RgbGolor(r,g,b) ;
149 bf_item.symbol = sy ;
150 bf_item.width = w ;
151 bf_item.lineStyle = st ;
152
153 items.push_back(bf_item) ;
154 }
155
156 void
157 Graph::addToCurve( indexType i, valueType x, valueType y ) {
158 Point2D bf ;
159 bf.xvalue = x ;
160 bf.yvalue = y ;
161 items[i-1].pnts.push_back(bf) ;
162 }
163
164 void
165 Graph::addPoint( valueType x, valueType y ) {
166 addToCurve(items.size(),x,y) ;
167 }
168
169 void
170 Graph::drawTics( Driver *gr ) {
171 gr -> black() ;
172 if ( drawAxes ) {
173 gr->line(gbb.min.x,Y(0),gbb.max.x,Y(0)) ;
174 gr->line(X(0),gbb.min.y,X(0),gbb.max.y) ;
175 }
176
177 string str ;
178
179 if ( step.x > 0 ) {
180 valueType ymi, yma ;
181 if ( drawGrid ) {
182 ymi = gbb.min.y ;
183 yma = gbb.max.y ;
184 } else {
185 ymi = gbb.min.y-TICS_LEN ;
186 yma = gbb.min.y ;
187 }
188 indexType is = gc.min.x/step.x - 0.1,
189 ie = gc.max.x/step.x + 0.1 ;
190 for ( int i = is ; i <= ie ; i++ ) {
191 char msg[1000] ;
192 valueType xx = i*step.x ;
193 sprintf(msg,fmtx.c_str(),xx) ;
194 xx = X(xx) ;
195 gr -> line(xx,ymi,xx,yma) ;
196 gr -> drawText(xx,ymi-0.6*LABEL_SIZE,msg,GR_ALIGN_CENTER,0) ;
197 }
198 }
199
200 if ( step.y > 0 ) {
201 valueType xmi, xma ;
202 if ( drawGrid ) {
203 xmi = gbb.min.x ;
204 xma = gbb.max.x ;
205 } else {
206 xmi = gbb.min.x-TICS_LEN ;
207 xma = gbb.min.x ;
208 }
209 indexType js = gc.min.y/step.y - 0.1,
210 je = gc.max.y/step.y + 0.1 ;
211 for ( int j = js ; j <= je ; j++ ) {
212 valueType yy = j*step.y ;
213 char msg[1000];
214 sprintf( msg, fmty.c_str(),yy) ;
215 yy = Y(yy) ;
216 gr -> line(xmi,yy,xma,yy) ;
217 gr -> drawText(xmi-0.6*LABEL_SIZE,yy,msg,GR_ALIGN_CENTER,90) ;
218 }
219 }
220 }
221
222 void
223 Graph::drawCurves( Driver *gr ) {
224
225 gr -> clip(gbb.min.x,gbb.min.y,gbb.max.x,gbb.max.y) ;
226
227 for ( vector<GraphItem>::iterator i = items . begin() ;
228 i != items . end() ;
229 ++i ) {
230
231 Symbol * s = i -> symbol ;
232
233 if ( i -> pnts.size() == 0 ) break ;
234
235 gr -> rgbColor ( i -> color ) ;
236 gr -> setLineWidth ( i -> width ) ;
237 gr -> setLineStyle ( i -> lineStyle ) ;
238
239 list<Point2D>::iterator p = i -> pnts . begin() ;
240 valueType ox = X(p->xvalue) ;
241 valueType oy = Y(p->yvalue) ;
242 for ( ++p ; p != i -> pnts . end() ; ++p ) {
243 valueType nx = X(p->xvalue) ;
244 valueType ny = Y(p->yvalue) ;
245 gr -> line(ox,oy,nx,ny) ;
246 ox = nx ;
247 oy = ny ;
248 }
249
250 gr->setLineWidth(LINE_WIDTH) ;
251 gr->setLineStyle(LINE_STYLE) ;
252 for ( p = i -> pnts . begin() ; p != i->pnts . end() ; ++p ) {
253 s -> move(X(p->xvalue),Y(p->yvalue)) ;
254 s -> draw(gr) ;
255 }
256 }
257 }
258
259 void
260 Graph::drawLegend( Driver *gr ) {
261
262 if ( legend.position < 1 || items.size() == 0 ) return ;
263
264 gr -> setFont(legend.font, legend.face, legend.size) ;
265
266 vector<GraphItem>::const_iterator i ;
267
268 valueType msx=0, msy=0 ;
269 for ( i = items . begin() ; i != items . end() ; ++i ) {
270 Symbol *s = i -> symbol ;
271 if ( s->wx() > msx ) msx = s->wx() ;
272 if ( s->wy() > msy ) msy = s->wy() ;
273 }
274
275 // 1 2 3
276 // 4 5 6
277 // 7 8 9
278 valueType xsy, y;
279 bool on_left = true ;
280 switch ( legend.position % 3 ) {
281 case 1:
282 xsy = gbb.min.x + msx + item_sep ;
283 on_left = false ;
284 break ;
285 case 2:
286 xsy = (gbb.min.x+gbb.max.x)/2 + msx + item_sep ;
287 break ;
288 default:
289 xsy = gbb.max.x - msx - item_sep ;
290 break ;
291 }
292
293 switch ( legend.position/3 ) {
294 case 1:
295 y = gbb.max.y+item_sep ;
296 break ;
297 case 2:
298 y = (gbb.min.y+gbb.max.y+items.size()*(msy+item_sep))/2 ;
299 break ;
300 default:
301 y = gbb.min.y+items.size()*(msy+item_sep)+item_sep ;
302 break ;
303 }
304
305 y -= msy/2 ;
306 for ( i = items . begin() ; i != items . end() ; ++i ) {
307
308 gr -> rgbColor ( i -> color ) ;
309 gr -> setLineWidth ( i -> width ) ;
310 gr -> setLineStyle ( i -> lineStyle ) ;
311
312 Symbol *s = i -> symbol ;
313
314 gr -> line(xsy-msx,y,xsy+msx,y) ;
315 gr -> setLineWidth(LINE_WIDTH) ;
316 gr -> setLineStyle(LINE_STYLE) ;
317
318 s -> move(xsy,y) ;
319 s -> draw(gr) ;
320
321 if ( on_left )
322 gr -> drawText(xsy-msx-item_sep,y,i->name,GR_ALIGN_LEFT,0) ;
323 else
324 gr -> drawText(xsy+msx+item_sep,y,i->name,GR_ALIGN_RIGHT,0) ;
325 y -= item_sep+msy ;
326 }
327 }
328
329 void
330 Graph::draw( Driver *gr ) {
331 if ( Title != NULL ) Title -> draw(gr) ;
332 if ( subTitle != NULL ) subTitle -> draw(gr) ;
333 if ( xLabel != NULL ) xLabel -> draw(gr) ;
334 if ( yLabel != NULL ) yLabel -> draw(gr) ;
335
336 gr->red() ;
337 gr->box(bb.min.x,bb.min.y,bb.max.x,bb.max.y,false) ;
338 gr->blue() ;
339 gr->box(gbb.min.x,gbb.min.y,gbb.max.x,gbb.max.y,false) ;
340
341 drawTics(gr) ;
342 drawCurves(gr) ;
343 drawLegend(gr) ;
344 }
345
346}
A driver test program
File main.cc
:open:
1#include <iostream>
2#include <cmath>
3
4#include "PsDriver.hh"
5#include "GrGraph.hh"
6
7Gr::Graph *G ;
8
9int
10main() {
11
12 G = new Gr::Graph(10,10,490,400) ;
13 G->setTitle("Titolo") ;
14 G->setSubTitle("Sotto Titolo") ;
15 G->setXlabel("X label") ;
16 G->setYlabel("Y label") ;
17
18 G->newCurve("PIPPO", new Gr::Diamond(0,0,5,true), .5,3,0,0,0) ;
19 G->newCurve("PLUTO", new Gr::Circle(0,0,5,false), 1,4,1,0,0) ;
20 G->newCurve("Paperino", new Gr::Square(0,0,5,false),1,5,1,0,0) ;
21
22 for ( int i=0 ; i <= 20 ; i++ ) {
23 Gr::valueType x = 2*i/20.0-1 ;
24 G->addToCurve(1,x,x) ;
25 G->addToCurve(2,x,x*x) ;
26 G->addToCurve(3,x,x*x*x) ;
27 }
28
29 G->setLegendPosition(7) ;
30 G->xRange(-1,1) ;
31 G->yRange(-1,1) ;
32 G->setXstep(0.3) ;
33 G->setYstep(0.3) ;
34 G->setAxesVisible(false) ;
35
36 //
37
38 Gr::PsDriver * ps = new Gr::PsDriver("prova.ps",500,500,false,false) ;
39 ps->window(0,500,0,500) ;
40 ps->blue() ;
41 G->draw(ps) ;
42 delete ps ;
43
44}
The lesson in a zip file
The zip file lesson5.zip