home *** CD-ROM | disk | FTP | other *** search
- //========================================================================
- //
- // poly.h
- //
- // Copyright 1999 Emmanuel Lesueur
- //
- // A basic polygon manipulation package. This is experimental.
- // There are probably much better algorythms...
- // There is plenty of room for optimizations.
- //
- //========================================================================
-
- #ifndef POLY_H
-
- #ifdef __GNUC__
- #pragma interface
- #endif
-
- static const double epsilon=1e-6;
-
-
- #ifdef __SASC
- inline void* operator new (size_t,void* p) { return p; }
- # ifndef throw
- # include <stdio.h>
- # define throw(x) {printf("Exception: %s\n",(x)); exit(EXIT_FAILURE);}
- # define nothrow
- # define rethrow
- # define try
- # define catch(x) if(0)
- # endif
- #else
- # define nothrow throw()
- # define rethrow throw
- static inline void* operator new (size_t,void* p) { return p; }
- #endif
-
- #if MWDEBUG
- # include "sc:extras/memlib/memwatch.h"
- extern char* memdbg_file;
- extern int memdbg_line;
- # define new (memdbg_file=__FILE__,memdbg_line=__LINE__),new
- # define delete (memdbg_file=__FILE__,memdbg_line=__LINE__),delete
- #endif
-
- #include <math.h>
- #if defined(__SASC) && !defined(__PPC__)
- # include <m68881.h>
- #endif
-
- template<class T> inline int compare(T x,T y) {
- return x<y?-1:(x==y?0:1);
- }
-
- inline int compare(double x,double y) {
- return fabs(x-y)<=epsilon*(fabs(x)+fabs(y))?0:(x<y?-1:1);
- }
- inline int compare(float x,float y) {
- return fabs(x-y)<=epsilon*(fabs(x)+fabs(y))?0:(x<y?-1:1);
- }
- inline int compare(long double x,long double y) {
- return fabs(x-y)<=epsilon*(fabs(x)+fabs(y))?0:(x<y?-1:1);
- }
-
-
- /*int compare(double x,double y) {
- return x<y?-1:(x==y?0:1);
- }*/
-
- //
- // General array class. Much like the standard 'vector' class,
- // except that it is reference-counted with 'copy on write'
- // semantic, so that passing arrays by value is cheap.
- //
- template<class T> class array {
- public:
- typedef size_t size_type;
- typedef T* iterator;
- typedef const T* const_iterator;
-
- array() : d(NULL),pbeg(NULL),pend(NULL),pcur(NULL) {}
- array(const array& a)
- : d(a.d),pbeg(a.pbeg),pcur(a.pcur),pend(a.pend) {
- if(d)
- ++d->count;
- }
- ~array() { destroy(); }
-
- array& operator = (const array& a) {
- if(&a!=this) {
- destroy();
- d=a.d;
- if(d)
- ++d->count;
- pbeg=a.pbeg;
- pcur=a.pcur;
- pend=a.pend;
- }
- return *this;
- }
-
- size_type size() const { return pcur-pbeg; }
- bool empty() const { return pcur==pbeg; }
- void reserve(size_type);
-
- const T& operator [] (int n) const { return pbeg[n]; }
- //T& operator [] (int n) { return pbeg[n]; }
- class modifier;
- friend class modifier;
- class modifier {
- public:
- explicit modifier(array& a) : arr(a) { a.resize(0); }
- T& operator [] (int n) const { return arr.pbeg[n]; }
- private:
- array& arr;
- };
-
- //iterator begin();
- //iterator end();
- const_iterator begin() const { return pbeg; }
- const_iterator end() const { return pcur; }
-
- //iterator rbegin();
- //iterator rend();
- //const_iterator rbegin() const;
- //const_iterator rend() const;
-
- void push_back(const T& x) {
- if(pcur==pend || d->count!=1)
- resize(1);
- new (pcur) T(x);
- ++pcur;
- }
-
- void pop_back() {
- (--pcur)->~T();
- }
-
- const T& back() const { return pcur[-1]; }
- //T& back() { return pcur[-1]; }
-
- void insert(const_iterator,const T&);
- void erase(const_iterator);
-
- void clear() {
- destroy();
- d=NULL;
- pbeg=pcur=pend=NULL;
- }
-
- private:
- struct data {
- int count;
- T buf[1];
- };
- data* d;
- T* pbeg;
- T* pcur;
- T* pend;
- void destroy();
- void resize(size_type);
- static void destroy(iterator,iterator);
- static void copy(iterator,const_iterator,const_iterator);
- static void move_forward(iterator,iterator,int);
- static void move_backward(iterator,iterator,int);
- #ifdef __SASC // SASC has no oprator new/delete[]
- static void* myalloc(size_t sz) { return operator new (sz); }
- static void myfree(void* p) { operator delete (p); }
- #else
- static void* myalloc(size_t sz) { return operator new [] (sz); }
- static void myfree(void* p) { operator delete [] (p); }
- #endif
- };
-
-
- template<class T> class Vertex {
- public:
- Vertex() {}
- Vertex(T a,T b) : x(a),y(b) {}
- T x,y;
- };
-
- template<class T> class Vector {
- public:
- Vector(const Vertex<T>& v1,const Vertex<T>& v2) {
- vertex[0]=v1;
- vertex[1]=v2;
- }
- const Vertex<T>& operator [] (int n) const { return vertex[n]; }
- private:
- Vertex<T> vertex[2];
- };
-
-
- template<class T> class Line {
- public:
- Line(const Vector<T>& w) {
- T u=w[1].y-w[0].y;
- T v=w[0].x-w[1].x;
- T d=sqrt(u*u+v*v);
- a=u/d;
- b=v/d;
- c=-a*w[0].x-b*w[0].y;
- }
- Line(const Vertex<T>& v1,const Vertex<T>& v2) {
- T u=v2.y-v1.y;
- T v=v1.x-v2.x;
- T d=sqrt(u*u+v*v);
- a=u/d;
- b=v/d;
- c=-a*v1.x-b*v1.y;
- }
- Line(T u,T v,T w) {
- T d=sqrt(u*u+v*v);
- a=u/d;
- b=v/d;
- c=w/d;
- }
-
- Vertex<T> intersection(const Line&) const;
-
- int side(const Vertex<T>&) const;
-
- T a,b,c;
- };
-
-
- template<class T> class Polygon : public array<Vertex<T> > {
- public:
- Polygon() : convex(false) {}
- //~Polygon();
-
- void is_convex(bool c) { convex=c; }
- bool is_convex() const { return convex; }
- Vertex<T> center() const;
- bool is_rectangle() const;
- void reduce();
-
- private:
- bool convex;
- };
-
- // Area bounded by a family of polygons.
- template<class T> class PArea : public array<Polygon<T> > {
- public:
- enum Rule { even_odd,winding };
-
- PArea() : rule_val(even_odd),convex_union(false) {}
- //~PArea();
-
- void even_odd_rule() { rule_val=even_odd; }
- void winding_rule() { rule_val=winding; }
-
- void rule(Rule r) { rule_val=r; }
- Rule rule() const { return rule_val; }
-
- bool is_convex_union() const { return convex_union; }
- void is_convex_union(bool c) { convex_union=c; }
- bool split(PArea&,PArea&,const Line<T>&) const;
- PArea make_convex_union() const;
-
- void reduce();
-
- bool is_rectangle_union() const;
- bool is_disjoint_rectangle_union() const;
-
- private:
- Rule rule_val;
- bool convex_union;
- };
-
- template<class T> PArea<T> operator & (const PArea<T>&,const PArea<T>&);
-
- #endif
-
-