feisty meow concerns codebase  2.140
warper.h
Go to the documentation of this file.
1 #ifndef RECTANGLE_WARPER_CLASS
2 #define RECTANGLE_WARPER_CLASS
3 
4 /*****************************************************************************\
5 * *
6 * Name : rectangle_warper *
7 * Author : Chris Koeritz *
8 * *
9 *******************************************************************************
10 * Copyright (c) 1992-$now By Author. This program is free software; you can *
11 * redistribute it and/or modify it under the terms of the GNU General Public *
12 * License as published by the Free Software Foundation; either version 2 of *
13 * the License or (at your option) any later version. This is online at: *
14 * http://www.fsf.org/copyleft/gpl.html *
15 * Please send any updates to: fred@gruntose.com *
16 \*****************************************************************************/
17 
19 
28 #include "rectangle.h"
29 
30 #include <basis/astring.h>
31 
32 namespace geometric {
33 
34 template <class numeric_type>
36 {
37 public:
39 
46 
49  origin_vertex system_1_origin = BOTTOM_LEFT,
50  origin_vertex system_2_origin = BOTTOM_LEFT);
52 
57 
58  point<numeric_type> to_system_1(const point<numeric_type> &in_system_2) const;
60 
64  point<numeric_type> to_system_2(const point<numeric_type> &in_system_1) const;
66 
71  (const rectangle<numeric_type> &in_system_2) const;
74  (const rectangle<numeric_type> &in_system_1) const;
76 
77  rectangle<numeric_type> system_1() const { return _system_1; }
78  rectangle<numeric_type> system_2() const { return _system_2; }
79  origin_vertex origin_1() const { return _vert_1; }
80  origin_vertex origin_2() const { return _vert_2; }
81 
82  void system_1(const rectangle<numeric_type> &to_set,
83  origin_vertex origin_corner = BOTTOM_LEFT);
84  void system_2(const rectangle<numeric_type> &to_set,
85  origin_vertex origin_corner = BOTTOM_LEFT);
86 
87  basis::astring text_form() const;
89 
92 
95 
96  void separate_vertical(origin_vertex v, vertical_component &to_set) const;
99 
100 private:
101  rectangle<numeric_type> _system_1;
102  rectangle<numeric_type> _system_2;
103  origin_vertex _vert_1;
104  origin_vertex _vert_2;
105 
106  point<numeric_type> scale_point(const rectangle<numeric_type> &source,
107  const rectangle<numeric_type> &target,
109  const point<numeric_type> &old) const;
110  rectangle<numeric_type> scale_rectangle(const rectangle<numeric_type> &source,
111  const rectangle<numeric_type> &target,
113  const rectangle<numeric_type> &old) const;
114  rectangle<numeric_type> flip_accordingly
115  (const rectangle<numeric_type> &to_flip, origin_vertex to_flip_origin,
116  origin_vertex target_origin) const;
118 
121 };
122 
124 
125 // implementations for longer methods below...
126 
127 template <class numeric_type>
129  (const rectangle<numeric_type> &system_1,
130  const rectangle<numeric_type> &system_2,
132 : _system_1(system_1), _system_2(system_2), _vert_1(v1), _vert_2(v2)
133 {}
134 
135 template <class numeric_type>
137 
138 template <class numeric_type>
140  (const rectangle<numeric_type> &to_set, origin_vertex v)
141 { _system_1 = to_set; _vert_1 = v; }
142 
143 template <class numeric_type>
145  (const rectangle<numeric_type> &to_set, origin_vertex v)
146 { _system_2 = to_set; _vert_2 = v; }
147 
148 template <class numeric_type>
150  (const point<numeric_type> &in_system_2) const
151 { return scale_point(_system_2, _system_1, _vert_2, _vert_1, in_system_2); }
152 
153 template <class numeric_type>
155  (const point<numeric_type> &in_system_1) const
156 { return scale_point(_system_1, _system_2, _vert_1, _vert_2, in_system_1); }
157 
158 template <class numeric_type>
160  (const rectangle<numeric_type> &in_system_2) const
161 {
162  return scale_rectangle(_system_2, _system_1, _vert_2, _vert_1,
163  in_system_2);
164 }
165 
166 template <class numeric_type>
168  (const rectangle<numeric_type> &in_system_1) const
169 {
170  return scale_rectangle(_system_1, _system_2, _vert_1, _vert_2,
171  in_system_1);
172 }
173 
174 template <class numeric_type>
176  (origin_vertex v, vertical_component &to_set) const
177 {
178  if ( (v == BOTTOM_LEFT) || (v == BOTTOM_RIGHT) ) to_set = RW_BOTTOM;
179  to_set = RW_TOP;
180 }
181 
182 template <class numeric_type>
184  (origin_vertex v, horizontal_component &to_set) const
185 {
186  if ( (v == BOTTOM_LEFT) || (v == TOP_LEFT) ) to_set = RW_LEFT;
187  to_set = RW_RIGHT;
188 }
189 
190 template <class numeric_type>
192  (const rectangle<numeric_type> &to_flip, origin_vertex flipo,
193  origin_vertex targo) const
194 {
195 //LOG(basis::astring("flipping ") + to_flip.text_form() + " from " + flipo.text_form() + " to " + targo.text_form());
196  if (flipo == targo) return to_flip;
197  numeric_type x1(to_flip.vertex_1().x());
198  numeric_type y1(to_flip.vertex_1().y());
199  numeric_type x2(to_flip.vertex_2().x());
200  numeric_type y2(to_flip.vertex_2().y());
201  horizontal_component horiz1;
202  separate_horizontal(flipo, horiz1);
203  horizontal_component horiz2;
204  separate_horizontal(targo, horiz2);
205  bool flip_x = bool(horiz1 != horiz2);
206  vertical_component vert1;
207  separate_vertical(flipo, vert1);
208  vertical_component vert2;
209  separate_vertical(targo, vert2);
210  bool flip_y = bool(vert1 != vert2);
211  if (flip_x) basis::swap_values(x1, x2);
212  if (flip_y) basis::swap_values(y1, y2);
213 //LOG(basis::astring("it becomes ") + rectangle<numeric_type>(x1, y1, x2, y2).text_form());
214  return rectangle<numeric_type>(x1, y1, x2, y2);
215 }
216 
217 template <class numeric_type>
218 rectangle<numeric_type> rectangle_warper<numeric_type>::scale_rectangle
219  (const rectangle<numeric_type> &source,
220  const rectangle<numeric_type> &target, origin_vertex source_origin,
221  origin_vertex target_origin, const rectangle<numeric_type> &old) const
222 {
223  rectangle<numeric_type> s = rectangle<numeric_type>
224  (flip_accordingly(source, source_origin, BOTTOM_LEFT));
225  numeric_type width_source = s.vertex_2().x() - s.vertex_1().x();
226  numeric_type height_source = s.vertex_2().y() - s.vertex_1().y();
227  if ( !width_source || !height_source ) {
228 // cerr << "degenerate rectangle in rectangle_warper::scaler: " << s
229 // << endl << flush;
230  return old;
231  }
232  rectangle<numeric_type> t(flip_accordingly(target, target_origin, BOTTOM_LEFT));
233  numeric_type width_target = t.vertex_2().x() - t.vertex_1().x();
234  numeric_type height_target = t.vertex_2().y() - t.vertex_1().y();
235  numeric_type x_scale = width_target / width_source;
236  numeric_type y_scale = height_target / height_source;
237 
238 //LOG(basis::astring("scaler: source ") + source.text_form() + " with vert " + source_origin.text_form() + " becomes " + s + " target " + target + " with vert " + target_origin + " becomes " + t + ".");
239 
240  rectangle<numeric_type> o(flip_accordingly(old, source_origin, BOTTOM_LEFT));
241 
242  rectangle<numeric_type> to_return = flip_accordingly(rectangle<numeric_type>
243  ((o.vertex_1().x() - s.vertex_1().x()) * x_scale + t.vertex_1().x(),
244  (o.vertex_1().y() - s.vertex_1().y()) * y_scale + t.vertex_1().y(),
245  (o.vertex_2().x() - s.vertex_1().x()) * x_scale + t.vertex_1().x(),
246  (o.vertex_2().y() - s.vertex_1().y()) * y_scale + t.vertex_1().y()),
247  BOTTOM_LEFT, target_origin);
248 
249 // LOG(basis::astring("old ") + old.text_form() + " with source vert becomes " + o.text_form() + " and then is moved into " + to_return.text_form());
250 
251  return to_return;
252 }
253 
254 template <class numeric_type>
255 point<numeric_type> rectangle_warper<numeric_type>::scale_point
256  (const rectangle<numeric_type> &source, const rectangle<numeric_type> &target,
257  origin_vertex source_origin, origin_vertex target_origin,
258  const point<numeric_type> &old) const
259 {
260  // gross but simple.
261  return scale_rectangle(source, target, source_origin, target_origin,
262  rectangle<numeric_type>(old, old)).vertex_1();
263 }
264 
265 template <class numeric_type>
267 {
268  basis::astring name("unknown");
269  switch (v) {
270  case BOTTOM_LEFT: name = "bottom-left"; break;
271  case BOTTOM_RIGHT: name = "bottom-right"; break;
272  case TOP_LEFT: name = "top-left"; break;
273  case TOP_RIGHT: name = "top-right"; break;
274  }
275  return name;
276 }
277 
278 template <class numeric_type>
280 {
281  return basis::astring("<warps from: ") + _system_1.text_form()
282  + basis::astring(" with vertex at ") + vertex_name(_vert_1)
283  + basis::astring(" into ") + _system_2.text_form()
284  + basis::astring(" with vertex at ") + vertex_name(_vert_2)
285  + basis::astring(">");
286 }
287 
288 } // namespace.
289 
290 #endif
291 
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
virtual void text_form(base_string &state_fill) const
Provides a text view of all the important info owned by this object.
Definition: astring.cpp:130
Represents a geometric point.
Definition: point.h:37
basis::astring vertex_name(origin_vertex v) const
Prints out the name of the vertex location.
Definition: warper.h:266
rectangle_warper(const rectangle< numeric_type > &system_1, const rectangle< numeric_type > &system_2, origin_vertex system_1_origin=BOTTOM_LEFT, origin_vertex system_2_origin=BOTTOM_LEFT)
constructs a warper given the two reference systems.
Definition: warper.h:129
origin_vertex origin_1() const
Definition: warper.h:79
rectangle< numeric_type > system_1() const
Definition: warper.h:77
origin_vertex origin_2() const
Definition: warper.h:80
void separate_horizontal(origin_vertex v, horizontal_component &to_set) const
separates out a component of the placement of the vertex.
Definition: warper.h:184
point< numeric_type > to_system_1(const point< numeric_type > &in_system_2) const
Converts from the second system into the first.
Definition: warper.h:150
rectangle< numeric_type > system_2() const
Definition: warper.h:78
basis::astring text_form() const
Prints out the two systems held in the rectangle_warper.
Definition: warper.h:279
origin_vertex
describes where a rectangle's origin is located on the rectangle.
Definition: warper.h:45
void separate_vertical(origin_vertex v, vertical_component &to_set) const
Definition: warper.h:176
point< numeric_type > to_system_2(const point< numeric_type > &in_system_1) const
Converts from the first system into the second.
Definition: warper.h:155
Represents a geometric rectangle.
Definition: rectangle.h:28
point< numeric_type > vertex_1() const
Definition: rectangle.h:148
point< numeric_type > vertex_2() const
Definition: rectangle.h:152
void swap_values(type &a, type &b)
Exchanges the values held by "a" & "b".
Definition: functions.h:103
Contains all of our objects for geometry and avoids name clashes.
Definition: angle.h:25