BOOKS i'm reading
 |
/*
* Module ID: dcel.h
* Titre : Declaration de la classe DCEL (doubly connected edge list).
* Utilite : Structure de donnee pour contenir les aretes d'un graphe
* planaire comme decrit dans 'Computational Geometry ' de
* Franco P. Preparata & Michael Ian Shamos (P. 15)
*
* Auteur : Olivier Langlois (olivier@olivierlanglois.net)
* Date : 07 Mars 1998
*
* Revision :
*
* 001 27-Mar-1998 - Olivier Langlois
* Les fstreams ne fonctionnent pas avec le compilateur GNU 2.7.2.1
* lorsque compile avec l'option -frtti.
*
* 002 09-Sep-1998 - Olivier Langlois
* Modifications pour s'adapter a la nouvelle classe oliCollection.
*/
#ifndef _DCEL_H_
#define _DCEL_H_
#include "collect/dict.h"
#include "collect/colvar.h"
#include "geo/geox.h"
#include "geo/line.h"
#include "geo/polygon.h"
#include "uref.h"
/*
* Declarations incompletes
*/
class edge;
class graphObject : public Reference
{
public:
virtual ~graphObject() {}
void removeIdx( const CollectableULong *key );
void addIdx ( const CollectableULong *key );
const IDList *getEdgeIdxList( void ) const { return &edgeIdxList; }
protected:
// Cette classe ne possede pas de fonctions pures virtuelles alors pour
// la rendre abstraite, le default & le copy constructors sont definis
// comme etant protected. Ainsi, il y a que les classes derivees qui
// peuvent instantier une instance de cette classe.
graphObject() {}
graphObject(const graphObject &go)
: edgeIdxList(go.edgeIdxList) {}
#ifdef __GNUG__
void restoreList( FILE *is );
void saveList( FILE *os )
#else
void restoreList( istream &is );
void saveList( ostream &os )
#endif
{ edgeIdxList.saveGuts(os); }
private:
IDList edgeIdxList; // Liste des edges qui ont une reference a cet objet.
};
class vertex : public graphObject, public point
{
DECLARE_COLLECTABLE(vertex)
public:
vertex() {}
vertex(const point &p);
~vertex();
virtual Boolean isEqual(const Collectable*) const;
#ifdef __GNUG__
virtual void saveGuts( FILE * );
virtual void restoreGuts( FILE * );
#else
virtual void saveGuts( ostream & );
virtual void restoreGuts( istream & );
#endif
Boolean operator==(const vertex &) const;
};
class face : public graphObject, public Collectable
{
DECLARE_COLLECTABLE(face)
public:
face() {}
face( const point &p ) : location(p) {}
virtual unsigned hash( void ) const { return location.hash(); }
virtual Boolean isEqual(const Collectable*) const;
#ifdef __GNUG__
virtual void saveGuts( FILE * );
virtual void restoreGuts( FILE * );
#else
virtual void saveGuts( ostream & );
virtual void restoreGuts( istream & );
#endif
Boolean operator==(const face &) const;
const point &getLocation( void ) const { return location; }
private:
point location;
};
/*
* VerticesDictionary : Conserve une reference sur
*
* 1 - Le vertex le plus a gauche dans le dictionaire
* 2 - Le vertex le plus a droite dans le dictionaire
* 3 - Le vertex le plus haut dans le dictionaire
* 4 - Le vertex le plus bas dans le dictionaire
*/
class VerticesDictionary : public Dictionary
{
DECLARE_COLLECTABLE(VerticesDictionary)
public:
VerticesDictionary(size_t N = oliCollection::DEFAULT_CAPACITY,
float ff = 0.67)
: Dictionary(N,ff), xmin(ULONG_MAX), xmax(ULONG_MAX),
ymin(ULONG_MAX), ymax(ULONG_MAX) {}
VerticesDictionary(const VerticesDictionary &dict)
: Dictionary(dict), xmin(dict.xmin), xmax(dict.xmax),
ymin(dict.ymin), ymax(dict.ymax) {}
virtual void clear();
/******************************************************************************
*
* Nom : Insert
*
* Utilite : Insere un vertex et sa clef dans le dictionaire.
*
* Parametres:
* kx (const Collectable *) Clef.
* dx (const Collectable *) Donnee.
*
* Valeur de retour: Aucune
*
****************************************************************************/
virtual void Insert(const Collectable *kx, const Collectable *dx );
/******************************************************************************
*
* Nom : remove
*
* Utilite : Enleve un vertex associee a la clef specifiee.
*
* Parametres:
* kx (const Collectable *) Clef.
*
* Note : L'usager est responsable de la destruction de la valeur
* retournee.
*
* Valeur de retour: (Collectable *) La valeur demandee ou NULL si
* non-existante.
*
****************************************************************************/
virtual Collectable *remove(const Collectable *kx);
CollectableULong getxminIdx() { return xmin; }
CollectableULong getxmaxIdx() { return xmax; }
CollectableULong getyminIdx() { return ymin; }
CollectableULong getymaxIdx() { return ymax; }
vertex *getxmin()
{ return (vertex *)getValue(&xmin); }
vertex *getxmax()
{ return (vertex *)getValue(&xmax); }
vertex *getymin()
{ return (vertex *)getValue(&ymin); }
vertex *getymax()
{ return (vertex *)getValue(&ymax); }
private:
CollectableULong ymin;
CollectableULong xmin;
CollectableULong ymax;
CollectableULong xmax;
};
// Classe utilisee par DCEL::setBox
class BoxInfo
{
public:
BoxInfo(): Vertex(NULL),leftFace(NULL),rightFace(NULL) {}
int operator==(const BoxInfo &b)
{
return Key == b.Key;
}
int operator!=(const BoxInfo &b)
{
return !operator==(b);
}
// La priorite est plus petite lorsque la clef est plus grande.
int operator<(const BoxInfo &b)
{
return Key > b.Key;
}
// La priorite est plus grande lorsque la clef est plus petite.
int operator>(const BoxInfo &b)
{
return Key < b.Key;
}
int operator<=(const BoxInfo &b)
{
return operator<(b)||operator==(b);
}
int operator>=(const BoxInfo &b)
{
return operator>(b)||operator==(b);
}
vertex *Vertex;
face *leftFace;
face *rightFace;
double Key;
};
class DCEL : public oliCollection
{
DECLARE_COLLECTABLE(DCEL)
friend class edge;
public:
DCEL();
~DCEL();
unsigned long getNextVertexKey();
unsigned long getNextFaceKey();
unsigned long getNextEdgeKey();
VerticesDictionary &Vertices() { return VerticesList; }
Dictionary &Faces() { return FacesList; }
Dictionary &Edges() { return EdgesList; }
/******************************************************************************
*
* Nom : insertEdge
*
* Utilite : Insere une arete dans la liste associatedList.
*
* Note : Si le edge ne peut etre insere, il sera detruit.
*
* Parametres:
* e (edge *) Edge a insere
*
* Valeur de retour: 0 si insere sinon -1
*
****************************************************************************/
int insertEdge( edge * );
/******************************************************************************
*
* Nom : setBox
*
* Utilite : Ferme le graph a l'interieur d'une boite.
*
*
* Parametres:
* poly (polygon &) Forme de la boite.
*
* Valeur de retour: Aucune
*
****************************************************************************/
void setBox( polygon & );
/******************************************************************************
*
* Nom : clean
*
* Utilite : Elimine toutes les aretes non connectees.
*
* Parametres:
* Aucun
*
* Valeur de retour: Aucune
*
****************************************************************************/
void clean();
virtual void clear();
#ifdef __GNUG__
virtual void saveGuts( FILE * );
virtual void restoreGuts( FILE * );
#else
virtual void saveGuts( ostream & );
virtual void restoreGuts( istream & );
#endif
vertex *getVertex( const CollectableULong *idx ) const
{
return (vertex *)VerticesList.getValue(idx);
}
face *getFace ( const CollectableULong *idx ) const
{
return (face *)FacesList.getValue(idx);
}
edge *getEdge ( const CollectableULong *idx ) const
{
return (edge *)EdgesList.getValue(idx);
}
edge *getxminEdge();
edge *getyminEdge();
edge *getxmaxEdge();
edge *getymaxEdge();
virtual size_t entries( void ) const
{ return EdgesList.entries(); }
virtual Boolean isEmpty( void ) const
{ return EdgesList.isEmpty(); }
private:
void init(void);
void setP1( edge *, CollectableULong * );
void setP2( edge *, CollectableULong * );
void removeP1( edge * );
void removeP2( edge * );
unsigned long nextVertexKey;
unsigned long nextFaceKey;
unsigned long nextEdgeKey;
/*
* Des indexes sont preferes a des pointeurs. La raison est qu'ainsi,
* il est plus facile d'implanter la persistence sur cette classe.
*/
Dictionary EdgesList;
Dictionary FacesList;
VerticesDictionary VerticesList;
};
/*
* class edge
*/
class edge : public Collectable, public Reference
{
DECLARE_COLLECTABLE(edge)
friend class DCEL;
public:
edge( DCEL *l, face *f1, face *f2, vertex *v1, vertex *v2 );
edge( DCEL *l, face *f1, face *f2, const segment &s );
edge( DCEL *l, face *f1, face *f2, const line &s );
~edge();
virtual Boolean isEqual(const Collectable*) const;
#ifdef __GNUG__
virtual void saveGuts( FILE * );
virtual void restoreGuts( FILE * );
#else
virtual void saveGuts( ostream & );
virtual void restoreGuts( istream & );
#endif
Boolean atRight( const point & ) const;
Boolean intersection( edge &, point & );
face *getF1() const;
face *getF2() const;
vertex *getV1() const;
vertex *getV2() const;
CollectableULong *getKey() { return &myKey; }
unsigned long getF1Idx() {return F1.value();}
unsigned long getF2Idx() {return F2.value();}
unsigned long getV1Idx() {return V1.value();}
unsigned long getV2Idx() {return V2.value();}
segment getSegment()
{ return segment( *getV1(), *getV2() ); }
void setF1( face * );
void setF2( face * );
void setV1( vertex * );
void setV2( vertex * );
/******************************************************************************
*
* Nom : insert
*
* Utilite : Insere cette arete dans la liste associatedList.
*
* Note : Cette fonction est surtout utile pour les algorithmes de
* construction de graphe planaire qui doivent executer certaines
* manipulations sur les edges avant de les inseres.
*
* Parametres:
* Aucun.
*
* Valeur de retour: Aucune.
*
****************************************************************************/
void insert( void ) { associatedList->insertEdge( this ); }
protected:
edge() {}
void init( face *f1, face *f2, vertex *v1, vertex *v2 );
// Fonction appellee exclusivement par le DCEL.
void setMyKey( unsigned long key );
/*
* Des indexes sont preferes a des pointeurs. La raison est qu'ainsi,
* 1 - il est plus facile d'implanter la persistence sur cette classe.
*/
// Convention: V1 est toujours le point dont x est plus petit
CollectableULong V1, V2; // Index des vertices
// Convention: F1 est toujours le point a droite de segment(V1,V2)
CollectableULong F1, F2; // Index des faces
CollectableULong P1, P2; // Indexes sur les aretes suivantes
CollectableULong myKey; // Index attribue par le DCEL pour l'arete courante.
DCEL *associatedList;
private:
edge( const edge &e ) {}
};
#endif /* _DCEL_H_ */
|