comp20003-project02/dcel.h

262 lines
7.4 KiB
C
Raw Normal View History

#ifndef TOWERS_HEADER
#include "towers.h"
#endif
#ifndef DCEL_HEADER
#define DCEL_HEADER
/* Here is the Base Code from Grady, with some alterations by me */
enum intersectType {
DOESNT_INTERSECT = 0, // Doesn't intersect
INTERSECT = 1, // Intersects
SAME_LINE_OVERLAP = 2, // Lines are the same
ENDS_OVERLAP = 3 // Intersects at exactly one point (endpoint)
};
typedef struct vertex {
double x;
double y;
} vertex_t;
typedef struct bisector {
double startX;
double startY;
double endX;
double endY;
/* This refers to the midpoint of the line segment AB, not the midpoint
* of the bisector itself.
*/
double midX;
double midY;
int isSlopeInfinite;
double slope;
} bisector_t;
typedef struct halfEdgeLabel {
struct halfEdgeLabel *previous;
struct halfEdgeLabel *next;
struct halfEdgeLabel *twin;
int face;
int edge;
int startVertex;
int endVertex;
} halfEdge_t;
typedef struct edge {
halfEdge_t *halfEdge;
} edge_t;
typedef struct face {
halfEdge_t *start;
tower_t *tower;
} face_t;
typedef struct split {
int startEdge;
int endEdge;
int verticesSpecified;
vertex_t startPoint;
vertex_t endPoint;
} split_t;
typedef struct intersection {
vertex_t intersectionPoint;
} intersection_t;
typedef struct DCEL {
edge_t *edges;
int edgesUsed;
int edgesAllocated;
face_t *faces;
int facesUsed;
int facesAllocated;
vertex_t *vertices;
int verticesUsed;
int verticesAllocated;
} DCEL_t;
/* Allocate a new DCEL and return it. */
DCEL_t *newDCEL();
/* Allocate a new halfEdge and return it. */
halfEdge_t *newHalfEdge();
/* Returns INSIDE if the points is on the INSIDE of the vector twin by the CW
* winding order, OUTSIDE if it is OUTSIDE by the CW winding order, and
* DIR_UNDECIDED if the point lies on the vector between the points v1 and v2.
*/
int getRelativeDir(double x, double y, vertex_t *v1, vertex_t *v2);
/* Takes an established direction and a new direction, and returns 1 if the
* direction matches the decidedDirection or if the direction is undecided.
*/
int directionOrUndecided(int decidedDirection, int direction);
/* Check there's space for another vertex in the DCEL,
* or increase the allocated space.
*/
void ensureSpaceForVertex(DCEL_t *dcel);
/* Check there's space for another edge in the DCEL,
* or increase the allocated space.
*/
void ensureSpaceForEdge(DCEL_t *dcel);
/* Check there's space for another face in the DCEL,
* or increase the allocated space.
*/
void ensureSpaceForFace(DCEL_t *dcel);
/* Add an edge from the startVertex index vertex to the endVertex index.
* Only fills one half-edge as other half-edges will always be added
* through geometry construction.
*/
void addEdge(DCEL_t *dcel, int startVertex, int endVertex);
/* Add a face to the DCEL given using the given halfEdge and sets the face. */
void addFace(DCEL_t *dcel, halfEdge_t *he);
/* Reads the polygon from the given file. */
DCEL_t *readPolygonFile(char *polygonfileName);
/* Reads the next split from the given file. */
split_t *readNextSplit(FILE *splitfile);
/* Frees a given split. */
void freeSplit(split_t *split);
/* Returns 1 if vertices are sufficiently close, 0 otherwise. */
int vertexMatch(vertex_t *v1, vertex_t *v2);
/* Gets the string for the given bisector equation. */
char *getBisectorEquation(bisector_t *b);
/* Frees the given bisector. */
void freeBisector(bisector_t *bisector);
/* Representation of no face */
#define NOFACE (-1)
/* Default face for intersections. */
#define DEFAULT_FACE 0
/* Default minimum length for bisector in each direction */
#define DEFAULTMINLENGTH (200)
/* Gets the intersection between the given bisector and the given DCEL
* for the given face.
*/
intersection_t *getIntersection(bisector_t *b, DCEL_t *dcel, \
int face, double minLength);
/* Gets the string for the given intersection. */
char *getIntersectionString(intersection_t *intersection);
/* Frees a given intersection. */
void freeIntersection(intersection_t *intersection);
/* Applies a given split to the DCEL. */
void applySplit(split_t *split, DCEL_t *dcel);
/* Frees the given DCEL */
void freeDCEL(DCEL_t *dcel);
/* Gets the number of faces in the DCEL. */
int getFaceCount(DCEL_t *dcel);
/* Returns 1 if the given x,y point is inside the given face. */
int inFace(DCEL_t *dcel, double x, double y, int faceIndex);
/* Gets the diameter of the given face. */
double getDiameter(DCEL_t *dcel, int faceIndex);
/* Adds the watchtower to the Voronoi diagram represented by the given DCEL,
* applying required splits and setting the watchtower as required.
*/
void incrementalVoronoi(DCEL_t *dcel, tower_t *watchTower);
/* Returns the number of vertices in the DCEL. */
int getDCELPointCount(DCEL_t *dcel);
/* Get x value of given vertex in DCEL. */
double getDCELVertexX(DCEL_t *dcel, int vertex);
/* Get y value of given vertex in DCEL. */
double getDCELVertexY(DCEL_t *dcel, int vertex);
/* Returns the number of edges in the DCEL. */
int getDCELEdgeCount(DCEL_t *dcel);
/* Get start vertex of given edge in DCEL. */
int getDCELEdgeVertexStart(DCEL_t *dcel, int edge);
/* Get end vertex of given edge in DCEL. */
int getDCELEdgeVertexEnd(DCEL_t *dcel, int edge);
/* Get start vertex of paired given edge in DCEL. */
int getDCELEdgeVertexPairStart(DCEL_t *dcel, int edge);
/* Get end vertex of paired given edge in DCEL. */
int getDCELEdgeVertexPairEnd(DCEL_t *dcel, int edge);
/* Check if the DCEL has the given edge. */
int DCELhasEdge(DCEL_t *dcel, int edge);
/* Check if the DCEL has a pair for the given edge. */
int DCELhasEdgePair(DCEL_t *dcel, int edge);
/* My own functions */
/* Reads the polygon file and stores the information in the vertices array */
vertex_t **readPolygon(vertex_t **vertices, FILE *polygonFile, \
int *numVertices);
/* Frees an array of vertices */
void freeVertices(vertex_t **vertices, int numVertices);
/* Calculates and returns the equation of a bisector of two points */
bisector_t *getBisector(vertex_t *pointA, vertex_t *pointB);
/* Euclidian distance between two 2D points */
double dist_2D(double x1, double y1, double x2, double y2);
/* Returns a value for x that ensures the point (x, y) is at least d (distance)
* away from (x1, y1) whilst ensuring (x, y) is on the line y = mx + c1.
*/
double inv_dist_2D(double x1, double y1, double m, double c, double d);
/* Returns a point at least distance away from the midpoint of the bisector given */
vertex_t *getBisectorPoint(double distance, bisector_t *b);
/* O'Rourke's functions */
/* Returns -1, 0 or 1, based on the area enclosed by the three points. 0 corresponds
to no area enclosed.
*/
int areaSign(double sx, double sy, double ex, double ey, double x, double y);
/* Returns 1 if point (x, y) is between (sx, sy) and (ex, ey) */
int between(double sx, double sy, double ex, double ey, double x, double y);
/* Returns 1 if the point (x, y) is in the line from s(x, y) to e(x, y),
* 0 otherwise.
*/
int collinear(double sx, double sy, double ex, double ey, double x, double y);
/* Tests if the half edge and bisector are parallel and overlapping, or not
* intersecting.
*/
enum intersectType parallelIntersects(double heSx, double heSy, \
double heEx, double heEy, double bSx, double bSy, \
double bEx, double bEy, double *x, double *y);
/* Tests if */
enum intersectType intersects(halfEdge_t *he, bisector_t *b, \
DCEL_t *dcel, double minLength, double *x, double *y);
#endif