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
32namespace geometric {
33
34template <class numeric_type>
36{
37public:
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
89
92
95
99
100private:
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
127template <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
135template <class numeric_type>
137
138template <class numeric_type>
140 (const rectangle<numeric_type> &to_set, origin_vertex v)
141{ _system_1 = to_set; _vert_1 = v; }
142
143template <class numeric_type>
145 (const rectangle<numeric_type> &to_set, origin_vertex v)
146{ _system_2 = to_set; _vert_2 = v; }
147
148template <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
153template <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
158template <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
166template <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
174template <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
182template <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
190template <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
217template <class numeric_type>
218rectangle<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
254template <class numeric_type>
255point<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
265template <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
278template <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
rectangle< numeric_type > system_2() const
Definition warper.h:78
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
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_1() const
Definition warper.h:77
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