comp20003-project02/dcel.h

229 lines
6.5 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 {
2021-09-13 12:27:17 +10:00
vertex_t *mid;
int isSlopeInfinite;
double slope;
} bisector_t;
2021-09-13 12:27:17 +10:00
typedef struct halfEdge {
struct halfEdge *previous;
struct halfEdge *next;
struct halfEdge *twin;
int face;
int edge;
int startVertex;
int endVertex;
} halfEdge_t;
typedef struct edge {
halfEdge_t *halfEdge;
2021-09-13 12:27:17 +10:00
tower_t *tower;
} 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 {
2021-09-13 12:27:17 +10:00
int fromEdge;
int toEdge;
vertex_t *fromPoint;
vertex_t *toPoint;
} 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);
/* 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)
/* 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);
2021-09-13 12:27:17 +10:00
/* Gets the intersection between the given bisector and the given DCEL
* for the given face.
*/
intersection_t **getIntersections(intersection_t **intersections, \
int *numIntersections, bisector_t **bisectors, int numBisectors, \
DCEL_t *dcel, int face, double minLength);
/* 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);
2021-09-13 12:27:17 +10:00
/* O'Rourke's intersection 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);
2021-09-13 12:27:17 +10:00
/* Tests if a half edge and a bisector intersect */
enum intersectType intersects(halfEdge_t *he, bisector_t *b, \
DCEL_t *dcel, double minLength, double *x, double *y);
2021-09-13 12:27:17 +10:00
/* 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 **getBisectors(bisector_t **bisectors, vertex_t **points, \
int numPoints);
/* Returns a point at least distance away from the midpoint of the
* bisector given. If direction is 0, then the point is +distance away in the
* x-direction, otherwise -distance away in the x-direction.
*/
vertex_t *getBisectorPoint(double distance, bisector_t *b, int direction);
/* Create a new intersection */
intersection_t *newIntersection();
/* Frees an array of bisectors */
void freeBisectors(bisector_t **bisectors, int numBisectors);
/* Frees an array of points */
void freePoints(vertex_t **points, int numPoints);
/* Frees an array of intersections */
void freeIntersections(intersection_t **intersections, int numIntersections);
/* Reads a points file and stores the information in the points array */
vertex_t **readPoints(vertex_t **points, FILE *pointsFile, int *numPoints);
#endif