00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef SGE_MATH_RECT_IMPL_HPP_INCLUDED
00022 #define SGE_MATH_RECT_IMPL_HPP_INCLUDED
00023
00024 #include <ostream>
00025 #include <boost/lexical_cast.hpp>
00026 #include <sge/exception.hpp>
00027 #include "rect.hpp"
00028 #include "compare.hpp"
00029
00030 template<typename T>
00031 sge::math::basic_rect<T>::basic_rect(
00032 value_type const &left_,
00033 value_type const &top_,
00034 value_type const &right_,
00035 value_type const &bottom_)
00036 : left_(left_),
00037 top_(top_),
00038 right_(right_),
00039 bottom_(bottom_)
00040 {
00041 check();
00042 }
00043
00044 template<typename T>
00045 sge::math::basic_rect<T>::basic_rect(
00046 point_type const &pos,
00047 dim_type const &sz)
00048 : left_(pos.x()),
00049 top_(pos.y()),
00050 right_(pos.x() + sz.w()),
00051 bottom_(pos.y() + sz.h())
00052 {
00053 check();
00054 }
00055
00056 template<typename T>
00057 sge::math::basic_rect<T>::basic_rect(
00058 dim_type const &sz)
00059 : left_(
00060 static_cast<value_type>(0)),
00061 top_(
00062 static_cast<value_type>(0)),
00063 right_(sz.w()),
00064 bottom_(sz.h())
00065 {
00066 check();
00067 }
00068
00069 template<typename T>
00070 typename sge::math::basic_rect<T>::value_type sge::math::basic_rect<T>::w() const
00071 {
00072 return right() - left();
00073 }
00074
00075 template<typename T>
00076 typename sge::math::basic_rect<T>::value_type sge::math::basic_rect<T>::h() const
00077 {
00078 return bottom() - top();
00079 }
00080
00081 template<typename T>
00082 typename sge::math::basic_rect<T>::point_type const
00083 sge::math::basic_rect<T>::pos() const
00084 {
00085 return point_type(left(), top());
00086 }
00087
00088 template<typename T>
00089 typename sge::math::basic_rect<T>::size_type
00090 sge::math::basic_rect<T>::area() const
00091 {
00092 return dim().content();
00093 }
00094
00095 template<typename T>
00096 typename sge::math::basic_rect<T>::dim_type const
00097 sge::math::basic_rect<T>::dim() const
00098 {
00099 return dim_type(w(), h());
00100 }
00101
00102 template<typename T>
00103 typename sge::math::basic_rect<T>::const_reference
00104 sge::math::basic_rect<T>::left() const
00105 {
00106 return left_;
00107 }
00108
00109 template<typename T>
00110 typename sge::math::basic_rect<T>::const_reference
00111 sge::math::basic_rect<T>::top() const
00112 {
00113 return top_;
00114 }
00115
00116 template<typename T>
00117 typename sge::math::basic_rect<T>::const_reference
00118 sge::math::basic_rect<T>::right() const
00119 {
00120 return right_;
00121 }
00122
00123 template<typename T>
00124 typename sge::math::basic_rect<T>::const_reference
00125 sge::math::basic_rect<T>::bottom() const
00126 {
00127 return bottom_;
00128 }
00129
00130 template<typename T>
00131 typename sge::math::basic_rect<T>::reference
00132 sge::math::basic_rect<T>::left()
00133 {
00134 return left_;
00135 }
00136
00137 template<typename T>
00138 typename sge::math::basic_rect<T>::reference
00139 sge::math::basic_rect<T>::top()
00140 {
00141 return top_;
00142 }
00143
00144 template<typename T>
00145 typename sge::math::basic_rect<T>::reference
00146 sge::math::basic_rect<T>::right()
00147 {
00148 return right_;
00149 }
00150
00151 template<typename T>
00152 typename sge::math::basic_rect<T>::reference
00153 sge::math::basic_rect<T>::bottom()
00154 {
00155 return bottom_;
00156 }
00157
00158 template<typename T>
00159 void sge::math::basic_rect<T>::check()
00160 {
00161 if (right() < left() || bottom() < top())
00162 throw exception(SGE_TEXT("tried to create a rectangle ")+
00163 boost::lexical_cast<string>(*this)+SGE_TEXT(" which is invalid"));
00164 }
00165
00166 template<typename T>
00167 sge::math::basic_rect<T> const sge::math::operator+(
00168 basic_rect<T> const &l,
00169 typename basic_rect<T>::point_type const & r)
00170 {
00171 return basic_rect<T>(l.left() + r.x(),
00172 l.top() + r.y(),
00173 l.right() + r.x(),
00174 l.bottom() + r.y());
00175 }
00176
00177 template<typename T>
00178 sge::math::basic_rect<T> const
00179 sge::math::operator-(
00180 basic_rect<T> const &l,
00181 typename basic_rect<T>::point_type const &r)
00182 {
00183 return basic_rect<T>(l.left() - r.x(),
00184 l.top() - r.y(),
00185 l.right() - r.x(),
00186 l.bottom - r.y());
00187 }
00188
00189 template<typename T>
00190 bool sge::math::operator==(const basic_rect<T>& l,
00191 const basic_rect<T>& r)
00192 {
00193 return compare(l.left(),r.left())
00194 && compare(l.top(),r.top())
00195 && compare(l.right(),r.right())
00196 && compare(l.bottom(),r.bottom());
00197 }
00198
00199 template<typename T>
00200 bool sge::math::operator!=(const basic_rect<T>& l,
00201 const basic_rect<T>& r)
00202 {
00203 return !(l==r);
00204 }
00205
00206 template<typename T>
00207 sge::math::basic_rect<T> const
00208 sge::math::resize_borders(
00209 const basic_rect<T>& r,
00210 const T diff)
00211 {
00212 return basic_rect<T>(
00213 r.left() + diff,
00214 r.top() + diff,
00215 r.right() - diff,
00216 r.bottom() - diff);
00217 }
00218
00219 template<typename T, typename Ch, typename Traits>
00220 std::basic_ostream<Ch,Traits>& sge::math::operator<<(std::basic_ostream<Ch,Traits>& s,
00221 const basic_rect<T>& r)
00222 {
00223 return s << s.widen('(')
00224 << s.widen('(') << r.left() << s.widen(',') << r.top() << s.widen(')')
00225 << s.widen(',')
00226 << s.widen('(') << r.right() << s.widen(',') << r.bottom() << s.widen(')')
00227 << s.widen(')');
00228 }
00229
00230 template<typename D, typename S>
00231 sge::math::basic_rect<D> const
00232 sge::math::structure_cast(basic_rect<S> const &r)
00233 {
00234 return basic_rect<D>(
00235 structure_cast<D>(r.pos()),
00236 structure_cast<D>(r.dim()));
00237 }
00238
00239 #endif