home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Enigma Amiga Life 110
/
EnigmaAmiga110CD.iso
/
indispensabili
/
utility
/
apdf
/
xpdf-0.80
/
xpdf
/
poly.h
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-20
|
6KB
|
276 lines
//========================================================================
//
// 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