warper.h

Go to the documentation of this file.
00001 #ifndef RECTANGLE_WARPER_CLASS
00002 #define RECTANGLE_WARPER_CLASS
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : rectangle_warper                                                  *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 1992-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
00016 \*****************************************************************************/
00017 
00019 
00028 #include "rectangle.h"
00029 
00030 #include <basis/astring.h>
00031 
00032 namespace geometric {
00033 
00034 template <class numeric_type>
00035 class rectangle_warper
00036 {
00037 public:
00039 
00045   enum origin_vertex { BOTTOM_LEFT, TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT };
00046 
00047   rectangle_warper(const rectangle<numeric_type> &system_1,
00048           const rectangle<numeric_type> &system_2,
00049           origin_vertex system_1_origin = BOTTOM_LEFT,
00050           origin_vertex system_2_origin = BOTTOM_LEFT);
00052 
00056   ~rectangle_warper();
00057 
00058   point<numeric_type> to_system_1(const point<numeric_type> &in_system_2) const;
00060 
00064   point<numeric_type> to_system_2(const point<numeric_type> &in_system_1) const;
00066 
00070   rectangle<numeric_type> to_system_1
00071           (const rectangle<numeric_type> &in_system_2) const;
00073   rectangle<numeric_type> to_system_2
00074           (const rectangle<numeric_type> &in_system_1) const;
00076 
00077   rectangle<numeric_type> system_1() const { return _system_1; }
00078   rectangle<numeric_type> system_2() const { return _system_2; }
00079   origin_vertex origin_1() const { return _vert_1; }
00080   origin_vertex origin_2() const { return _vert_2; }
00081 
00082   void system_1(const rectangle<numeric_type> &to_set,
00083           origin_vertex origin_corner = BOTTOM_LEFT);
00084   void system_2(const rectangle<numeric_type> &to_set,
00085           origin_vertex origin_corner = BOTTOM_LEFT);
00086 
00087   basis::astring text_form() const;
00089 
00090   basis::astring vertex_name(origin_vertex v) const;
00092 
00093   enum vertical_component { RW_BOTTOM, RW_TOP };
00094   enum horizontal_component { RW_LEFT, RW_RIGHT };
00095 
00096   void separate_vertical(origin_vertex v, vertical_component &to_set) const;
00097   void separate_horizontal(origin_vertex v, horizontal_component &to_set) const;
00099 
00100 private:
00101   rectangle<numeric_type> _system_1;
00102   rectangle<numeric_type> _system_2;
00103   origin_vertex _vert_1;
00104   origin_vertex _vert_2;
00105 
00106   point<numeric_type> scale_point(const rectangle<numeric_type> &source,
00107           const rectangle<numeric_type> &target,
00108           origin_vertex v1, origin_vertex v2,
00109           const point<numeric_type> &old) const;
00110   rectangle<numeric_type> scale_rectangle(const rectangle<numeric_type> &source,
00111           const rectangle<numeric_type> &target,
00112           origin_vertex v1, origin_vertex v2,
00113           const rectangle<numeric_type> &old) const;
00114   rectangle<numeric_type> flip_accordingly
00115           (const rectangle<numeric_type> &to_flip, origin_vertex to_flip_origin,
00116           origin_vertex target_origin) const;
00118 
00121 };
00122 
00124 
00125 // implementations for longer methods below...
00126 
00127 template <class numeric_type>
00128 rectangle_warper<numeric_type>::rectangle_warper
00129     (const rectangle<numeric_type> &system_1,
00130      const rectangle<numeric_type> &system_2,
00131      origin_vertex v1, origin_vertex v2)
00132 : _system_1(system_1), _system_2(system_2), _vert_1(v1), _vert_2(v2)
00133 {}
00134 
00135 template <class numeric_type>
00136 rectangle_warper<numeric_type>::~rectangle_warper() {}
00137 
00138 template <class numeric_type>
00139 void rectangle_warper<numeric_type>::system_1
00140     (const rectangle<numeric_type> &to_set, origin_vertex v)
00141 { _system_1 = to_set; _vert_1 = v; }
00142 
00143 template <class numeric_type>
00144 void rectangle_warper<numeric_type>::system_2
00145     (const rectangle<numeric_type> &to_set, origin_vertex v)
00146 { _system_2 = to_set; _vert_2 = v; }
00147 
00148 template <class numeric_type>
00149 point<numeric_type> rectangle_warper<numeric_type>::to_system_1
00150     (const point<numeric_type> &in_system_2) const
00151 { return scale_point(_system_2, _system_1, _vert_2, _vert_1, in_system_2); }
00152 
00153 template <class numeric_type>
00154 point<numeric_type> rectangle_warper<numeric_type>::to_system_2
00155     (const point<numeric_type> &in_system_1) const
00156 { return scale_point(_system_1, _system_2, _vert_1, _vert_2, in_system_1); }
00157 
00158 template <class numeric_type>
00159 rectangle<numeric_type> rectangle_warper<numeric_type>::to_system_1
00160     (const rectangle<numeric_type> &in_system_2) const
00161 { 
00162   return scale_rectangle(_system_2, _system_1, _vert_2, _vert_1, 
00163       in_system_2); 
00164 }
00165 
00166 template <class numeric_type>
00167 rectangle<numeric_type> rectangle_warper<numeric_type>::to_system_2
00168     (const rectangle<numeric_type> &in_system_1) const
00169 {
00170   return scale_rectangle(_system_1, _system_2, _vert_1, _vert_2,
00171       in_system_1); 
00172 }
00173 
00174 template <class numeric_type>
00175 void rectangle_warper<numeric_type>::separate_vertical
00176     (origin_vertex v, vertical_component &to_set) const
00177 {
00178   if ( (v == BOTTOM_LEFT) || (v == BOTTOM_RIGHT) ) to_set = RW_BOTTOM;
00179   to_set = RW_TOP;
00180 }
00181 
00182 template <class numeric_type>
00183 void rectangle_warper<numeric_type>::separate_horizontal
00184     (origin_vertex v, horizontal_component &to_set) const
00185 {
00186   if ( (v == BOTTOM_LEFT) || (v == TOP_LEFT) ) to_set = RW_LEFT;
00187   to_set = RW_RIGHT;
00188 }
00189 
00190 template <class numeric_type>
00191 rectangle<numeric_type> rectangle_warper<numeric_type>::flip_accordingly
00192     (const rectangle<numeric_type> &to_flip, origin_vertex flipo,
00193     origin_vertex targo) const
00194 {
00195 //LOG(basis::astring("flipping ") + to_flip.text_form() + " from " + flipo.text_form() + " to " + targo.text_form());
00196   if (flipo == targo) return to_flip;
00197   numeric_type x1(to_flip.vertex_1().x());
00198   numeric_type y1(to_flip.vertex_1().y());
00199   numeric_type x2(to_flip.vertex_2().x());
00200   numeric_type y2(to_flip.vertex_2().y());
00201   horizontal_component horiz1;
00202   separate_horizontal(flipo, horiz1);
00203   horizontal_component horiz2;
00204   separate_horizontal(targo, horiz2);
00205   bool flip_x = bool(horiz1 != horiz2);
00206   vertical_component vert1;
00207   separate_vertical(flipo, vert1);
00208   vertical_component vert2;
00209   separate_vertical(targo, vert2);
00210   bool flip_y = bool(vert1 != vert2);
00211   if (flip_x) swap_values(x1, x2);
00212   if (flip_y) swap_values(y1, y2);
00213 //LOG(basis::astring("it becomes ") + rectangle<numeric_type>(x1, y1, x2, y2).text_form());
00214   return rectangle<numeric_type>(x1, y1, x2, y2);
00215 }
00216 
00217 template <class numeric_type>
00218 rectangle<numeric_type> rectangle_warper<numeric_type>::scale_rectangle
00219     (const rectangle<numeric_type> &source,
00220     const rectangle<numeric_type> &target, origin_vertex source_origin,
00221     origin_vertex target_origin, const rectangle<numeric_type> &old) const
00222 {
00223   rectangle<numeric_type> s = rectangle<numeric_type>
00224       (flip_accordingly(source, source_origin, BOTTOM_LEFT));
00225   numeric_type width_source = s.vertex_2().x() - s.vertex_1().x();
00226   numeric_type height_source = s.vertex_2().y() - s.vertex_1().y();
00227   if ( !width_source || !height_source ) {
00228 //    cerr << "degenerate rectangle in rectangle_warper::scaler: " << s
00229 //      << endl << flush;
00230     return old;
00231   }
00232   rectangle<numeric_type> t(flip_accordingly(target, target_origin, BOTTOM_LEFT));
00233   numeric_type width_target = t.vertex_2().x() - t.vertex_1().x();
00234   numeric_type height_target = t.vertex_2().y() - t.vertex_1().y();
00235   numeric_type x_scale = width_target / width_source;
00236   numeric_type y_scale = height_target / height_source;
00237 
00238 //LOG(basis::astring("scaler: source ") + source.text_form() + " with vert " + source_origin.text_form() + " becomes " + s + " target " + target + " with vert " + target_origin + " becomes " + t + ".");
00239 
00240   rectangle<numeric_type> o(flip_accordingly(old, source_origin, BOTTOM_LEFT));
00241 
00242   rectangle<numeric_type> to_return = flip_accordingly(rectangle<numeric_type>
00243      ((o.vertex_1().x() - s.vertex_1().x()) * x_scale + t.vertex_1().x(),
00244       (o.vertex_1().y() - s.vertex_1().y()) * y_scale + t.vertex_1().y(),
00245       (o.vertex_2().x() - s.vertex_1().x()) * x_scale + t.vertex_1().x(),
00246       (o.vertex_2().y() - s.vertex_1().y()) * y_scale + t.vertex_1().y()),
00247      BOTTOM_LEFT, target_origin);
00248 
00249 //  LOG(basis::astring("old ") + old.text_form() + " with source vert becomes " + o.text_form() + " and then is moved into " + to_return.text_form());
00250 
00251   return to_return;
00252 }
00253 
00254 template <class numeric_type>
00255 point<numeric_type> rectangle_warper<numeric_type>::scale_point
00256   (const rectangle<numeric_type> &source, const rectangle<numeric_type> &target,
00257    origin_vertex source_origin, origin_vertex target_origin,
00258    const point<numeric_type> &old) const
00259 {
00260   // gross but simple.
00261   return scale_rectangle(source, target, source_origin, target_origin,
00262       rectangle<numeric_type>(old, old)).vertex_1();
00263 }
00264 
00265 template <class numeric_type>
00266 basis::astring rectangle_warper<numeric_type>::vertex_name(origin_vertex v) const
00267 {
00268   basis::astring name("unknown");
00269   switch (v) {
00270     case BOTTOM_LEFT: name = "bottom-left"; break;
00271     case BOTTOM_RIGHT: name = "bottom-right"; break;
00272     case TOP_LEFT: name = "top-left"; break;
00273     case TOP_RIGHT: name = "top-right"; break;
00274   }
00275   return name;
00276 }
00277 
00278 template <class numeric_type>
00279 basis::astring rectangle_warper<numeric_type>::text_form() const
00280 {
00281   return basis::astring("<warps from: ") + _system_1.text_form()
00282       + basis::astring(" with vertex at ") + vertex_name(_vert_1)
00283       + basis::astring(" into ") + _system_2.text_form()
00284       + basis::astring(" with vertex at ") + vertex_name(_vert_2)
00285       + basis::astring(">");
00286 }
00287 
00288 } // namespace.
00289 
00290 #endif
00291 
Generated on Sat Jan 28 04:22:42 2012 for hoople2 project by  doxygen 1.6.3