// ******** // curves.h (80 pts) // ******** // // updates on Nov 6, 2009: // // o removed the last two parameters xx0 and yy0 from the constructor Line::Line. // // Nov 5: // // o modified the comments next to Point:endp1 and Point:endp2. // o Curve::getTrans() changed to const. // o boundingBox() and type() functions of Curve and three derived classes all // changed to const. // o the exception selfIntersection renamed as intersectIdenticalCurves. // // Nov 3: // // o changed Point::print() to const. // // Oct 29: // // o removed arcLength function from Ellipse and CrunodalCubic classes. // o redistributed the points for these two functions. // o added the boundingBox method to Ellipse and CrunodalCubic classes // // Curves include line segments, ellipses, and crunodal cubics. Draw the curves // and compute their intersection points. Also, compute arc length as well as // curvature at specified points. #ifndef CURVES_H #define CURVES_H #include using namespace std; const double pi = 3.14159265358979323846; const double h = 0.000001; // size of intervals for numerical integration using // the trapezoidal rule. // ---------- // Exceptions (6 pts) // ---------- // // Implement three exceptions: // // 1. pointOffCurve, when a point does not lie on a curve. // 2. parameterOutsideDomain, when the curve parameter value is out of range. // 3. intersectIdenticalCurves, when trying to intersect two identical curves, which // are of the same shape and at the same location. // // They are to be throw by member functions of the class Curve and its derived classes. // add your code here ... // ----- // Point (10 pts) // ----- class Point { public: Point(double a = 0, double b = 0): x(a), y(b) {} // (1 pt) Point(const Point& pt); // (1 pt) Point operator-() const; // (1 pt) negation Point operator-(const Point &q) const; // (1 pt) vector subtraction double operator*(const Point &q) const; // (1 pt) dot product double operator%(const Point &q) const; // (1 pt) cross product double norm() const; // (1 pt) distance from the origin to the point Point unit_vector() const; // (1 pt) unit vector from the origin to the point // draw a point using openGL. void draw(int size=5, float r = 1.0f, float g = 0.0f, float b = 0.0f) const; // (1 pt) void setXY(double xx, double yy); // (1 pt) reset the x- & y-coordinate values double getX() const { return x; } double getY() const { return y; } void print() const { cout << "( " << x << ", " << y << " )" << endl; } private: double x, y; }; enum curveType {LINE, ELLIPSE, CRUNODALCUBIC}; // ------------------------- // Base class for all curves (12 pts) // ------------------------- // // All member functions accepting values of the curve parameter should throw a self-defined exception // parameterOutsideDomain if some of the values are not in the curve domain. class Curve { public: Curve(double xx = 0, double yy = 0, bool closed = false); // (1 pt) closed or open curve virtual curveType type() const = 0; virtual void print() const = 0; // print the curve description virtual Point point(double t) const = 0; // location (x(t), y(t)) on the curve virtual double parameter(Point p) const = 0; // find the parameter value t such that (x(t), y(t)) = p. // throw an exception pointOffCurve if t cannot be found virtual Point tangent(double t) const = 0; // (x'(t), y'(t)) not necessarily a unit vector virtual Point derivTangent(double t) const = 0; // (x'', y''), derivative of tangent virtual double curvature(double t = 0) const; // (4 pts) virtual double arcLength(double t1, double t2) const; // (5 pts) arc length of the segment over [t1, t2] virtual void boundingBox(Point& lowerLeft, Point& upperRight) const = 0; // determine the bounding box of the curve // return its lower left and upper right vertices virtual void draw() const = 0; // render the curve in OpenGL void drawPoint(double t, float r = 1.0f, float g = 0.0f, float b = 0.0f) const; // (1 pt) draw a point on the curve Point getTrans() const; // (1 pt) get the translation (x0, y0) protected: bool closedCurve; // true if this is a closed curve double x0, y0; // translation of the canonical curve given in equations (3)-(6) in the notes. }; // ------------ // Line Segment (10 pts) // ------------ // // A line segment is determined by two points p1 and p2 and has the parametrization // // p1 + t * (p2 - p1) with 0 <= t <= 1. // class Line : public Curve { public: Line(Point p1, Point p2); // (1 pt) Line(const Line& ln); // (1 pts) curveType type() const; // (0.5 pt) void print() const; // (0.5 pt) Point point(double t) const; // (0.5 pt) double parameter(Point p) const; // (0.5 pt) Point tangent(double t) const; // (0.5 pt) Point derivTangent(double t) const; // (0.5 pt) double curvature(double t = 0) const; // (1 pt) double arcLength(double t1, double t2) const; // (1 pt) no need for numerical integration. void getEndPoints(Point& p1, Point& p2) const; // (0.5 pt) void putEndPoints(const Point& p1, const Point& p2); // (0.5 pt) void boundingBox(Point& lowerLeft, Point& upperRight) const; // (1 pt) void draw() const; // (1 pt) private: Point endp1; // one endpoint Point endp2; // another endpoint }; // -------------------- // Ellipse (and Circle) (18 pts) // -------------------- // // An ellipse is represented as (a cos phi, b sin phi) where phi in [0, 2 * pi]. // However, any real value of parameter phi is considered valid. // // When a = b, it becomes a circle of radius a. class Ellipse : public Curve { public: Ellipse(double aa = 1, double bb = 1, double xx0 = 0, double yy0 = 0); // (1 pt) Ellipse(const Ellipse& e); // (1 pt) curveType type() const; // (1 pt) void print() const; // (1 pt) Point point(double phi) const; // (1 pt) double parameter(Point p) const; // (3 pts) Point tangent(double phi) const; // (1 pt) Point derivTangent(double phi) const; // (1 pt) double curvature(double phi = 0) const; // (2 pt) void getSemiAxes(double& aa, double& bb) const; // (1 pt) void putSemiAxes(double aa, double bb); // (1 pt) void boundingBox(Point& lowerLeft, Point& upperRight) const; // (2 pts) void draw() const; // (2 pts) private: double a, b; // halves of the lengths of the major and minor axes }; // -------------- // Crunodal Cubic (24 pts) // -------------- // This class implements the crunodal cubic // // x = c * (t^2 - 1); // y = d * t * (t^2 - 1) // // defined over an interval [tmin, tmax]. class CrunodalCubic: public Curve { public: CrunodalCubic(double cc = 1, double dd = 1, double xx0 = 0, double yy0 = 0, double t1 = 0, double t2 = 0 ); // (2 pts) tmin = t1, tmax = t2 CrunodalCubic(const CrunodalCubic& ccb); // (2 pts) curveType type() const; // (1 pt) void print() const; // (1 pt) Point point(double t) const; // (1 pt) double parameter(Point p) const; // (4 pts) Point tangent(double t) const; // (1 pt) Point derivTangent(double t) const; // (1 pt) double curvature(double t) const; // (2 pt) Point getCoeffs() const; // (1 pt) return the point (c, d) void setCoeffs(const Point& cd); // (1 pt) set the c & d to be the same as the // x and y coordinates of the point cd Point getRange() const; // (1 pt) return a point (tmin, tmax) void setRange(const Point& trange); // (1 pt) set tmin & tmax to be the same as the // x and y coordinates of trange. void boundingBox(Point& lowerLeft, Point& upperRight) const; // (2 pts) void draw() const; // (3 pts) private: double c; double d; double tmin; // left endpoint of the interval on which curve is defined double tmax; // right endpoint }; #endif