/* This file is part of the extensible drawing editor Ipe. Copyright (C) 1993-2004 Otfried Cheong Ipe is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exception, you have permission to link Ipe with the CGAL library and distribute executables, as long as you follow the requirements of the Gnu General Public License in regard to all of the software in the executable aside from CGAL. Ipe is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Ipe; if not, you can find it at "http://www.gnu.org/copyleft/gpl.html", or write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* -*-C++-*- * * plageo.h * * This is a slightly modified version of the Plageo header file, * with some changes to make it compile on other machines * --- templates eliminated by using "ireray.h" instead of "reray.h" * --- using C's "stdio.h" instead of C++'s "iostream.h" * --- replaced by to use only ANSI functions * --- inserted a few missing types in this file and in `pl_onedim.C' * * $Modified: Monday, September 19, 1994 by otfried $ */ /* NOTICE This software is public domain. It may be freely copied and used in non-commercial products, assuming proper credit to the author is given, but it should not be resold. If you want to use the software for commercial products, contact the author. This software is provided `as is' without warranty of any kind, either expressed or implied. The entire risk as to the quality and performance of the software is with you. Should the software prove defective, you assume the cost of all necessary servicing, repair or correction. Please send any comments to Geert-Jan Giezeman (geert@cs.ruu.nl). --- but beware that I may have introduced bugs! (otfried@cs.ruu.nl) */ // set a flag for a few fixes necessary for Ipe #define FOR_IPE #ifndef PLAGEOH #define PLAGEOH #include #ifdef FOR_IPE #include #include #include #else #include #include #include // replaces the old definition in this header file #define DeclareReray(Trr, T) typedef reray Trr; #endif /******************************* * * basic types (classes) for planar geometry * * angles * vectors * bounding boxes * *******************************/ /* enum pl_types { PL_NOTYPE=100, S_COORD=101, RERAY=102, PL_COORD=111, PL_VEC=112, PL_UNITVEC=113, PL_BOUNDINGBOX=114, PL_ROTRA=115, PL_VERTEX=121, PL_LINE=122, PL_RAY=123, PL_EDGE=124, PL_POLYGON=12, PL_DISC=126, PL_ARC=127 }; */ #ifdef sgi typedef float s_coord; // for single coordinate #else typedef double s_coord; // for single coordinate #endif class pl_angle { public: pl_angle() {} pl_angle(s_coord v) {_a = v;} void normalise(s_coord lowlimit = -M_PI); void normalize(s_coord lowlimit = -M_PI) { normalise(lowlimit);} int lies_between(pl_angle small, pl_angle large) const; s_coord value() const { return _a; } s_coord degrees() const { return (180/M_PI)*_a; } s_coord normalised_value(s_coord lowlimit = -M_PI) const; s_coord normalized_value(s_coord lowlimit = -M_PI) const { return normalised_value(lowlimit); } operator s_coord() const { return _a; } protected: s_coord _a; }; DeclareReray(s_coordreray, s_coord); DeclareReray(intreray, int); inline int increasing_angle_order(pl_angle small, pl_angle theta, pl_angle large) { return theta.lies_between(small, large); } // returns true if, travelling over the unit circle counterclockwise, you will // encounter the angles small, theta and large in that order. // returns false if you would encounter them in the order large, theta, small. inline int decreasing_angle_order(pl_angle large, pl_angle theta, pl_angle small) { return theta.lies_between(small, large); } // opposite of increasing_angle_order // vectors class pl_fixedvec { public: pl_fixedvec() {} pl_fixedvec(s_coord x, s_coord y) { c[0]=x; c[1]=y;} const s_coord &x() const {return c[0];} const s_coord &y() const {return c[1];} s_coord length() const { return sqrt_pp(c[0]*c[0] + c[1]*c[1]); } s_coord sqlength() const { return c[0]*c[0] + c[1]*c[1]; } protected: s_coord c[2]; private: // Ipe: somehow, the HP compiler cannot cope with these assignments #ifdef sgi void operator=(pl_fixedvec) ; // not implemented. #endif }; inline int operator< (const pl_fixedvec &a, const pl_fixedvec &b) { int result; if (a.x() == b.x()) result = (a.y() < b.y()); else result = (a.x() < b.x()); return result; } inline int operator> (const pl_fixedvec &a, const pl_fixedvec &b) { int result; if (a.x() == b.x()) result = (a.y() > b.y()); else result = (a.x() > b.x()); return result; } inline int operator<= (const pl_fixedvec &a, const pl_fixedvec &b) { int result; if (a.x() == b.x()) result = (a.y() <= b.y()); else result = (a.x() < b.x()); return result; } inline int operator>= (const pl_fixedvec &a, const pl_fixedvec &b) { int result; if (a.x() == b.x()) result = (a.y() >= b.y()); else result = (a.x() > b.x()); return result; } extern int compare(const pl_fixedvec &a, const pl_fixedvec &b); class pl_vec: public pl_fixedvec { public: pl_vec() {} pl_vec(const pl_fixedvec &vec) : pl_fixedvec(vec) {} pl_vec(const s_coord x, const s_coord y) : pl_fixedvec(x, y) {} void normalise() {s_coord l=1/length();c[0]*=l;c[1]*=l;} void normalize() { normalise();} void set_x(s_coord x) { c[0] = x;} void set_y(s_coord y) { c[1] = y;} #ifdef sgi void operator=(const pl_fixedvec &vec) { c[0] = vec.x(); c[1] = vec.y(); } #endif void operator*=(s_coord f) { c[0] *= f; c[1] *= f;} void operator+=(const pl_fixedvec &vec) {c[0] += vec.x(); c[1] += vec.y(); } void operator-=(const pl_fixedvec &vec) {c[0] -= vec.x(); c[1] -= vec.y(); } }; class pl_unitvec: public pl_fixedvec { // assert: length == 1 public: pl_unitvec(): pl_fixedvec(1.0, 0.0) {} pl_unitvec(pl_angle angle) ; pl_unitvec operator-() const { return pl_unitvec(-x(), -y()); } pl_unitvec normal() const { return pl_unitvec(-y(), x());} friend pl_unitvec normalised(const pl_fixedvec &vec) ; friend s_coord factorise(pl_unitvec &uv,const pl_fixedvec &vec); #ifdef sgi void operator=(const pl_unitvec &uvec) { c[0]=uvec.x(); c[1]=uvec.y(); } #endif protected: pl_unitvec(const s_coord a, const s_coord b): pl_fixedvec(a, b){} pl_unitvec(const pl_fixedvec &vec): pl_fixedvec(vec) {} }; inline pl_unitvec normalized(const pl_fixedvec &vec) { return normalised(vec); } inline s_coord factorize(pl_unitvec &uvec,const pl_fixedvec &vec) { return factorise(uvec, vec); } const pl_vec pl_origin(0, 0); extern const pl_unitvec pl_xdir; extern const pl_unitvec pl_ydir; extern pl_angle angle_of(const pl_fixedvec &vec); pl_vec to_polar(const pl_fixedvec &); pl_vec from_polar(const pl_fixedvec &); extern pl_angle angle_between(const pl_unitvec &, const pl_unitvec &); inline pl_vec operator- (const pl_fixedvec &vec) { return pl_vec(-vec.x(), -vec.y()); } inline pl_vec operator*(s_coord f, const pl_fixedvec &v) { return pl_vec(f*v.x(), f*v.y()); } inline pl_vec operator+ (const pl_fixedvec &v1, const pl_fixedvec &v2) { return pl_vec(v1.x()+v2.x(), v1.y()+v2.y()); } inline pl_vec operator- (const pl_fixedvec &v1, const pl_fixedvec &v2) { return pl_vec(v1.x()-v2.x(), v1.y()-v2.y()); } inline s_coord dot(const pl_fixedvec &v1, const pl_fixedvec &v2) { return v1.x()*v2.x() + v1.y()*v2.y(); } inline s_coord cross(const pl_fixedvec &v1, const pl_fixedvec &v2) { return v1.x()*v2.y() - v1.y()*v2.x(); } class pl_boundingbox { public: pl_boundingbox() {} pl_boundingbox(pl_fixedvec c) : min(c),max(c){} int is_empty() const {return min.x() > max.x();} s_coord xmax() const {return max.x();} s_coord xmin() const {return min.x();} s_coord ymax() const {return max.y();} s_coord ymin() const {return min.y();} void make_empty() {min.set_x(1); max.set_x(-1);} s_coord area() const ; void translate(const pl_fixedvec &disp); void scale(s_coord fac); void add_point(const pl_fixedvec &c); void add_first_point(const pl_fixedvec &c) {min = c; max = c; } void add_non_first_point(const pl_fixedvec &c) ; void operator+=(const pl_boundingbox &); friend pl_boundingbox intersect(pl_boundingbox const &, pl_boundingbox const &); friend pl_boundingbox operator+(const pl_boundingbox &, const pl_boundingbox &); protected: pl_vec min; pl_vec max; }; typedef pl_boundingbox pl_box; extern int lies_inside(const pl_box &innerbb, const pl_box &outerbb); class pl_transform { public: virtual pl_vec operator*(const pl_vec &) const =0; virtual pl_unitvec operator*(const pl_unitvec &) const =0; virtual s_coord operator*(s_coord) const =0; virtual pl_angle operator*(pl_angle) const = 0; }; enum pl_object_type {PL_POINT=1, PL_LINE, PL_RAY, PL_EDGE, PL_POLYGON, PL_DISC, PL_ARC}; class pl_object { public: virtual ~pl_object() ; virtual pl_box bbox() const = 0; virtual void transform(const pl_transform &tfm) = 0; virtual void rotate(pl_angle) ; virtual void translate(const pl_fixedvec &) ; virtual void scale(s_coord) ; virtual pl_object_type type() const = 0; }; class pl_point: public pl_object { public: pl_point() {} pl_point(const pl_fixedvec& v) :_vec(v) {} pl_point(s_coord a, s_coord b) : _vec(a, b) {} pl_object_type type() const; pl_box bbox() const ; const pl_vec &vec() const {return _vec;} void transform(const pl_transform &tfm); void translate(const pl_fixedvec &disp) ; void scale(s_coord fac); protected: pl_vec _vec; }; DeclareReray(uvecreray, pl_unitvec); DeclareReray(pl_vecreray, pl_vec); /**** flags8 **** * * flags8 supplies 8 flags. * initially the flags are not set. * one or more flags can be queried by means of is_set(char x). * this funtion returns true iff all flags denoted by x are true. * the flags denoted by x are those bits of x that are 1, so * isvalid(0x2c) (0010 1100) inspects 3 flags. * the other routines set, unset or toggle one or more bits. * ********************/ class flags8 { char flags; // internally: bit 0:set, 1:not set public: flags8() { flags = all_flags; } int is_set(char x) const { return ((x & flags) == 0); } void set(char x) { flags &= ~x; } void unset(char x) { flags |= x; } void toggle(char x) { flags ^= x; } enum flags { flag0 = 0x01, flag1 = 0x02, flag2 = 0x04, flag3 = 0x08, flag4 = 0x10, flag5 = 0x20, flag6 = 0x40, flag7 = 0x80, all_flags = 0xff }; }; typedef unsigned short ushort; class flags16 { ushort flags; // internally: bit 0:set, 1:not set public: flags16() { flags = all_flags; } int is_set(ushort x) const { return ((x & flags) == 0); } void set(ushort x) { flags &= ~x; } void unset(ushort x) { flags |= x; } void toggle(ushort x) { flags ^= x; } enum flags { flag0 = 0x01, flag1 = 0x02, flag2 = 0x04, flag3 = 0x08, flag4 = 0x10, flag5 = 0x20, flag6 = 0x40, flag7 = 0x80, flag8 = 0x100, flag9 = 0x200, flag10 = 0x400, flag11 = 0x800, flag12 = 0x1000, flag13 = 0x2000, flag14 = 0x4000, flag15 = 0x8000, all_flags = 0xffff }; }; #ifndef FOR_IPE // the HP C++ compiler complains about long enum's typedef unsigned long ulong; class flags32 { ulong flags; // internally: bit 0:set, 1:not set public: flags32() { flags = all_flags; } int is_set(ulong x) const { return ((x & flags) == 0); } void set(ulong x) { flags &= ~x; } void unset(ulong x) { flags |= x; } void toggle(ulong x) { flags ^= x; } enum flags { flag0 = 0x1, flag1 = 0x2, flag2 = 0x4, flag3 = 0x8, flag4 = 0x10, flag5 = 0x20, flag6 = 0x40, flag7 = 0x80, flag8 = 0x100, flag9 = 0x200, flag10 = 0x400, flag11 = 0x800, flag12 = 0x1000, flag13 = 0x2000, flag14 = 0x4000, flag15 = 0x8000, flag16 = 0x10000, flag17 = 0x20000, flag18 = 0x40000, flag19 = 0x80000, flag20 = 0x100000, flag21 = 0x200000, flag22 = 0x400000, flag23 = 0x800000, flag24 = 0x1000000, flag25 = 0x2000000, flag26 = 0x4000000, flag27 = 0x8000000, flag28 = 0x10000000, flag29 = 0x20000000, flag30 = 0x40000000, flag31 = 0x80000000, all_flags = 0xffffffff }; }; #endif class pl_unit_tfm : public pl_transform{ public: virtual pl_vec operator*(const pl_vec &) const =0; virtual pl_unitvec operator*(const pl_unitvec &) const =0; virtual pl_angle operator*(pl_angle) const = 0; s_coord operator*(s_coord) const; }; class pl_uniscale: public pl_transform { public: pl_uniscale() : _scale(1) {} pl_uniscale(s_coord f) : _scale(f) {} pl_vec operator*(const pl_vec &) const ; pl_unitvec operator*(const pl_unitvec &) const ; pl_angle operator*(pl_angle) const; s_coord operator*(s_coord) const ; s_coord factor() const { return _scale;} protected: s_coord _scale; }; class pl_translation: public pl_unit_tfm { public: pl_translation() : _trans(0, 0) {} pl_translation(const pl_fixedvec &v) :_trans(v) {} pl_vec operator*(const pl_vec &) const ; s_coord operator*(s_coord) const ; pl_unitvec operator*(const pl_unitvec &) const ; pl_angle operator*(pl_angle) const; pl_vec vec() const { return _trans;} protected: pl_vec _trans; }; class pl_rotation: public pl_unit_tfm { public: pl_rotation() : _angle(0) {_rot[0]=1; _rot[1]=0;} pl_rotation(pl_angle theta) ; pl_vec operator*(const pl_vec &) const ; s_coord operator*(s_coord) const ; pl_unitvec operator*(const pl_unitvec &) const ; pl_angle operator*(pl_angle) const; pl_angle angle() const ; protected: s_coord _rot[2]; pl_angle _angle; }; class pl_rotra: public pl_unit_tfm { public: pl_rotra() : _trans(0, 0), _angle(0) {_rot[0]=1;_rot[1]=0;} pl_rotra(pl_angle theta, const pl_fixedvec &vec) ; pl_rotra(pl_angle theta) ; pl_rotra(const pl_fixedvec &vec) ; pl_rotra inverse() const; pl_vec operator*(const pl_vec &) const ; s_coord operator*(s_coord) const ; pl_unitvec operator*(const pl_unitvec &) const ; pl_angle operator*(pl_angle) const; pl_rotra operator*(const pl_rotra &) const; void get_params(pl_angle &theta, pl_vec &vec) const; int operator==(const pl_rotra &) const; void set_x(s_coord x) { _trans.set_x(x); } s_coord x() const { return _trans.x();} s_coord get_x() const { return _trans.x();} void set_y(s_coord y) { _trans.set_y(y); } s_coord y() const { return _trans.y();} s_coord get_y() const { return _trans.y();} void set_angle(pl_angle theta) ; pl_angle get_angle() const ; protected: pl_angle _angle; s_coord _rot[2]; pl_vec _trans; }; class pl_ortho_tfm: public pl_transform { public: pl_ortho_tfm() : _angle(0), _scale(1), _trans(0, 0) {_tfm[0]=1; _tfm[1]=0;} pl_ortho_tfm(pl_angle, s_coord, const pl_fixedvec &) ; pl_vec operator*(const pl_vec &) const ; pl_unitvec operator*(const pl_unitvec &) const ; pl_angle operator*(pl_angle) const; s_coord operator*(s_coord) const ; pl_ortho_tfm operator*(const pl_ortho_tfm &) const; int operator==(const pl_ortho_tfm &) const; void get_params(pl_angle &theta, s_coord &scale, pl_vec &trans) ; protected: pl_angle _angle; s_coord _scale; s_coord _tfm[2]; // transformation matrix (top row), pl_vec _trans; }; class intervals { public: int starts_at_min_infinity; // boolean s_coordreray boundaries; // sorted reray of boundaries of intervals intervals() : starts_at_min_infinity(0) {} void toggle(); void toggle_after(s_coord x); int is_empty() const; int lies_in(s_coord) const; int find_index_after(s_coord x) const; int is_interval_endpoint(int index) const; }; extern intervals operator&(const intervals &, const intervals &); extern intervals operator|(const intervals &, const intervals &); extern intervals operator^(const intervals &, const intervals &); // shortest gap gives the shortest distance between an interval in a to // an interval in b. It will be zero if a&b is not empty. extern s_coord shortest_gap(const intervals &a, const intervals &b); /******************************* * * one dimensional types (classes) for planar geometry * * -lines * -rays * -edges * *******************************/ class pl_line: public pl_object { public: pl_line() {}; pl_line(const pl_fixedvec &v1, const pl_fixedvec &v2) : _vt(v1), _d(normalized(v2-v1)) {} pl_line(const pl_fixedvec &vt, const pl_unitvec &uv) : _vt(vt), _d(uv) {} pl_object_type type() const; pl_box bbox() const ; const pl_vec & ref_vt() const { return _vt; } const pl_unitvec & direction() const { return _d; } pl_unitvec normal() const { return _d.normal(); } s_coord placeproject(const pl_fixedvec &vec) const ; s_coord dirproject(const pl_fixedvec &vec) const ; pl_vec placevec(s_coord co) const {return _vt + co*_d;} pl_vec dirvec(s_coord co) const {return co*_d;} void transform(const pl_transform &tfm) ; void translate(const pl_fixedvec &disp) ; void scale(s_coord fac); protected: pl_vec _vt; pl_unitvec _d; }; class pl_ray: public pl_object { public: pl_ray() {} pl_ray(const pl_fixedvec &vt, const pl_unitvec &vec) : _begin_vt(vt), _d(vec) {} pl_object_type type() const; pl_box bbox() const ; const pl_vec & begin_vt() const {return _begin_vt;} const pl_unitvec & direction() const { return _d;} pl_line supporting_line() const { return pl_line(_begin_vt, _d); } void transform(const pl_transform &tfm) ; void translate(const pl_fixedvec &disp) ; void scale(s_coord fac); protected: pl_vec _begin_vt; pl_unitvec _d; // direction }; class pl_edge: public pl_object { public: pl_edge() {} pl_edge(const pl_fixedvec &v1, const pl_fixedvec &v2) : _begin_vt(v1), _end_vt(v2) {} pl_object_type type() const; pl_box bbox() const; const pl_vec & begin_vt() const { return _begin_vt;} const pl_vec & end_vt() const { return _end_vt;} pl_line supporting_line() const {return pl_line(_begin_vt,_end_vt);} s_coord length() const {return (_end_vt-_begin_vt).length();} pl_unitvec direction() const {return normalized(_end_vt-_begin_vt); } void transform(const pl_transform &tfm) ; void translate(const pl_fixedvec &disp) ; void scale(s_coord fac); protected: pl_vec _begin_vt, _end_vt; }; extern pl_vec placeproject(const pl_fixedvec &vt, const pl_line &l); extern pl_vec dirproject(const pl_fixedvec &vt, const pl_line &l); inline pl_unitvec normal(const pl_edge &e) { return e.supporting_line().normal(); } // zeer voorlopig class design class pl_dotted_line { public: intervals fiv; pl_vec reference_vertex; pl_unitvec dir; pl_unitvec direction() const {return dir;} pl_vec ref_vt() const {return reference_vertex;} protected: }; DeclareReray(pl_edgereray, pl_edge); int is_to_the_left(const pl_fixedvec &, const pl_line &); int is_to_the_right(const pl_fixedvec &, const pl_line &); int is_above(const pl_fixedvec &, const pl_line &); int is_below(const pl_fixedvec &, const pl_line &); typedef unsigned short ushort; DeclareReray(ushortreray, ushort); class pl_pgn: public pl_object { public: pl_pgn():_vertices(),_el(),_ord(),_direction() {} pl_pgn(const pl_vecreray &vl): _vertices(vl) {} int element(int i) const {validate(sortflag); return _el[i];} const pl_vec & velement(int i) const {validate(sortflag); return vertex(_el[i]);} int order(int i) const {validate(sortflag); return _ord[i];} const pl_unitvec & direction(int i) const {validate(directionflag); return _direction[i];} int is_ok() const {validate(simpleflag); return _flags.is_set(is_simplef);} pl_object_type type() const; pl_box bbox() const ; int is_clockwise() const {validate(clockwiseflag); return _flags.is_set(is_clockwisef);} void invert_orientation(); int is_convex() const { validate(convexflag); return _flags.is_set(is_convexf);} int size() const { return _vertices.size(); } const pl_vec & vertex(int i) const {return _vertices[i];} const pl_vec & vertex_mod(int i) const ; const pl_vecreray & all_vertices() const {return _vertices;} void all_vertices(pl_vecreray &result) const {result= _vertices;} pl_edge edge(int i) const ; // edge from vertex(i) to vertex(i+1) pl_edge edge_mod(int i) const ; // edge from vertex(i) to vertex(i+1) void all_edges(pl_edgereray &result) const; s_coord area() const {validate(areaflag); return _area;} void translate(const pl_fixedvec &vec) ; void scale(s_coord); void transform(const pl_transform &); protected: flags16 _flags; pl_vecreray _vertices; ushortreray _el; // als i el[i]==j uvecreray _direction; // direction of edges pl_box _bb; s_coord _area; enum pgnflags{ bbflag = flags16::flag0, sortflag = flags16::flag1, simpleflag = flags16::flag2, clockwiseflag = flags16::flag3, convexflag = flags16::flag4, is_convexf = flags16::flag5, is_clockwisef = flags16::flag6, is_simplef = flags16::flag7, directionflag = flags16::flag8, areaflag = flags16::flag9 }; void validate(short x) const {if (!_flags.is_set(x)) validate_work(x);} void validate_work(short x) const; // casts away const void makebbox(); void compute_area(); void compute_directions(); void sort(); int insertion_check(int, int, int) const; int transition_check(int, int, int) const; int deletion_check(int) const; int check_event(int) const; void check_simple(); void check_clockwise(); void check_convex(); }; typedef pl_pgn pl_polygon; DeclareReray(pl_pgnreray, pl_pgn); typedef pl_pgnreray pl_polygonreray; class pl_disc: public pl_object { public: pl_disc(const pl_fixedvec &vt, s_coord radius) { _center = vt; // assert (radius >= 0) _radius = radius; } pl_disc() {} pl_object_type type() const; pl_box bbox() const; pl_vec center() const { return _center; } s_coord radius() const { return _radius; } s_coord area() const ; void set_center(const pl_fixedvec &vt) { _center = vt; } void set_radius(s_coord radius) { _radius = radius; } void transform(const pl_transform &tfm); void translate(const pl_fixedvec &disp) ; void scale(s_coord fac); void outer_approximation_d(pl_vecreray &result, s_coord epsilon) const; void outer_approximation_n(pl_vecreray &result, int n) const; void inner_approximation_d(pl_vecreray &result, s_coord epsilon) const; void inner_approximation_n(pl_vecreray &result, int n) const; protected: pl_vec _center; s_coord _radius; }; class pl_arc: public pl_object { public: pl_arc(const pl_fixedvec &vt, s_coord radius, pl_angle startangle, pl_angle enclosed_angle) ; pl_arc(const pl_disc &c, pl_angle angle, pl_angle diffangle) ; pl_arc() {} pl_object_type type() const; pl_box bbox() const ; pl_vec center() const { return _disc.center(); } s_coord radius() const { return _disc.radius(); } pl_vec begin_vt() const; pl_vec end_vt() const; pl_vec small_vt() const; pl_vec big_vt() const; pl_angle begin_angle() const { return _startangle; } pl_angle end_angle() const { return _startangle + _angle;} pl_angle enclosed_angle() const { return _angle; } pl_angle small_angle() const; pl_angle big_angle() const; s_coord length() const {return fabs_pp(radius()*_angle);} const pl_disc& supporting_disc() const { return _disc; } void set_center(const pl_fixedvec &vt) { _disc.set_center(vt); } void set_radius(s_coord radius) { _disc.set_radius(radius); } void set_angles(pl_angle angle, pl_angle diffangle) ; void transform(const pl_transform &tfm); void translate(const pl_fixedvec &disp) ; void scale(s_coord fac); void outer_approximation_d(pl_vecreray &result, s_coord epsilon) const; void outer_approximation_n(pl_vecreray &result, int n) const; void inner_approximation_d(pl_vecreray &result, s_coord epsilon) const; void inner_approximation_n(pl_vecreray &result, int n) const; protected: pl_disc _disc; pl_angle _startangle; pl_angle _angle; pl_box _bbox; void make_bbox(); }; // *********** Axis Centered Ellipse : for internal use class pl_ACE { public: pl_ACE() {} pl_ACE(s_coord x, s_coord y) {_x=x; _y=y;} s_coord x() const {return _x;} s_coord y() const {return _y;} protected: s_coord _x, _y; }; extern s_coord wn_clearance(pl_vec &wn, const pl_fixedvec &, const pl_ACE &); extern s_coord wn_clearance(pl_vec &wn, const pl_fixedvec &, const pl_ACE &, s_coord bound); extern s_coord wn_open_clearance(pl_vec &wn,const pl_fixedvec &,const pl_ACE&); extern s_coord wn_open_clearance(pl_vec &wn, const pl_fixedvec &, const pl_ACE &, s_coord bound); extern s_coord open_clearance(const pl_fixedvec &, const pl_ACE &, s_coord); extern s_coord clearance(const pl_fixedvec &, const pl_ACE &, s_coord); // *********** #ifdef FOR_IPE // for portability reasons, Ipe uses the C stdio library with a C++ // interface defined in "ipestream.h". Ipe doesn't use pl_io.C, // but this one function here is used in pl_pgn.C (and in Ipe). inline ostream & operator<<(ostream &fh, const pl_fixedvec &vec) { return (fh << vec.x() << " " << vec.y()); } #else extern ostream & operator<<(ostream &ofile, const pl_angle &); extern istream & operator>>(istream &ifile, pl_angle &); extern ostream & operator<<(ostream &ofile, const pl_fixedvec &vec); extern istream & operator>>(istream &ifile, pl_vec &vec); extern istream & operator>>(istream &ifile, pl_unitvec &uvec); inline ostream & operator<<(ostream &ofile, const pl_point &vt) { return ofile<>(istream &ifile, pl_point &pt); extern ostream & operator<<(ostream &ofile, const pl_edge &edge); extern istream & operator>>(istream &ifile, pl_edge &edge); extern ostream & operator<<(ostream &ofile, const pl_ray &ray); extern istream & operator>>(istream &ifile, pl_ray &ray); extern ostream & operator<<(ostream &ofile, const pl_line &line); extern istream & operator>>(istream &ifile, pl_line &line); extern ostream & operator<<(ostream &ofile, const pl_arc &arc); extern istream & operator>>(istream &ifile, pl_arc &arc); extern ostream & operator<<(ostream &ofile, const pl_box &box); extern istream & operator>>(istream &ifile, pl_box &box); extern ostream & operator<<(ostream &ofile, const pl_polygon &pgn); extern istream & operator>>(istream &ifile, pl_polygon &pgn); extern ostream & operator<<(ostream &ofile, const pl_disc &disc); extern istream & operator>>(istream &ifile, pl_disc &disc); extern ostream & operator<<(ostream &ofile, const pl_vecreray &); extern istream & operator>>(istream &ifile, pl_vecreray &); extern ostream & operator<<(ostream &ofile, const pl_edgereray &); extern istream & operator>>(istream &ifile, pl_edgereray &); extern ostream & operator<<(ostream &ofile, const pl_polygonreray &); extern istream & operator>>(istream &ifile, pl_polygonreray &); #endif // ******** ROUTINES DELIVERING A WITNESS OF AN INTERSECTION ******** // witnesses of intersections between one dimensional objects // edge, ray, line, arc and disc (taken as circle) extern int intersect(pl_vec &, const pl_line &, const pl_line &); extern int intersect(pl_vec &, const pl_ray &, const pl_line &); inline int intersect(pl_vec &wn, const pl_line &l, const pl_ray &r) { return intersect(wn, r, l); } extern int intersect(pl_vec &, const pl_edge &, const pl_line &); inline int intersect(pl_vec &wn, const pl_line &l, const pl_edge &e) { return intersect(wn, e, l); } extern int intersect(pl_vec &, const pl_ray&, const pl_ray&); extern int intersect(pl_vec & ,const pl_edge&, const pl_ray&); inline int intersect(pl_vec &wn, const pl_ray &r, const pl_edge &e) { return intersect(wn, e, r); } extern int intersect(pl_vec &, const pl_edge&, const pl_edge&); extern intervals intersect(const pl_pgn &, const pl_line &); inline intervals intersect(const pl_line &l, const pl_pgn &pgn) { return intersect(pgn, l); } extern intervals intersect(const pl_pgn &, const pl_ray &); inline intervals intersect(const pl_ray &ray, const pl_pgn &pgn) { return intersect(pgn, ray); } extern int intersect(pl_vec &wn1, pl_vec &wn2, const pl_disc &disc, const pl_edge &edge); inline int intersect(pl_vec &wn1, pl_vec &wn2, const pl_edge &edge, const pl_disc &disc) { return intersect(wn1, wn2, disc, edge); } extern int intersect(pl_vec &wn1, pl_vec &wn2, const pl_disc &disc, const pl_ray &ray); inline int intersect(pl_vec &wn1, pl_vec &wn2, const pl_ray &ray, const pl_disc &disc) { return intersect(wn1, wn2, disc, ray); } extern int intersect(pl_vec &wn1, pl_vec &wn2, const pl_disc &disc, const pl_line &line); inline int intersect(pl_vec &wn1, pl_vec &wn2, const pl_line &line, const pl_disc &disc) { return intersect(wn1, wn2, disc, line); } extern int intersect(pl_vec &wn1, pl_vec &wn2, const pl_edge &edge, const pl_arc &arc); inline int intersect(pl_vec &wn1, pl_vec &wn2, const pl_arc &arc, const pl_edge &edge) { return intersect(wn1, wn2, edge, arc); } extern int intersect(pl_vec &wn1, pl_vec &wn2, const pl_ray &ray, const pl_arc &arc); inline int intersect(pl_vec &wn1, pl_vec &wn2, const pl_arc &arc, const pl_ray &ray) { return intersect(wn1, wn2, ray, arc); } extern int intersect(pl_vec &wn1, pl_vec &wn2, const pl_line &line, const pl_arc &arc); inline int intersect(pl_vec &wn1, pl_vec &wn2, const pl_arc &arc, const pl_line &line) { return intersect(wn1, wn2, line, arc); } extern int intersect(pl_vec &wn1, pl_vec &wn2, const pl_disc &disc1, const pl_disc &disc2); extern int intersect(pl_vec &wn1, pl_vec &wn2, const pl_disc &disc, const pl_arc &arc); inline int intersect(pl_vec &wn1, pl_vec &wn2, const pl_arc &arc, const pl_disc &disc) { return intersect(wn1, wn2, disc, arc); } extern int intersect(pl_vec &wn1, pl_vec &wn2, const pl_arc &, const pl_arc &); // ******** INTERSECTION DECISION ROUTINES******** // ****** OBJECT ***** extern int do_cross(const pl_object &, const pl_fixedvec &); extern int do_cross(const pl_object &, const pl_point &); extern int do_cross(const pl_object &, const pl_line &); extern int do_cross(const pl_object &, const pl_ray &); extern int do_cross(const pl_object &, const pl_edge &); extern int do_cross(const pl_object &, const pl_arc &); extern int do_cross(const pl_object &, const pl_box &); extern int do_cross(const pl_object &, const pl_pgn &); extern int do_cross(const pl_object &, const pl_disc &); extern int do_cross(const pl_object &, const pl_object &); extern int do_overlap(const pl_object &, const pl_fixedvec &); extern int do_overlap(const pl_object &, const pl_point &); extern int do_overlap(const pl_object &, const pl_line &); extern int do_overlap(const pl_object &, const pl_ray &); extern int do_overlap(const pl_object &, const pl_edge &); extern int do_overlap(const pl_object &, const pl_arc &); extern int do_overlap(const pl_object &, const pl_box &); extern int do_overlap(const pl_object &, const pl_pgn &); extern int do_overlap(const pl_object &, const pl_disc &); extern int do_overlap(const pl_object &, const pl_object &); // ****** VEC ****** inline int do_cross(const pl_fixedvec &vec, const pl_object &obj) { return do_cross(obj, vec); } inline int do_cross(const pl_fixedvec &vec, const pl_fixedvec &vec2) { if (vec.x()==vec2.x()); return 0; } inline int do_cross(const pl_fixedvec &vec, const pl_box &box) { if (vec.x()==box.xmax()); return 0; } extern int lies_inside(const pl_fixedvec &, const pl_box &); extern int lies_inside(const pl_fixedvec &, const pl_pgn &); extern int lies_inside(const pl_fixedvec &, const pl_disc &); inline do_overlap(const pl_fixedvec &vec, const pl_box &box) { return lies_inside(vec, box); } inline do_overlap(const pl_fixedvec &vec, const pl_pgn &pgn) { return lies_inside(vec, pgn); } inline do_overlap(const pl_fixedvec &vec, const pl_disc &disc) { return lies_inside(vec, disc); } inline do_overlap(const pl_fixedvec &vec, const pl_object &obj) { return do_overlap(obj, vec); } // ****** POINT ****** inline int do_cross(const pl_point &vt, const pl_object &obj) { return do_cross(obj, vt.vec()); } inline int do_cross(const pl_point &vt, const pl_fixedvec &vec2) { if (vt.vec().x()==vec2.x()); return 0; } inline int do_cross(const pl_point &vt, const pl_box &box) { if (vt.vec().x()==box.xmax()); return 0; } inline int lies_inside(const pl_point &pt, const pl_box &box) { return lies_inside(pt.vec(), box); } inline int lies_inside(const pl_point &pt, const pl_pgn &pgn) { return lies_inside(pt.vec(), pgn); } inline int lies_inside(const pl_point &pt, const pl_disc &disc) { return lies_inside(pt.vec(), disc); } // Ipe bug fix: the type was missing in the next few declarations inline int do_overlap(const pl_point &vt, const pl_box &box) { return lies_inside(vt.vec(), box); } inline int do_overlap(const pl_point &vt, const pl_pgn &pgn) { return lies_inside(vt.vec(), pgn); } inline int do_overlap(const pl_point &vt, const pl_disc &disc) { return lies_inside(vt.vec(), disc); } inline int do_overlap(const pl_point &vt, const pl_object &obj) { return do_overlap(obj, vt.vec()); } // ****** EDGE ****** extern int do_intersect(const pl_edge &e1, const pl_edge &e2); extern int do_intersect(const pl_edge &e1, const pl_ray &e2); extern int do_intersect(const pl_edge &e, const pl_line &l); inline int do_intersect(const pl_edge &edge, const pl_arc &arc) { pl_vec dummy1, dummy2; return intersect(dummy1, dummy2, arc, edge); } inline int do_cross(const pl_edge &edge, const pl_fixedvec &vec) { if (edge.begin_vt().x()==vec.x()); return 0; } inline int do_cross(const pl_edge &edge, const pl_point &vt) { if (edge.begin_vt().x()==vt.vec().x()); return 0; } inline int do_cross(const pl_edge &edge1, const pl_edge &edge2) { return do_intersect(edge1, edge2); } inline int do_cross(const pl_edge &edge, const pl_ray &ray) { return do_intersect(edge, ray); } inline int do_cross(const pl_edge &edge, const pl_line &line) { return do_intersect(edge, line); } inline int do_cross(const pl_edge &edge, const pl_arc &arc) { return do_intersect(edge, arc); } extern int do_cross(const pl_edge &, const pl_box &); extern int do_cross(const pl_edge &, const pl_pgn &); extern int do_cross(const pl_edge &, const pl_disc &); inline int do_overlap(const pl_edge &edge, const pl_fixedvec &vec) { if (edge.begin_vt().x()==vec.x()); return 0; } inline int do_overlap(const pl_edge &edge, const pl_point &vt) { if (edge.begin_vt().x()==vt.vec().x()); return 0; } inline int do_overlap(const pl_edge &edge1, const pl_edge &edge2) { return do_intersect(edge1, edge2); } inline int do_overlap(const pl_edge &edge, const pl_ray &ray) { return do_intersect(edge, ray); } inline int do_overlap(const pl_edge &edge, const pl_line &line) { return do_intersect(edge, line); } inline int do_overlap(const pl_edge &edge, const pl_arc &arc) { return do_intersect(edge, arc); } extern int do_overlap(const pl_edge &, const pl_box &); extern int do_overlap(const pl_edge &, const pl_pgn &); extern int do_overlap(const pl_edge &, const pl_disc &); // ****** RAY ****** inline int do_intersect(const pl_ray &ray, const pl_edge &edge) { return do_intersect(edge, ray); } extern int do_intersect(const pl_ray &, const pl_ray &); extern int do_intersect(const pl_ray &, const pl_line &); extern int do_intersect(const pl_ray &ray, const pl_arc &arc); inline int do_cross(const pl_ray &ray, const pl_fixedvec &vec) { if (ray.begin_vt().x()==vec.x()); return 0; } inline int do_cross(const pl_ray &ray, const pl_point &vt) { if (ray.begin_vt().x()==vt.vec().x()); return 0; } inline int do_cross(const pl_ray &ray, const pl_edge &edge) { return do_intersect(ray, edge); } inline int do_cross(const pl_ray &ray1, const pl_ray &ray) { return do_intersect(ray1, ray); } inline int do_cross(const pl_ray &ray, const pl_line &line) { return do_intersect(ray, line); } inline int do_cross(const pl_ray &ray, const pl_arc &arc) { return do_intersect(ray, arc); } extern int do_cross(const pl_ray &, const pl_box &); extern int do_cross(const pl_ray &, const pl_pgn &); extern int do_cross(const pl_ray &, const pl_disc &); inline int do_overlap(const pl_ray &ray, const pl_fixedvec &vec) { if (ray.begin_vt().x()==vec.x()); return 0; } inline int do_overlap(const pl_ray &ray, const pl_point &vt) { if (ray.begin_vt().x()==vt.vec().x()); return 0; } inline int do_overlap(const pl_ray &ray, const pl_edge &edge) { return do_intersect(ray, edge); } inline int do_overlap(const pl_ray &ray1, const pl_ray &ray) { return do_intersect(ray1, ray); } inline int do_overlap(const pl_ray &ray, const pl_line &line) { return do_intersect(ray, line); } inline int do_overlap(const pl_ray &ray, const pl_arc &arc) { return do_intersect(ray, arc); } extern int do_overlap(const pl_ray &, const pl_box &); extern int do_overlap(const pl_ray &, const pl_pgn &); extern int do_overlap(const pl_ray &, const pl_disc &); // ****** LINE ****** inline int do_intersect(const pl_line &line, const pl_edge &edge) { return do_intersect(edge, line); } inline int do_intersect(const pl_line &line, const pl_ray &ray) { return do_intersect(ray, line); } inline int do_intersect(const pl_line &l1, const pl_line &l2) { if (l1.ref_vt().x()==l2.ref_vt().x()); return 1; // pl_vec dummy; // return intersect(dummy, l1, l2); } extern int do_intersect(const pl_line &line, const pl_arc &arc); inline int do_cross(const pl_line &line, const pl_fixedvec &vec) { if (line.ref_vt().x()==vec.x()); return 0; } inline int do_cross(const pl_line &line, const pl_point &vt) { if (line.ref_vt().x()==vt.vec().x()); return 0; } inline int do_cross(const pl_line &line, const pl_edge &edge) { return do_intersect(line, edge); } inline int do_cross(const pl_line &line1, const pl_ray &ray) { return do_intersect(line1, ray); } inline int do_cross(const pl_line &line1, const pl_line &line) { if (line1.ref_vt().x()==line.ref_vt().x()); return 1; } inline int do_cross(const pl_line &line, const pl_arc &arc) { return do_intersect(line, arc); } extern int do_cross(const pl_line &, const pl_box &); extern int do_cross(const pl_line &, const pl_pgn &); extern int do_cross(const pl_line &, const pl_disc &); inline int do_overlap(const pl_line &line, const pl_fixedvec &vec) { if (line.ref_vt().x()==vec.x()); return 0; } inline int do_overlap(const pl_line &line, const pl_point &vt) { if (line.ref_vt().x()==vt.vec().x()); return 0; } inline int do_overlap(const pl_line &line, const pl_edge &edge) { return do_intersect(line, edge); } inline int do_overlap(const pl_line &line1, const pl_ray &ray) { return do_intersect(line1, ray); } inline int do_overlap(const pl_line &line1, const pl_line &line) { if (line1.ref_vt().x()==line.ref_vt().x()); return 1; } inline int do_overlap(const pl_line &line, const pl_arc &arc) { return do_intersect(line, arc); } extern int do_overlap(const pl_line &, const pl_box &); extern int do_overlap(const pl_line &, const pl_pgn &); extern int do_overlap(const pl_line &, const pl_disc &); // ****** ARC ****** inline int do_intersect(const pl_arc &arc, const pl_edge &edge) { pl_vec dummy1, dummy2; return intersect(dummy1, dummy2, arc, edge); } inline int do_intersect(const pl_arc &arc, const pl_ray &ray) { return do_intersect(ray, arc); } inline int do_intersect(const pl_arc &arc, const pl_line &line) { return do_intersect(line, arc); } extern int do_intersect(const pl_arc &, const pl_arc &); inline int do_cross(const pl_arc &arc, const pl_fixedvec &vec) { if (arc.begin_vt().x()==vec.x()); return 0; } inline int do_cross(const pl_arc &arc, const pl_point &vt) { if (arc.begin_vt().x()==vt.vec().x()); return 0; } inline int do_cross(const pl_arc &arc, const pl_edge &edge) { return do_intersect(arc, edge); } inline int do_cross(const pl_arc &arc1, const pl_ray &ray) { return do_intersect(arc1, ray); } inline int do_cross(const pl_arc &arc, const pl_line &line) { if (arc.begin_vt().x()==line.ref_vt().x()); return 1; } inline int do_cross(const pl_arc &arc1, const pl_arc &arc) { return do_intersect(arc1, arc); } extern int do_cross(const pl_arc &, const pl_box &); extern int do_cross(const pl_arc &, const pl_pgn &); extern int do_cross(const pl_arc &arc, const pl_disc &disc); inline int do_overlap(const pl_arc &arc, const pl_fixedvec &vec) { if (arc.begin_vt().x()==vec.x()); return 0; } inline int do_overlap(const pl_arc &arc, const pl_point &vt) { if (arc.begin_vt().x()==vt.vec().x()); return 0; } inline int do_overlap(const pl_arc &arc, const pl_edge &edge) { return do_intersect(arc, edge); } inline int do_overlap(const pl_arc &arc1, const pl_ray &ray) { return do_intersect(arc1, ray); } inline int do_overlap(const pl_arc &arc, const pl_line &line) { if (arc.begin_vt().x()==line.ref_vt().x()); return 1; } inline int do_overlap(const pl_arc &arc1, const pl_arc &arc) { return do_intersect(arc1, arc); } extern int do_overlap(const pl_arc &, const pl_box &); extern int do_overlap(const pl_arc &, const pl_pgn &); extern int do_overlap(const pl_arc &, const pl_disc &); // ****** BOX ****** inline int do_cross(const pl_box &box, const pl_fixedvec &vec) { if (vec.x()==box.xmax()); return 0;} inline int do_cross(const pl_box &box, const pl_point &vt) { if (vt.vec().x()==box.xmax()); return 0;} inline int do_cross( const pl_box &box, const pl_edge &edge) { return do_cross(edge, box); } inline int do_cross(const pl_box &box, const pl_ray &ray) { return do_cross(ray, box); } inline int do_cross(const pl_box &box, const pl_line &line) { return do_cross(line, box); } inline int do_cross(const pl_box &box, const pl_arc &arc) { return do_cross(arc, box); } extern int do_cross(const pl_box &, const pl_box &); extern int do_cross(const pl_box &, const pl_pgn &); extern int do_cross(const pl_box &, const pl_disc &); inline int do_overlap(const pl_box &box, const pl_fixedvec &vec) { return lies_inside(vec, box);} inline int do_overlap(const pl_box &box, const pl_point &vt) { return lies_inside(vt, box);} inline int do_overlap( const pl_box &box, const pl_edge &edge) { return do_overlap(edge, box); } inline int do_overlap(const pl_box &box, const pl_ray &ray) { return do_overlap(ray, box); } inline int do_overlap(const pl_box &box, const pl_line &line) { return do_overlap(line, box); } inline int do_overlap(const pl_box &box, const pl_arc &arc) { return do_overlap(arc, box); } extern int do_overlap(const pl_box & , const pl_box &); extern int do_overlap(const pl_box & , const pl_pgn & ); extern int do_overlap(const pl_box & , const pl_disc & ); // ****** POLYGON ****** inline int do_cross(const pl_pgn &pgn, const pl_fixedvec &vec) { if (vec.x()==0||pgn.size()); return 0;} // dummy conditional inline int do_cross(const pl_pgn &pgn, const pl_point &vt) { if (vt.vec().x()==0||pgn.size()); return 0;} // dummy conditional inline int do_cross( const pl_pgn &pgn, const pl_edge &edge) { return do_cross(edge, pgn); } inline int do_cross(const pl_pgn &pgn, const pl_ray &ray) { return do_cross(ray, pgn); } inline int do_cross(const pl_pgn &pgn, const pl_line &line) { return do_cross(line, pgn); } inline int do_cross(const pl_pgn &pgn, const pl_arc &arc) { return do_cross(arc, pgn); } inline int do_cross(const pl_pgn &pgn, const pl_box &box) { return do_cross(box, pgn); } extern int do_cross(const pl_pgn &, const pl_pgn &); extern int do_cross(const pl_pgn &, const pl_disc &); inline int do_overlap(const pl_pgn &pgn, const pl_fixedvec &vec) { return lies_inside(vec, pgn);} inline int do_overlap(const pl_pgn &pgn, const pl_point &vt) { return lies_inside(vt, pgn);} inline int do_overlap( const pl_pgn &pgn, const pl_edge &edge) { return do_overlap(edge, pgn); } inline int do_overlap(const pl_pgn &pgn, const pl_ray &ray) { return do_overlap(ray, pgn); } inline int do_overlap(const pl_pgn &pgn, const pl_line &line) { return do_overlap(line, pgn); } inline int do_overlap(const pl_pgn &pgn, const pl_arc &arc) { return do_overlap(arc, pgn); } inline int do_overlap(const pl_pgn &pgn, const pl_box &box) { return do_overlap(box, pgn); } extern int do_overlap(const pl_pgn & , const pl_pgn & ); extern int do_overlap(const pl_pgn & , const pl_disc & ); // ****** DISC ****** inline int do_cross(const pl_disc &disc, const pl_fixedvec &vec) { if (vec.x()==disc.center().x()); return 0;} // dummy conditional inline int do_cross(const pl_disc &disc, const pl_point &vt) { if (vt.vec().x()==disc.center().x()); return 0;} // dummy conditional inline int do_cross( const pl_disc &disc, const pl_edge &edge) { return do_cross(edge, disc); } inline int do_cross(const pl_disc &disc, const pl_ray &ray) { return do_cross(ray, disc); } inline int do_cross(const pl_disc &disc, const pl_line &line) { return do_cross(line, disc); } inline int do_cross(const pl_disc &disc, const pl_arc &arc) { return do_cross(arc, disc); } inline int do_cross(const pl_disc &disc, const pl_box &box) { return do_cross(box, disc); } inline int do_cross(const pl_disc &disc, const pl_pgn &pgn) { return do_cross(pgn, disc); } extern int do_cross(const pl_disc &, const pl_disc &); inline int do_overlap(const pl_disc &disc, const pl_fixedvec &vec) { return lies_inside(vec, disc);} inline int do_overlap(const pl_disc &disc, const pl_point &vt) { return lies_inside(vt, disc);} inline int do_overlap( const pl_disc &disc, const pl_edge &edge) { return do_overlap(edge, disc); } inline int do_overlap(const pl_disc &disc, const pl_ray &ray) { return do_overlap(ray, disc); } inline int do_overlap(const pl_disc &disc, const pl_line &line) { return do_overlap(line, disc); } inline int do_overlap(const pl_disc &disc, const pl_arc &arc) { return do_overlap(arc, disc); } inline int do_overlap(const pl_disc &disc, const pl_box &box) { return do_overlap(box, disc); } inline int do_overlap(const pl_disc &disc, const pl_pgn &pgn) { return do_overlap(pgn, disc); } extern int do_overlap(const pl_disc & , const pl_disc & ); // ******** OTHER ROUTINES (internal use) ******** extern int pl__ontbind2(s_coord fac[], const pl_vec &e0, const pl_vec &e1, const pl_vec &v); inline s_coord sqclearance(const pl_fixedvec &vt1, const pl_fixedvec & vt2) { return (vt2-vt1).sqlength(); } // checks the clearance between a fixedvec and a box extern int certain_clearance(const pl_fixedvec &, const pl_boundingbox &, s_coord); // checks the square of the clearance between a fixedvec and a box extern int certain_sqclearance(const pl_fixedvec &, const pl_boundingbox &, s_coord sqbound); // checks the square of clearance between two boxes extern int certain_sqclearance(const pl_boundingbox &, const pl_boundingbox &, s_coord sqbound); // returns true if clearance between two boxes is certainly bigger than bound. // if false is returned, the clearance may still be bigger extern int certain_clearance(const pl_boundingbox &, const pl_boundingbox &, s_coord bound); extern s_coord sqclearance(const pl_fixedvec &, const pl_line &); extern s_coord sqclearance(const pl_fixedvec &, const pl_edge &); // ***** // ****** VEC ****** inline s_coord clearance(const pl_fixedvec &vt1, const pl_fixedvec & vt2) { return (vt2-vt1).length(); } extern s_coord clearance(const pl_fixedvec &, const pl_fixedvec &, s_coord ); inline s_coord clearance(const pl_fixedvec &vt1, const pl_point & vt2) { return (vt2.vec()-vt1).length(); } inline s_coord clearance(const pl_fixedvec &pt1, const pl_point &pt2, s_coord bound) { return clearance(pt1, pt2.vec(), bound); } extern s_coord clearance(const pl_fixedvec &, const pl_edge &); extern s_coord clearance(const pl_fixedvec &, const pl_edge &, s_coord bound); extern s_coord clearance(const pl_fixedvec &, const pl_ray &); extern s_coord clearance(const pl_fixedvec &, const pl_ray &, s_coord bound); extern s_coord clearance(const pl_fixedvec &, const pl_line &); extern s_coord clearance(const pl_fixedvec &, const pl_line &, s_coord bound); extern s_coord clearance(const pl_fixedvec &, const pl_arc &); extern s_coord clearance(const pl_fixedvec &, const pl_arc &, s_coord bound); extern s_coord clearance(const pl_fixedvec &, const pl_box &); extern s_coord clearance(const pl_fixedvec &, const pl_box &, s_coord bound); extern s_coord clearance(const pl_fixedvec &, const pl_pgn &); extern s_coord clearance(const pl_fixedvec &, const pl_pgn &, s_coord bound); extern s_coord clearance(const pl_fixedvec &, const pl_disc &); extern s_coord clearance(const pl_fixedvec &, const pl_disc &, s_coord bound); extern s_coord clearance(const pl_fixedvec &, const pl_object &); extern s_coord clearance(const pl_fixedvec &, const pl_object &, s_coord bound); // ****** POINT ****** inline s_coord clearance(const pl_point &vt1, const pl_fixedvec & vt2) { return (vt2-vt1.vec()).length(); } inline s_coord clearance(const pl_point &pt1, const pl_fixedvec &pt2, s_coord bound) { return clearance(pt1.vec(), pt2, bound); } inline s_coord clearance(const pl_point &vt1, const pl_point & vt2) { return (vt2.vec()-vt1.vec()).length(); } inline s_coord clearance(const pl_point &pt1, const pl_point &pt2, s_coord bound) { return clearance(pt1.vec(), pt2.vec(), bound); } inline s_coord clearance(const pl_point &pt, const pl_edge &edge) { return clearance(pt.vec(), edge); } inline s_coord clearance(const pl_point &pt, const pl_edge &edge, s_coord bound) { return clearance(pt.vec(), edge, bound); } inline s_coord clearance(const pl_point &pt, const pl_ray &ray) { return clearance(pt.vec(), ray); } inline s_coord clearance(const pl_point &pt, const pl_ray &ray, s_coord bound) { return clearance(pt.vec(), ray, bound); } inline s_coord clearance(const pl_point &pt, const pl_line &line) { return clearance(pt.vec(), line); } inline s_coord clearance(const pl_point &pt, const pl_line &line, s_coord bound) { return clearance(pt.vec(), line, bound); } inline s_coord clearance(const pl_point &pt, const pl_arc &arc) { return clearance(pt.vec(), arc); } inline s_coord clearance(const pl_point &pt, const pl_arc &arc, s_coord bound) { return clearance(pt.vec(), arc, bound); } inline s_coord clearance(const pl_point &pt, const pl_box &box) { return clearance(pt.vec(), box); } inline s_coord clearance(const pl_point &pt, const pl_box &box, s_coord bound) { return clearance(pt.vec(), box, bound); } inline s_coord clearance(const pl_point &pt, const pl_pgn &pgn) { return clearance(pt.vec(), pgn); } inline s_coord clearance(const pl_point &pt, const pl_pgn &pgn, s_coord bound) { return clearance(pt.vec(), pgn, bound); } inline s_coord clearance(const pl_point &pt, const pl_disc &disc) { return clearance(pt.vec(), disc); } inline s_coord clearance(const pl_point &pt, const pl_disc &disc, s_coord bound) { return clearance(pt.vec(), disc, bound); } inline s_coord clearance(const pl_point &pt, const pl_object &obj) { return clearance(pt.vec(), obj); } inline s_coord clearance(const pl_point &pt, const pl_object &obj, s_coord bound) { return clearance(pt.vec(), obj, bound); } // ****** EDGE ****** inline s_coord clearance(const pl_edge &edge, const pl_fixedvec &vt) { return clearance(vt, edge); } inline s_coord clearance(const pl_edge &edge, const pl_fixedvec &vt, s_coord bound) { return clearance(vt, edge, bound); } inline s_coord clearance(const pl_edge &edge, const pl_point &vt) { return clearance(vt.vec(), edge); } inline s_coord clearance(const pl_edge &edge, const pl_point &vt, s_coord bound) { return clearance(vt.vec(), edge, bound); } extern s_coord clearance(const pl_edge &, const pl_edge &); extern s_coord clearance(const pl_edge &, const pl_edge &, s_coord bound); extern s_coord clearance(const pl_edge &, const pl_ray &); extern s_coord clearance(const pl_edge &, const pl_ray &, s_coord bound); extern s_coord clearance(const pl_edge &, const pl_line &); extern s_coord clearance(const pl_edge &, const pl_line &, s_coord bound); extern s_coord clearance(const pl_edge &, const pl_arc &); extern s_coord clearance(const pl_edge &, const pl_arc &, s_coord bound); extern s_coord clearance(const pl_edge &, const pl_box &); extern s_coord clearance(const pl_edge &, const pl_box &, s_coord bound); extern s_coord clearance(const pl_edge &, const pl_pgn &); extern s_coord clearance(const pl_edge &, const pl_pgn &, s_coord bound); extern s_coord clearance(const pl_edge &, const pl_disc &); extern s_coord clearance(const pl_edge &, const pl_disc &, s_coord bound); extern s_coord clearance(const pl_edge &, const pl_object &); extern s_coord clearance(const pl_edge &, const pl_object &, s_coord bound); // ****** RAY ****** inline s_coord clearance(const pl_ray &ray, const pl_fixedvec &vt) { return clearance(vt, ray); } inline s_coord clearance(const pl_ray &ray, const pl_fixedvec &vt, s_coord bound) { return clearance(vt, ray, bound); } inline s_coord clearance(const pl_ray &ray, const pl_point &vt) { return clearance(vt.vec(), ray); } inline s_coord clearance(const pl_ray &ray, const pl_point &vt, s_coord bound) { return clearance(vt.vec(), ray, bound); } inline s_coord clearance(const pl_ray &r, const pl_edge &e) { return clearance(e,r); } inline s_coord clearance(const pl_ray &r, const pl_edge &e, s_coord bound) { return clearance(e,r, bound); } extern s_coord clearance(const pl_ray &, const pl_ray &); extern s_coord clearance(const pl_ray &, const pl_ray &, s_coord bound); extern s_coord clearance(const pl_ray &, const pl_line &); extern s_coord clearance(const pl_ray &, const pl_line &, s_coord bound); extern s_coord clearance(const pl_ray &, const pl_arc &); extern s_coord clearance(const pl_ray &, const pl_arc &, s_coord bound); extern s_coord clearance(const pl_ray &, const pl_box &); extern s_coord clearance(const pl_ray &, const pl_box &, s_coord bound); extern s_coord clearance(const pl_ray &, const pl_pgn &); extern s_coord clearance(const pl_ray &, const pl_pgn &, s_coord bound); extern s_coord clearance(const pl_ray &, const pl_disc &); extern s_coord clearance(const pl_ray &, const pl_disc &, s_coord bound); extern s_coord clearance(const pl_ray &, const pl_object &); extern s_coord clearance(const pl_ray &, const pl_object &, s_coord bound); // ****** LINE ****** inline s_coord clearance(const pl_line &l, const pl_fixedvec &vt) { return clearance(vt, l);} inline s_coord clearance(const pl_line &l, const pl_fixedvec &vt, s_coord bound) { return clearance(vt, l, bound);} inline s_coord clearance(const pl_line &l, const pl_point &vt) { return clearance(vt.vec(), l);} inline s_coord clearance(const pl_line &l, const pl_point &vt, s_coord bound) { return clearance(vt.vec(), l, bound);} inline s_coord clearance(const pl_line &l, const pl_edge &e) { return clearance(e,l); } inline s_coord clearance(const pl_line &l, const pl_edge &e, s_coord bound) { return clearance(e,l, bound); } inline s_coord clearance(const pl_line &l, const pl_ray &r) { return clearance(r,l); } inline s_coord clearance(const pl_line &l, const pl_ray &r, s_coord bound) { return clearance(r,l, bound); } extern s_coord clearance(const pl_line &, const pl_arc &); extern s_coord clearance(const pl_line &, const pl_arc &, s_coord bound); extern s_coord clearance(const pl_line &line, const pl_boundingbox &bb); extern s_coord clearance(const pl_line &, const pl_boundingbox &, s_coord bound); extern s_coord clearance(const pl_line &, const pl_pgn &); extern s_coord clearance(const pl_line &, const pl_pgn &, s_coord bound); extern s_coord clearance(const pl_line &, const pl_disc &); extern s_coord clearance(const pl_line &, const pl_disc &, s_coord bound); extern s_coord clearance(const pl_line &, const pl_object &); extern s_coord clearance(const pl_line &, const pl_object &, s_coord bound); // ****** ARC ****** inline s_coord clearance(const pl_arc &c, const pl_fixedvec &vt) { return clearance(vt, c); } inline s_coord clearance(const pl_arc &c, const pl_fixedvec &vt, s_coord bound) { return clearance(vt, c, bound); } inline s_coord clearance(const pl_arc &c, const pl_point &vt) { return clearance(vt.vec(), c); } inline s_coord clearance(const pl_arc &c, const pl_point &vt, s_coord bound) { return clearance(vt.vec(), c, bound); } inline s_coord clearance(const pl_arc &c, const pl_edge &edge) { return clearance(edge, c); } inline s_coord clearance(const pl_arc &c, const pl_edge &edge, s_coord bound) { return clearance(edge, c, bound); } inline s_coord clearance(const pl_arc &c, const pl_ray &ray) { return clearance(ray, c); } inline s_coord clearance(const pl_arc &c, const pl_ray &ray, s_coord bound) { return clearance(ray, c, bound); } inline s_coord clearance(const pl_arc &c, const pl_line &line) { return clearance(line, c); } inline s_coord clearance(const pl_arc &c, const pl_line &line, s_coord bound) { return clearance(line, c, bound); } extern s_coord clearance(const pl_arc &, const pl_arc &); extern s_coord clearance(const pl_arc &, const pl_arc &, s_coord bound); extern s_coord clearance(const pl_arc &, const pl_box &); extern s_coord clearance(const pl_arc &, const pl_box &, s_coord bound); extern s_coord clearance(const pl_arc &, const pl_pgn &); extern s_coord clearance(const pl_arc &, const pl_pgn &, s_coord bound); extern s_coord clearance(const pl_arc &, const pl_disc &); extern s_coord clearance(const pl_arc &, const pl_disc &, s_coord bound); extern s_coord open_clearance(const pl_arc &, const pl_disc &); extern s_coord open_clearance(const pl_arc &, const pl_disc &, s_coord bound); extern s_coord clearance(const pl_arc &, const pl_object &); extern s_coord clearance(const pl_arc &, const pl_object &, s_coord bound); // ****** BOX ****** inline s_coord clearance(const pl_box &box, const pl_fixedvec &vt) { return clearance(vt, box); } inline s_coord clearance(const pl_box &box, const pl_fixedvec &vt, s_coord bound) { return clearance(vt, box, bound); } inline s_coord clearance(const pl_box &box, const pl_point &vt) { return clearance(vt.vec(), box); } inline s_coord clearance(const pl_box &box, const pl_point &vt, s_coord bound) { return clearance(vt.vec(), box, bound); } inline s_coord clearance(const pl_box &bb, const pl_edge &edge) { return clearance(edge, bb); } inline s_coord clearance(const pl_box &bb, const pl_edge &edge, s_coord bound) { return clearance(edge, bb, bound); } inline s_coord clearance(const pl_box &bb, const pl_ray &ray) { return clearance(ray, bb); } inline s_coord clearance(const pl_box &bb, const pl_ray &ray, s_coord bound) { return clearance(ray, bb, bound); } inline s_coord clearance(const pl_box &bb, const pl_line &line) { return clearance(line, bb); } inline s_coord clearance(const pl_box &bb, const pl_line &line, s_coord bound) { return clearance(line, bb, bound); } inline s_coord clearance(const pl_box &bb, const pl_arc &arc) { return clearance(arc, bb); } inline s_coord clearance(const pl_box &bb, const pl_arc &arc, s_coord bound) { return clearance(arc, bb, bound); } extern s_coord clearance(const pl_box &, const pl_box &); extern s_coord clearance(const pl_box &, const pl_box &, s_coord bound); extern s_coord clearance(const pl_box &, const pl_pgn &); extern s_coord clearance(const pl_box &, const pl_pgn &, s_coord bound); extern s_coord clearance(const pl_box &, const pl_disc &); extern s_coord clearance(const pl_box &, const pl_disc &, s_coord bound); extern s_coord clearance(const pl_box &, const pl_object &); extern s_coord clearance(const pl_box &, const pl_object &, s_coord bound); // ****** POLYGON ****** inline s_coord clearance(const pl_pgn &pgn, const pl_fixedvec &vt) {return clearance(vt, pgn); } inline s_coord clearance(const pl_pgn &pgn, const pl_fixedvec &vt, s_coord bound) {return clearance(vt, pgn, bound); } inline s_coord clearance(const pl_pgn &pgn, const pl_point &vt) {return clearance(vt.vec(), pgn); } inline s_coord clearance(const pl_pgn &pgn, const pl_point &vt, s_coord bound) {return clearance(vt.vec(), pgn, bound); } inline s_coord clearance(const pl_pgn &pgn, const pl_edge &edge) { return clearance(edge, pgn); } inline s_coord clearance(const pl_pgn &pgn, const pl_edge &edge, s_coord bound) { return clearance(edge, pgn, bound); } inline s_coord clearance(const pl_pgn &pgn, const pl_ray &ray) { return clearance(ray, pgn); } inline s_coord clearance(const pl_pgn &pgn, const pl_ray &ray, s_coord bound) { return clearance(ray, pgn, bound); } inline s_coord clearance(const pl_pgn &pgn, const pl_line &line) { return clearance(line, pgn); } inline s_coord clearance(const pl_pgn &pgn, const pl_line &line, s_coord bound) { return clearance(line, pgn, bound); } inline s_coord clearance(const pl_pgn &pgn, const pl_arc &arc) { return clearance(arc, pgn); } inline s_coord clearance(const pl_pgn &pgn, const pl_arc &arc, s_coord bound) { return clearance(arc, pgn, bound); } inline s_coord clearance(const pl_pgn &pgn, const pl_box &box) { return clearance(box, pgn); } inline s_coord clearance(const pl_pgn &pgn, const pl_box &box, s_coord bound) { return clearance(box, pgn, bound); } extern s_coord clearance(const pl_pgn &, const pl_pgn &); extern s_coord clearance(const pl_pgn &, const pl_pgn &, s_coord bound); extern s_coord open_clearance(const pl_pgn &pgn1, const pl_pgn &pgn2); extern s_coord open_clearance(const pl_pgn &pgn1, const pl_pgn &pgn2, s_coord bound); extern s_coord clearance(const pl_pgn &, const pl_disc &); extern s_coord clearance(const pl_pgn &, const pl_disc &, s_coord bound); extern s_coord clearance(const pl_pgn &, const pl_object &); extern s_coord clearance(const pl_pgn &, const pl_object &, s_coord bound); // ****** DISC ****** inline s_coord clearance(const pl_disc &c, const pl_fixedvec &vt) { return clearance(vt, c); } inline s_coord clearance(const pl_disc &c, const pl_fixedvec &vt, s_coord bound) { return clearance(vt, c, bound); } inline s_coord clearance(const pl_disc &c, const pl_point &vt) { return clearance(vt.vec(), c); } inline s_coord clearance(const pl_disc &c, const pl_point &vt, s_coord bound) { return clearance(vt.vec(), c, bound); } inline s_coord clearance(const pl_disc &c, const pl_edge &edge) { return clearance(edge, c); } inline s_coord clearance(const pl_disc &c, const pl_edge &edge, s_coord bound) { return clearance(edge, c, bound); } inline s_coord clearance(const pl_disc &c, const pl_ray &ray) { return clearance(ray, c); } inline s_coord clearance(const pl_disc &c, const pl_ray &ray, s_coord bound) { return clearance(ray, c, bound); } inline s_coord clearance(const pl_disc &c, const pl_line &line) { return clearance(line, c); } inline s_coord clearance(const pl_disc &c, const pl_line &line, s_coord bound) { return clearance(line, c, bound); } inline s_coord clearance(const pl_disc &disc, const pl_arc &arc) { return clearance(arc, disc); } inline s_coord clearance(const pl_disc &disc, const pl_arc &arc, s_coord bound) { return clearance(arc, disc, bound); } inline s_coord open_clearance(const pl_disc &disc, const pl_arc &arc) { return open_clearance(arc, disc); } inline s_coord open_clearance(const pl_disc &disc, const pl_arc &arc, s_coord bound) { return open_clearance(arc, disc, bound); } inline s_coord clearance(const pl_disc &c, const pl_box &box) { return clearance(box, c); } inline s_coord clearance(const pl_disc &c, const pl_box &box, s_coord bound) { return clearance(box, c, bound); } inline s_coord clearance(const pl_disc &c, const pl_pgn &pgn) { return clearance(pgn, c); } inline s_coord clearance(const pl_disc &c, const pl_pgn &pgn, s_coord bound) { return clearance(pgn, c, bound); } extern s_coord clearance(const pl_disc &, const pl_disc &); extern s_coord clearance(const pl_disc &, const pl_disc &, s_coord bound); extern s_coord clearance(const pl_disc &, const pl_object &); extern s_coord clearance(const pl_disc &, const pl_object &, s_coord bound); // ****** OBJECT ****** inline s_coord clearance(const pl_object &c, const pl_fixedvec &vt) { return clearance(vt, c); } inline s_coord clearance(const pl_object &c, const pl_fixedvec &vt, s_coord bound) { return clearance(vt, c, bound); } inline s_coord clearance(const pl_object &c, const pl_point &vt) { return clearance(vt.vec(), c); } inline s_coord clearance(const pl_object &c, const pl_point &vt, s_coord bound) { return clearance(vt.vec(), c, bound); } inline s_coord clearance(const pl_object &c, const pl_edge &edge) { return clearance(edge, c); } inline s_coord clearance(const pl_object &c, const pl_edge &edge, s_coord bound) { return clearance(edge, c, bound); } inline s_coord clearance(const pl_object &c, const pl_ray &ray) { return clearance(ray, c); } inline s_coord clearance(const pl_object &c, const pl_ray &ray, s_coord bound) { return clearance(ray, c, bound); } inline s_coord clearance(const pl_object &c, const pl_line &line) { return clearance(line, c); } inline s_coord clearance(const pl_object &c, const pl_line &line, s_coord bound) { return clearance(line, c, bound); } inline s_coord clearance(const pl_object &disc, const pl_arc &arc) { return clearance(arc, disc); } inline s_coord clearance(const pl_object &disc, const pl_arc &arc, s_coord bound) { return clearance(arc, disc, bound); } inline s_coord clearance(const pl_object &c, const pl_box &box) { return clearance(box, c); } inline s_coord clearance(const pl_object &c, const pl_box &box, s_coord bound) { return clearance(box, c, bound); } inline s_coord clearance(const pl_object &c, const pl_pgn &pgn) { return clearance(pgn, c); } inline s_coord clearance(const pl_object &c, const pl_pgn &pgn, s_coord bound) { return clearance(pgn, c, bound); } inline s_coord clearance(const pl_object &c, const pl_disc &disc) { return clearance(disc, c); } inline s_coord clearance(const pl_object &c, const pl_disc &disc, s_coord bound) { return clearance(disc, c, bound); } extern s_coord clearance(const pl_object &, const pl_object &); extern s_coord clearance(const pl_object &, const pl_object &, s_coord bound); // ****** OTHERS ****** extern s_coord clearance(const pl_dotted_line &, const pl_dotted_line &); // *** extern s_coord sqclearance(const pl_pgn &, const pl_pgn &, s_coord sqbound); const int PL_COLORCOUNT = 256; extern void pl_color_components(int &red, int &green, int &blue, int col); class pl_drawarea { public: enum vertexshapes {DOT=0, CROSS=1, SQUARE=2, BOX=3}; enum areafills {NOFILL=0, FILL=1, OUTLINE=2, FILLOUT=3}; virtual ~pl_drawarea(); virtual void pageready()=0; virtual void clear()=0; virtual void draw(const pl_fixedvec &)=0; void draw(const pl_point &); virtual void draw(const pl_edge &)=0; void draw(const pl_ray &); void draw(const pl_line &); virtual void draw(const pl_arc &)=0; void draw(const pl_box &); virtual void draw(const pl_polygon &)=0; virtual void draw(const pl_disc &)=0; void draw(const pl_object &); virtual void draw_text(const pl_fixedvec&, const char*); void set_viewingarea(float x, float y, float xsize, float ysize); void set_viewingarea(float x, float y, float size); void get_viewingarea(float &x, float &y, float &xsize, float &ysize); int set_backcol(int c); int set_textcol(int c); int set_linecol(int c); int set_areacol(int c); int set_areafill(int); int set_vertexshape(int); float set_vertexsize(float); float set_textsize(float); protected: int _backcol; int _linecol; int _areacol; int _textcol; int _areafill; int _vertexshape; float _vertexsize; float _viewing_x; float _viewing_y; float _viewing_xsize; float _viewing_ysize; int _viewing_changed; float _textsize; void init_values(); }; class pl_psfile: public pl_drawarea { public: pl_psfile(ostream &os) ; pl_psfile(ostream &os, int xoffset, int yoffset, int xsize, int ysize) ; ~pl_psfile(); void pageready(); void clear(); void draw(const pl_fixedvec &); void draw(const pl_edge &); void draw(const pl_ray &ray) { pl_drawarea::draw(ray); } void draw(const pl_line &line) { pl_drawarea::draw(line); } void draw(const pl_arc &); void draw(const pl_box &box) { pl_drawarea::draw(box); } void draw(const pl_polygon &); void draw(const pl_disc &); void draw_text(const pl_fixedvec&, const char*) ; protected: void ps_init(); void page_init(); void setcol(int col); ostream &out; int _newpage; // 1 if page is not initialised, 0 otherwise. int _image_xsize; int _image_ysize; int _x_offset; int _y_offset; int _pagenumber; char _marked[PL_COLORCOUNT]; }; //extern void pl_draw(const pl_fixedvec &vt, int how, s_coord radius); //extern void pl_draw(const pl_edge &e); extern void pl_draw(const pl_polygon &pgn, int how); // 0:outline; 1:inside; class pl_glwindow: public pl_drawarea { public: pl_glwindow() ; pl_glwindow(int dx, int dy) ; pl_glwindow(int x, int y, int dx, int dy) ; ~pl_glwindow(); int set_directshow(int); void pageready(); void clear(); void hide(); void draw(const pl_fixedvec &); void draw(const pl_edge &); void draw(const pl_ray &ray) { pl_drawarea::draw(ray); } void draw(const pl_line &line) { pl_drawarea::draw(line); } void draw(const pl_arc &); void draw(const pl_box &box) { pl_drawarea::draw(box); } void draw(const pl_polygon &); void draw(const pl_disc &); void draw_text(const pl_fixedvec&, const char*) ; long identifier() const ; pl_vec get_mouseposition() ; int get_mousestatus(int) ; void set_name(const char *name) ; protected: long winid; int _ds; int _background_dirty; long _winx, _winy, _windx, _windy; char *_name; void win_init(); class active_win { public: active_win(long winid) ; ~active_win(); protected: long _keepwin; long _curwin; }; }; class pl_ipefile: public pl_drawarea { public: pl_ipefile(ostream &os) ; ~pl_ipefile(); void pageready(); void clear(); void draw(const pl_fixedvec &); void draw(const pl_edge &); void draw(const pl_ray &ray) { pl_drawarea::draw(ray); } void draw(const pl_line &line) { pl_drawarea::draw(line); } void draw(const pl_arc &); void draw(const pl_box &box) { pl_drawarea::draw(box); } void draw(const pl_polygon &); void draw(const pl_disc &); void draw_text(const pl_fixedvec&, const char*) ; protected: void ipe_init(); void page_init(); pl_vec to_ipe_coord(const pl_fixedvec &vt) const; s_coord to_ipe_size(s_coord) const; pl_box viewing_box() const; ostream &out; int _newpage; // 1 if page is not initialised, 0 otherwise. }; class pl_glsubwin: public pl_drawarea { public: pl_glsubwin() ; pl_glsubwin(int x, int y, int dx, int dy) ; ~pl_glsubwin(); void pageready(); void clear(); void draw(const pl_fixedvec &); void draw(const pl_edge &); void draw(const pl_ray &ray) { pl_drawarea::draw(ray); } void draw(const pl_line &line) { pl_drawarea::draw(line); } void draw(const pl_arc &); void draw(const pl_box &box) { pl_drawarea::draw(box); } void draw(const pl_polygon &); void draw(const pl_disc &); void draw_text(const pl_fixedvec&, const char*) ; void set_renderarea(int x, int y, int dx, int dy) ; void set_colorfunc(void (*cf)(int) ) {_colorfunc = cf; } protected: int _cleanpage; short _winx, _winy, _windx, _windy; void (*_colorfunc) (int) ; float _savemat[4][4]; long _prevmode; void init_page(); }; extern void pl_use_colormap(int col); extern void pl_use_rgbcolor(int col); extern void pl_use_autocolor(int col); #endif