00001 #ifndef PI
00002 #define PI 3.1415926535897932385
00003 #endif
00004
00005 #include <math.h>
00006 #include <ctype.h>
00007
00008 #include "point.h"
00009
00010
00011 MSLPoint::MSLPoint() {
00012 xrep = 0; yrep = 0;
00013 }
00014
00015
00016 MSLPoint::MSLPoint(double x, double y) {
00017 xrep = x; yrep = y;
00018 }
00019
00020
00021 double MSLPoint::angle(const MSLPoint& q, const MSLPoint& r) const
00022 {
00023 double dx1 = q.xcoord() - xrep;
00024 double dy1 = q.ycoord() - yrep;
00025 double dx2 = r.xcoord() - xrep;
00026 double dy2 = r.ycoord() - yrep;
00027
00028 if ((dx1 == 0 && dy1 == 0) || (dx2 == 0 && dy2 == 0)) {
00029 cerr << "MSLPoint::angle: zero vector input.\n";
00030 exit(-1);
00031 }
00032
00033 double norm = (dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2);
00034
00035 double cosfi = (dx1*dx2+dy1*dy2) / sqrt(norm);
00036
00037 if (cosfi >= 1.0 ) return 0;
00038 if (cosfi <= -1.0 ) return PI;
00039
00040 double fi = acos(cosfi);
00041
00042 if (dx1*dy2 < dy1*dx2) fi = -fi;
00043
00044 if (fi < 0) fi += 2*PI;
00045
00046 return fi;
00047 }
00048
00049
00050
00051
00052
00053 MSLPoint MSLPoint::rotate90(const MSLPoint& p) const
00054 { double px = p.xcoord();
00055 double py = p.ycoord();
00056 double dx = xrep - px;
00057 double dy = yrep - py;
00058 return MSLPoint(px-dy,py+dx);
00059 }
00060
00061 MSLPoint MSLPoint::rotate90() const
00062 { return MSLPoint(-yrep,xrep); }
00063
00064
00065 MSLPoint MSLPoint::rotate(const MSLPoint& origin, double fi) const
00066 { double cx = origin.xcoord();
00067 double cy = origin.ycoord();
00068 double sinfi = sin(fi);
00069 double cosfi = cos(fi);
00070 double dx = xrep - cx;
00071 double dy = yrep - cy;
00072 return MSLPoint(cx+dx*cosfi-dy*sinfi,cy+dx*sinfi+dy*cosfi);
00073 }
00074
00075
00076 MSLPoint MSLPoint::rotate(double fi) const
00077 { double sinfi = sin(fi);
00078 double cosfi = cos(fi);
00079 double x = xrep;
00080 double y = yrep;
00081 return MSLPoint(x*cosfi-y*sinfi,x*sinfi+y*cosfi);
00082 }
00083
00084
00085 MSLPoint MSLPoint::reflect(const MSLPoint& p, const MSLPoint& q) const
00086 {
00087
00088 double px = p.xrep;
00089 double py = p.yrep;
00090
00091 double x1 = xrep - px;
00092 double y1 = yrep - py;
00093 double x2 = q.xcoord() - px;
00094 double y2 = q.ycoord() - py;
00095
00096 double L = (x1*x1 + y1*y1) * (x2*x2 + y2*y2);
00097
00098 double cosfi = (x1*x2 + y1*y2);
00099 double sinfi = (x1*y2 - x2*y1);
00100 double cos2 = (cosfi*cosfi - sinfi*sinfi)/L;
00101 double sin2 = 2*cosfi*sinfi/L;
00102
00103 return MSLPoint(px + x1*cos2-y1*sin2, py + x1*sin2+y1*cos2);
00104 }
00105
00106
00107 MSLPoint MSLPoint::reflect(const MSLPoint& q) const
00108 {
00109 return MSLPoint(2*q.xcoord()-xrep, 2*q.ycoord()-yrep);
00110 }
00111
00112
00113
00114
00115
00116 MSLPoint MSLPoint::translate(double dx, double dy) const
00117 { return MSLPoint(xrep+dx,yrep+dy); }
00118
00119
00120 MSLPoint MSLPoint::translate_by_angle(double phi, double d) const
00121 { double dx = cos(phi) * d;
00122 double dy = sin(phi) * d;
00123 if (fabs(dx) < 1e-12) dx = 0;
00124 if (fabs(dy) < 1e-12) dy = 0;
00125 return MSLPoint(xrep+dx,yrep+dy);
00126 }
00127
00128
00129
00130
00131 double MSLPoint::sqr_dist(const MSLPoint& p) const
00132 { double dx = p.xcoord() - xrep;
00133 double dy = p.ycoord() - yrep;
00134 return dx*dx + dy*dy;
00135 }
00136
00137
00138
00139 double MSLPoint::xdist(const MSLPoint& q) const
00140 { return fabs(xrep - q.xcoord()); }
00141
00142 double MSLPoint::ydist(const MSLPoint& q) const
00143 { return fabs(yrep - q.ycoord()); }
00144
00145 double MSLPoint::distance(const MSLPoint& q) const
00146 { return sqrt(sqr_dist(q)); }
00147
00148
00149 bool MSLPoint::operator==(const MSLPoint& p) const
00150 { return (xrep == p.xcoord()) && (yrep == p.ycoord()); }
00151
00152
00153
00154 int side_of_circle(const MSLPoint& a, const MSLPoint& b, const MSLPoint& c,
00155 const MSLPoint& d)
00156 {
00157
00158 double ax = a.xcoord();
00159 double ay = a.ycoord();
00160
00161 double bx = b.xcoord() - ax;
00162 double by = b.ycoord() - ay;
00163 double bw = bx*bx + by*by;
00164
00165 double cx = c.xcoord() - ax;
00166 double cy = c.ycoord() - ay;
00167 double cw = cx*cx + cy*cy;
00168
00169 double D1 = cy*bw - by*cw;
00170 double D2 = bx*cw - cx*bw;
00171 double D3 = by*cx - bx*cy;
00172
00173 double dx = d.xcoord() - ax;
00174 double dy = d.ycoord() - ay;
00175
00176 double D = D1*dx + D2*dy + D3*(dx*dx + dy*dy);
00177
00178
00179 if (D != 0)
00180 return (D > 0) ? 1 : -1;
00181 else
00182 return 0;
00183 }
00184
00185
00186
00187 ostream& operator<<(ostream& out, const MSLPoint& p)
00188 { out << "(" << p.xcoord() << "," << p.ycoord() << ")";
00189 return out;
00190 }
00191
00192 istream& operator>>(istream& in, MSLPoint& p)
00193 {
00194
00195 double x,y;
00196 char c;
00197
00198 do in.get(c); while (in && isspace(c));
00199
00200 if (!in) return in;
00201
00202 if (c != '(') in.putback(c);
00203
00204 in >> x;
00205
00206 do in.get(c); while (isspace(c));
00207 if (c != ',') in.putback(c);
00208
00209 in >> y;
00210
00211 do in.get(c); while (c == ' ');
00212 if (c != ')') in.putback(c);
00213
00214 p = MSLPoint(x,y);
00215 return in;
00216
00217 }
00218
00219
00220 ostream& operator<<(ostream& out, const list<MSLPoint>& L)
00221 {
00222 list<MSLPoint>::iterator x;
00223 list<MSLPoint> vl;
00224 vl = L;
00225 for (x = vl.begin(); x != vl.end(); x++)
00226 out << " " << *x;
00227 return out;
00228 }
00229
00230
00231 istream& operator>>(istream& in, list<MSLPoint>& L)
00232 {
00233 L.clear();
00234 MSLPoint x;
00235 char c;
00236 for(;;)
00237 {
00238 while (in.get(c) && c==' ');
00239 if ((!in) || isspace(c)) break;
00240 in.putback(c);
00241 x = MSLPoint(); in >> x; L.push_back(x);
00242 }
00243 return in;
00244 }
00245
00246
00247
00248 ostream& operator<<(ostream& out, const list<list<MSLPoint> >& L)
00249 {
00250 list<list<MSLPoint> >::iterator x;
00251 list<list<MSLPoint> > vl;
00252 vl = L;
00253 for (x = vl.begin(); x != vl.end(); x++)
00254 out << *x << "\n";
00255 return out;
00256 }
00257
00258
00259 istream& operator>>(istream& in, list<list<MSLPoint> >& L)
00260 {
00261 L.clear();
00262 list<MSLPoint> x;
00263 for(;;)
00264 {
00265 char c;
00266 while (in.get(c) && isspace(c));
00267 if (!in) break;
00268 in.putback(c);
00269 x = MSLPolygon(); in >> x; L.push_back(x);
00270 }
00271 return in;
00272 }