00001 #ifndef POINT_IMPLEMENTATION
00002 #define POINT_IMPLEMENTATION
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "angle.cpp"
00019 #include "math_bits.h"
00020 #include "point.h"
00021
00022 #include <basis/function.h>
00023 #include <basis/istring.h>
00024
00025 #include <math.h>
00026
00027
00028
00029
00030
00031
00032
00033
00034 namespace geometric {
00035
00036 template <class numeric_type>
00037 point<numeric_type>::point(numeric_type x, numeric_type y) { set(x, y); }
00038
00039 template <class numeric_type>
00040 point<numeric_type>::point(numeric_type r, double_angle theta)
00041 { set(r, theta); }
00042
00043 template <class numeric_type>
00044 istring point<numeric_type>::text_form() const
00045 {
00046 numeric_type temp = 0;
00047 istring specifier(numeric_specifier(temp));
00048 istring sprintf_template(istring::SPRINTF, "(%s, %s)", specifier.s(), specifier.s());
00049 return istring(istring::SPRINTF, sprintf_template.s(), x(), y());
00050 }
00051
00052 template <class numeric_type>
00053 void point<numeric_type>::set(numeric_type x, numeric_type y)
00054 { _x = x; _y = y; }
00055
00056 template <class numeric_type>
00057 numeric_type point<numeric_type>::r() const
00058 {
00059 const double sumsquar = square(x()) + square(y());
00060 return numeric_type(sqrt(sumsquar));
00061 }
00062
00063 template <class numeric_type>
00064 void point<numeric_type>::set(numeric_type r, double_angle theta)
00065 { set(numeric_type(r * theta.cosine()), numeric_type(r * theta.sine())); }
00066
00067 template <class numeric_type>
00068 numeric_type point<numeric_type>::distance(const point &p2) const
00069 {
00070 const double sumsquar = square(p2.x() - x()) + square(p2.y() - y());
00071 return numeric_type(sqrt(sumsquar));
00072 }
00073
00074 template <class numeric_type>
00075 double_angle point<numeric_type>::theta() const
00076 {
00077 outcome retval;
00078 return double_angle::arctangent(y(), x(), retval);
00079 }
00080
00081 template <class contents>
00082 void point<contents>::pack(byte_array &packed_form) const
00083 {
00084 basis::attach(packed_form, _x);
00085 basis::attach(packed_form, _y);
00086 }
00087
00088 template <class contents>
00089 bool point<contents>::unpack(byte_array &packed_form)
00090 {
00091 if (!basis::detach(packed_form, _x)) return false;
00092 if (!basis::detach(packed_form, _y)) return false;
00093 return true;
00094 }
00095
00096 template <class numeric_type>
00097 numeric_type point<numeric_type>::magnitude() const
00098 {
00099 const double sumsquar = square(x()) + square(y());
00100 return numeric_type(sqrt(sumsquar));
00101 }
00102
00103 template <class numeric_type>
00104 point<numeric_type> point<numeric_type>::operator + (const point &arg2) const
00105 { return point<numeric_type>(x() + arg2.x(), y() + arg2.y()); }
00106
00107 template <class numeric_type>
00108 point<numeric_type> point<numeric_type>::operator - (const point &arg2) const
00109 { return point<numeric_type>(x() - arg2.x(), y() - arg2.y()); }
00110
00111 template <class numeric_type>
00112 point<numeric_type> &point<numeric_type>::operator += (const point &arg2)
00113 { _x += arg2.x(); _y += arg2.y(); return *this; }
00114
00115 template <class numeric_type>
00116 point<numeric_type> &point<numeric_type>::operator -= (const point &arg2)
00117 { _x -= arg2.x(); _y -= arg2.y(); return *this; }
00118
00119 template <class numeric_type>
00120 bool point<numeric_type>::operator == (const point &arg2) const
00121 {
00122
00123 double epsilon = 1e-10;
00124 return (absolute_value(x() - arg2.x()) <= epsilon)
00125 && (absolute_value(y() - arg2.y()) <= epsilon);
00126 }
00127
00128
00129 template <class numeric_type>
00130 bool point<numeric_type>::operator != (const point &arg2) const
00131 { return !(*this == arg2); }
00132
00133 template <class numeric_type>
00134 point<numeric_type> point<numeric_type>::rotate
00135 (const double_angle &theta) const
00136 {
00137 numeric_type tempX = x();
00138 numeric_type tempY = y();
00139 numeric_type temp1 = numeric_type(tempX * theta.cosine()
00140 - tempY * theta.sine());
00141 numeric_type temp2 = numeric_type(tempX * theta.sine()
00142 + tempY * theta.cosine());
00143 return point<numeric_type>(temp1, temp2);
00144 }
00145
00146 template <class numeric_type>
00147 bool point<numeric_type>::from_text(const istring &_text)
00148 {
00149 numeric_type x = 0, y = 0;
00150 istring text(_text);
00151
00152 text = crop_non_numeric(text);
00153
00154 x = text.convert(x);
00155
00156 text = crop_numeric(text);
00157
00158 text = crop_non_numeric(text);
00159
00160 y = text.convert(y);
00161 set(x, y);
00162 return true;
00163 }
00164
00165 }
00166
00167 #endif
00168