// FILE: coordsys.cpp // written for the course 2172, 1999 #include "coordsys.h" #include // constructor coordinate::coordinate(double a,double b):_x(a),_y(b) { } // properties double coordinate::x() const { return _x; } double coordinate::y() const { return _y; } ostream& operator<<(ostream& os, const coordinate& c) { return os << '<' << c._x << ',' << c._y << '>'; } // properties double coordsys::minX() const { return xmin; } double coordsys::minY() const { return ymin; } double coordsys::maxX() const { return xmax; } double coordsys::maxY() const { return ymax; } // constructor coordsys::coordsys(double lx, double ly, double hx, double hy) :xmin(lx),xmax(hx),ymin(ly),ymax(hy) { } /* S.map(system,p1) * p1 is a point in system * map returns the corrsponding * coordinates of p1 in S */ coordinate coordsys::map(coordsys system,coordinate p1) { return coordinate( xmin + (p1.x()-system.xmin) / (system.xmax - system.xmin) * (xmax - xmin), // mapped x value ymin + (p1.y()-system.ymin) / (system.ymax - system.ymin) * (ymax - ymin) // mapped y value ); } #ifndef sqr #define sqr(A) ((A)*(A)) #endif #ifndef pi #define pi 3.1415926535897 #endif /* S.rotate(o,p,angle) * returns the coordinates of p rotated about p * by angle many degrees (not radians!) counter * clock-wise */ coordinate coordsys::rotate(coordinate p,coordinate o,double beta) { // if o == p then beta is irrelevant if ((int)p.x() == (int)o.x() && (int)p.y() == (int)o.y()) return p; if (beta==0) return p; // no rotation double betarad = (pi * beta)/180.0; // beta in radians // hypotenuse double hyp = sqrt(sqr(p.x()-o.x()) + sqr(p.y() - o.y())); double alpharad; // move angle to the right quadrant // Tricky special cases that would render tan^-1 to infinity if ((int)p.x() == (int)o.x()) { // on same horizontal if (p.y() > o.y()) { // p above o alpharad = pi/2.0; // 90 } else { // p below o alpharad = -pi/2.0; // -90 } } else { // not on same horizontal if ((int)p.y() == (int)o.y()) { // on same vertical if (p.x() < o.x()) { // p "before" o alpharad = pi; // 180 } else { alpharad = 0; // 0 } } else { // not on same vertical, not on same horizontal double invtan = atan((p.y()-o.y())/(p.x()-o.x())); if (p.x() < o.x()) { // II or III quadrant alpharad = invtan + pi; // 180 - alpha } else { // I or IV quadrant alpharad = invtan; } } } return coordinate(o.x()+cos(alpharad+betarad)*hyp, o.y()+sin(alpharad+betarad)*hyp); } ostream& operator<<(ostream& os, const coordsys& s) { return os << '[' << coordinate(s.xmin,s.ymin) << ',' << coordinate(s.xmax,s.ymax) << ']'; }