00001 #ifndef WARPER_IMPLEMENTATION
00002 #define WARPER_IMPLEMENTATION
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "rectangle.cpp"
00019 #include "warper.h"
00020
00021 #include <basis/istring.h>
00022
00023 namespace geometric {
00024
00025 template <class numeric_type>
00026 rectangle_warper<numeric_type>::rectangle_warper
00027 (const rectangle<numeric_type> &system_1,
00028 const rectangle<numeric_type> &system_2,
00029 origin_vertex v1, origin_vertex v2)
00030 : _system_1(system_1), _system_2(system_2), _vert_1(v1), _vert_2(v2)
00031 {}
00032
00033 template <class numeric_type>
00034 rectangle_warper<numeric_type>::~rectangle_warper() {}
00035
00036 template <class numeric_type>
00037 void rectangle_warper<numeric_type>::system_1
00038 (const rectangle<numeric_type> &to_set, origin_vertex v)
00039 { _system_1 = to_set; _vert_1 = v; }
00040
00041 template <class numeric_type>
00042 void rectangle_warper<numeric_type>::system_2
00043 (const rectangle<numeric_type> &to_set, origin_vertex v)
00044 { _system_2 = to_set; _vert_2 = v; }
00045
00046 template <class numeric_type>
00047 point<numeric_type> rectangle_warper<numeric_type>::to_system_1
00048 (const point<numeric_type> &in_system_2) const
00049 { return scale_point(_system_2, _system_1, _vert_2, _vert_1, in_system_2); }
00050
00051 template <class numeric_type>
00052 point<numeric_type> rectangle_warper<numeric_type>::to_system_2
00053 (const point<numeric_type> &in_system_1) const
00054 { return scale_point(_system_1, _system_2, _vert_1, _vert_2, in_system_1); }
00055
00056 template <class numeric_type>
00057 rectangle<numeric_type> rectangle_warper<numeric_type>::to_system_1
00058 (const rectangle<numeric_type> &in_system_2) const
00059 {
00060 return scale_rectangle(_system_2, _system_1, _vert_2, _vert_1,
00061 in_system_2);
00062 }
00063
00064 template <class numeric_type>
00065 rectangle<numeric_type> rectangle_warper<numeric_type>::to_system_2
00066 (const rectangle<numeric_type> &in_system_1) const
00067 {
00068 return scale_rectangle(_system_1, _system_2, _vert_1, _vert_2,
00069 in_system_1);
00070 }
00071
00072 template <class numeric_type>
00073 void rectangle_warper<numeric_type>::separate_vertical
00074 (origin_vertex v, vertical_component &to_set) const
00075 {
00076 if ( (v == BOTTOM_LEFT) || (v == BOTTOM_RIGHT) ) to_set = RW_BOTTOM;
00077 to_set = RW_TOP;
00078 }
00079
00080 template <class numeric_type>
00081 void rectangle_warper<numeric_type>::separate_horizontal
00082 (origin_vertex v, horizontal_component &to_set) const
00083 {
00084 if ( (v == BOTTOM_LEFT) || (v == TOP_LEFT) ) to_set = RW_LEFT;
00085 to_set = RW_RIGHT;
00086 }
00087
00088 template <class numeric_type>
00089 rectangle<numeric_type> rectangle_warper<numeric_type>::flip_accordingly
00090 (const rectangle<numeric_type> &to_flip, origin_vertex flipo,
00091 origin_vertex targo) const
00092 {
00093
00094 if (flipo == targo) return to_flip;
00095 numeric_type x1(to_flip.vertex_1().x());
00096 numeric_type y1(to_flip.vertex_1().y());
00097 numeric_type x2(to_flip.vertex_2().x());
00098 numeric_type y2(to_flip.vertex_2().y());
00099 horizontal_component horiz1;
00100 separate_horizontal(flipo, horiz1);
00101 horizontal_component horiz2;
00102 separate_horizontal(targo, horiz2);
00103 bool flip_x = bool(horiz1 != horiz2);
00104 vertical_component vert1;
00105 separate_vertical(flipo, vert1);
00106 vertical_component vert2;
00107 separate_vertical(targo, vert2);
00108 bool flip_y = bool(vert1 != vert2);
00109 if (flip_x) swap_values(x1, x2);
00110 if (flip_y) swap_values(y1, y2);
00111
00112 return rectangle<numeric_type>(x1, y1, x2, y2);
00113 }
00114
00115 template <class numeric_type>
00116 rectangle<numeric_type> rectangle_warper<numeric_type>::scale_rectangle
00117 (const rectangle<numeric_type> &source,
00118 const rectangle<numeric_type> &target, origin_vertex source_origin,
00119 origin_vertex target_origin, const rectangle<numeric_type> &old) const
00120 {
00121 rectangle<numeric_type> s = rectangle<numeric_type>
00122 (flip_accordingly(source, source_origin, BOTTOM_LEFT));
00123 numeric_type width_source = s.vertex_2().x() - s.vertex_1().x();
00124 numeric_type height_source = s.vertex_2().y() - s.vertex_1().y();
00125 if ( !width_source || !height_source ) {
00126
00127
00128 return old;
00129 }
00130 rectangle<numeric_type> t(flip_accordingly(target, target_origin, BOTTOM_LEFT));
00131 numeric_type width_target = t.vertex_2().x() - t.vertex_1().x();
00132 numeric_type height_target = t.vertex_2().y() - t.vertex_1().y();
00133 numeric_type x_scale = width_target / width_source;
00134 numeric_type y_scale = height_target / height_source;
00135
00136
00137
00138 rectangle<numeric_type> o(flip_accordingly(old, source_origin, BOTTOM_LEFT));
00139
00140 rectangle<numeric_type> to_return = flip_accordingly(rectangle<numeric_type>
00141 ((o.vertex_1().x() - s.vertex_1().x()) * x_scale + t.vertex_1().x(),
00142 (o.vertex_1().y() - s.vertex_1().y()) * y_scale + t.vertex_1().y(),
00143 (o.vertex_2().x() - s.vertex_1().x()) * x_scale + t.vertex_1().x(),
00144 (o.vertex_2().y() - s.vertex_1().y()) * y_scale + t.vertex_1().y()),
00145 BOTTOM_LEFT, target_origin);
00146
00147
00148
00149 return to_return;
00150 }
00151
00152 template <class numeric_type>
00153 point<numeric_type> rectangle_warper<numeric_type>::scale_point
00154 (const rectangle<numeric_type> &source, const rectangle<numeric_type> &target,
00155 origin_vertex source_origin, origin_vertex target_origin,
00156 const point<numeric_type> &old) const
00157 {
00158
00159 return scale_rectangle(source, target, source_origin, target_origin,
00160 rectangle<numeric_type>(old, old)).vertex_1();
00161 }
00162
00163 template <class numeric_type>
00164 istring rectangle_warper<numeric_type>::vertex_name(origin_vertex v) const
00165 {
00166 istring name("unknown");
00167 switch (v) {
00168 case BOTTOM_LEFT: name = "bottom-left"; break;
00169 case BOTTOM_RIGHT: name = "bottom-right"; break;
00170 case TOP_LEFT: name = "top-left"; break;
00171 case TOP_RIGHT: name = "top-right"; break;
00172 }
00173 return name;
00174 }
00175
00176 template <class numeric_type>
00177 istring rectangle_warper<numeric_type>::text_form() const
00178 {
00179 return istring("<warps from: ") + _system_1.text_form()
00180 + istring(" with vertex at ") + vertex_name(_vert_1)
00181 + istring(" into ") + _system_2.text_form()
00182 + istring(" with vertex at ") + vertex_name(_vert_2)
00183 + istring(">");
00184 }
00185
00186 }
00187
00188 #endif
00189