DGtal  0.9.2
Path.cpp
1 /* -*- mode: c++ -*- */
9 /*
10  * \@copyright This File is part of the Board library which is
11  * licensed under the terms of the GNU Lesser General Public Licence.
12  * See the LICENCE file for further details.
13  */
14 
15 #include "Board/Path.h"
16 #include "Board/Transforms.h"
17 
18 
19 namespace LibBoard {
20 
21 Path &
23 {
24  _points.pop_back();
25  return *this;
26 }
27 
28 Path &
29 Path::operator<<( const Point & p )
30 {
31  _points.push_back( p );
32  return *this;
33 }
34 
35 Point
36 Path::center() const {
37  Rect bbox = boundingBox();
38  return Point( bbox.left + bbox.width/2.0,
39  bbox.top - bbox.height/2.0 );
40 }
41 
42 Path &
43 Path::rotate( double angle, const Point & rotCenter )
44 {
45  std::vector<Point>::iterator i = _points.begin();
46  std::vector<Point>::iterator end = _points.end();
47  while ( i != end ) {
48  i->rotate( angle, rotCenter );
49  ++i;
50  }
51  return *this;
52 }
53 
54 Path
55 Path::rotated( double angle, const Point & rotCenter ) const
56 {
57  Path res(*this);
58  std::vector<Point>::iterator i = res._points.begin();
59  std::vector<Point>::iterator end = res._points.end();
60  while ( i != end ) {
61  i->rotate( angle, rotCenter );
62  ++i;
63  }
64  return res;
65 }
66 
67 Path &
68 Path::rotate( double angle )
69 {
70  return Path::rotate( angle, center() );
71 }
72 
73 Path
74 Path::rotated( double angle ) const
75 {
76  Path res(*this);
77  return static_cast<Path&>( res.rotate( angle, center() ) );
78 }
79 
80 Path &
81 Path::translate( double dx, double dy )
82 {
83  std::vector<Point>::iterator i = _points.begin();
84  std::vector<Point>::iterator end = _points.end();
85  Point delta( dx, dy );
86  while ( i != end ) {
87  (*i) += delta;
88  ++i;
89  }
90  return *this;
91 }
92 
93 Path
94 Path::translated( double dx, double dy ) const
95 {
96  Path res(*this);
97  std::vector<Point>::iterator i = res._points.begin();
98  std::vector<Point>::iterator end = res._points.end();
99  Point delta( dx, dy );
100  while ( i != end ) {
101  (*i) += delta;
102  ++i;
103  }
104  return res;
105 }
106 
107 Path &
108 Path::scale( double sx, double sy )
109 {
110  Point c = center();
111  translate( -c.x, -c.y );
112  std::vector<Point>::iterator i = _points.begin();
113  std::vector<Point>::iterator end = _points.end();
114  while ( i != end ) {
115  i->x *= sx;
116  i->y *= sy;
117  ++i;
118  }
119  Point delta = c - center();
120  translate( delta.x, delta.y );
121  return *this;
122 }
123 
124 Path &
125 Path::scale( double s )
126 {
127  return Path::scale( s, s );
128 }
129 
130 Path
131 Path::scaled( double sx, double sy ) const
132 {
133  return Path(*this).scale( sx, sy );
134 }
135 
136 Path
137 Path::scaled( double s) const
138 {
139  return Path(*this).scale( s, s );
140 }
141 
142 void
143 Path::scaleAll( double s )
144 {
145  std::vector<Point>::iterator it = _points.begin();
146  std::vector<Point>::iterator end = _points.end();
147  while ( it != end ) {
148  (*it) *= s;
149  ++it;
150  }
151 }
152 
153 void
154 Path::flushPostscript( std::ostream & stream,
155  const TransformEPS & transform ) const
156 {
157  if ( _points.empty() )
158  return;
159  std::vector<Point>::const_iterator i = _points.begin();
160  std::vector<Point>::const_iterator end = _points.end();
161 
162  stream << transform.mapX( i->x ) << " " << transform.mapY( i->y ) << " m";
163  ++i;
164  while ( i != end ) {
165  stream << " " << transform.mapX( i->x ) << " " << transform.mapY( i->y ) << " l";
166  ++i;
167  }
168  if ( _closed ) stream << " cp";
169  stream << " ";
170 }
171 
172 void
173 Path::flushFIG( std::ostream & stream,
174  const TransformFIG & transform ) const
175 {
176  if ( _points.empty() )
177  return;
178 
179  std::vector<Point>::const_iterator i = _points.begin();
180  std::vector<Point>::const_iterator end = _points.end();
181  while ( i != end ) {
182  stream << " " << static_cast<int>( transform.mapX( i->x ) )
183  << " " << static_cast<int>( transform.mapY( i->y ) );
184  ++i;
185  }
186  if ( _closed ) {
187  stream << " " << static_cast<int>( transform.mapX( _points.begin()->x ) )
188  << " " << static_cast<int>( transform.mapY( _points.begin()->y ) );
189  }
190 }
191 
192 void
193 Path::flushSVGCommands( std::ostream & stream,
194  const TransformSVG & transform ) const
195 {
196  if ( _points.empty() )
197  return;
198  std::vector<Point>::const_iterator i = _points.begin();
199  std::vector<Point>::const_iterator end = _points.end();
200  int count = 0;
201 
202  stream << "M " << transform.mapX( i->x ) << " " << transform.mapY( i->y );
203  ++i;
204  while ( i != end ) {
205  stream << " L " << transform.mapX( i->x ) << " " << transform.mapY( i->y );
206  ++i;
207  count = ( count + 1 ) % 6;
208  if ( !count ) stream << "\n ";
209  }
210  if ( _closed )
211  stream << " Z" << std::endl;
212 }
213 
214 void
215 Path::flushSVGPoints( std::ostream & stream,
216  const TransformSVG & transform ) const
217 {
218  if ( _points.empty() )
219  return;
220  std::vector<Point>::const_iterator i = _points.begin();
221  std::vector<Point>::const_iterator end = _points.end();
222  int count = 0;
223  stream << transform.mapX( i->x ) << "," << transform.mapY( i->y );
224  ++i;
225  while ( i != end ) {
226  stream << " " << transform.mapX( i->x ) << "," << transform.mapY( i->y );
227  ++i;
228  count = ( count + 1 ) % 6;
229  if ( !count ) stream << "\n ";
230  }
231 }
232 
233 #ifdef WITH_CAIRO
234 void
236  const TransformCairo & transform ) const
237 {
238  if ( _points.empty() )
239  return;
240  std::vector<Point>::const_iterator i = _points.begin();
241  std::vector<Point>::const_iterator end = _points.end();
242  int count = 0;
243  cairo_move_to (cr, transform.mapX( i->x ), transform.mapY( i->y ));
244  ++i;
245  while ( i != end ) {
246  cairo_line_to (cr, transform.mapX( i->x ), transform.mapY( i->y ));
247  ++i;
248  count = ( count + 1 ) % 6;
249  //if ( !count ) stream << "\n ";
250  }
251 }
252 #endif
253 
254 void
255 Path::flushTikZPoints( std::ostream & stream,
256  const TransformTikZ & transform ) const
257 {
258  if ( _points.empty() )
259  return;
260  std::vector<Point>::const_iterator i = _points.begin();
261  std::vector<Point>::const_iterator end = _points.end();
262  stream << '(' << transform.mapX( i->x ) << "," << transform.mapY( i->y ) << ')';
263  ++i;
264  while ( i != end ) {
265  stream << " -- "
266  << '(' << transform.mapX( i->x ) << "," << transform.mapY( i->y ) << ')';
267  ++i;
268  }
269 }
270 
271 Rect
273 {
274  if ( _points.empty() )
275  return Rect( 0, 0, 0, 0 );
276  Rect rect;
277  std::vector< Point >::const_iterator i = _points.begin();
278  std::vector< Point >::const_iterator end = _points.end();
279  rect.top = i->y;
280  rect.left = i->x;
281  rect.width = 0.0;
282  rect.height = 0.0;
283  ++i;
284  while ( i != end ) {
285  if ( i->x < rect.left ) {
286  double dw = rect.left - i->x;
287  rect.left = i->x;
288  rect.width += dw;
289  } else if ( i->x > rect.left + rect.width ) {
290  rect.width = i->x - rect.left;
291  }
292  if ( i->y > rect.top ) {
293  double dh = i->y - rect.top;
294  rect.top = i->y;
295  rect.height += dh;
296  } else if ( i->y < rect.top - rect.height ) {
297  rect.height = rect.top - i->y;
298  }
299  ++i;
300  }
301  return rect;
302 }
303 
304 } // namespace LibBoard
Path & scale(double sx, double sy)
Definition: Path.cpp:108
void flushTikZPoints(std::ostream &stream, const TransformTikZ &transform) const
Definition: Path.cpp:255
Path & operator<<(const Point &p)
Definition: Path.cpp:29
void flushSVGCommands(std::ostream &stream, const TransformSVG &transform) const
Definition: Path.cpp:193
void flushSVGPoints(std::ostream &stream, const TransformSVG &transform) const
Definition: Path.cpp:215
Structure representing a scaling and translation suitable for an TikZ output.
Definition: Transforms.h:129
Rect boundingBox() const
Definition: Path.cpp:272
Path & translate(double dx, double dy)
Definition: Path.cpp:81
Structure representing a scaling and translation suitable for an Cairo output.
Definition: Transforms.h:112
Point center() const
Definition: Path.cpp:36
double top
Definition: Rect.h:29
A path, according to Postscript and SVG definition.
Definition: Path.h:43
Path scaled(double sx, double sy) const
Definition: Path.cpp:131
double left
Definition: Rect.h:28
Struct representing a 2D point.
Definition: Point.h:27
Path rotated(double angle, const Point &center) const
Definition: Path.cpp:55
Path & pop_back()
Definition: Path.cpp:22
Structure representing a scaling and translation suitable for an XFig output.
Definition: Transforms.h:73
std::vector< Point > _points
Definition: Path.h:226
double mapY(double y) const
Definition: Transforms.cpp:62
double x
Definition: Point.h:29
virtual double mapX(double x) const
Definition: Transforms.cpp:39
Path & rotate(double angle, const Point &center)
Definition: Path.cpp:43
double mapY(double y) const
Definition: Transforms.cpp:105
Structure representing a scaling and translation suitable for an SVG output.
Definition: Transforms.h:95
void scaleAll(double s)
Definition: Path.cpp:143
bool _closed
Definition: Path.h:227
double mapY(double y) const
Definition: Transforms.cpp:182
Path translated(double dx, double dy) const
Definition: Path.cpp:94
double mapY(double y) const
Definition: Transforms.cpp:234
double height
Definition: Rect.h:31
double y
Definition: Point.h:30
Structure representing a scaling and translation suitable for an EPS output.
Definition: Transforms.h:59
Struct representing a rectangle on the plane.
Definition: Rect.h:26
void flushPostscript(std::ostream &stream, const TransformEPS &transform) const
Definition: Path.cpp:154
void flushCairoPoints(cairo_t *cr, const TransformCairo &transform) const
Definition: Path.cpp:235
double width
Definition: Rect.h:30
void flushFIG(std::ostream &stream, const TransformFIG &transform) const
Definition: Path.cpp:173