2021-09-11 22:47:44 +10:00
|
|
|
#ifndef TOWERS_HEADER
|
|
|
|
#include "towers.h"
|
2021-09-08 21:48:00 +10:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef DCEL_HEADER
|
|
|
|
#define DCEL_HEADER
|
|
|
|
|
2021-09-11 22:47:44 +10:00
|
|
|
/* 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;
|
2021-09-11 22:47:44 +10:00
|
|
|
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;
|
2021-09-09 17:10:24 +10:00
|
|
|
int face;
|
|
|
|
int edge;
|
2021-09-11 22:47:44 +10:00
|
|
|
int startVertex;
|
|
|
|
int endVertex;
|
2021-09-09 17:10:24 +10:00
|
|
|
} halfEdge_t;
|
|
|
|
|
|
|
|
typedef struct edge {
|
2021-09-11 22:47:44 +10:00
|
|
|
halfEdge_t *halfEdge;
|
2021-09-13 12:27:17 +10:00
|
|
|
tower_t *tower;
|
2021-09-09 17:10:24 +10:00
|
|
|
} edge_t;
|
|
|
|
|
|
|
|
typedef struct face {
|
2021-09-11 22:47:44 +10:00
|
|
|
halfEdge_t *start;
|
|
|
|
tower_t *tower;
|
2021-09-09 17:10:24 +10:00
|
|
|
} face_t;
|
2021-09-08 21:48:00 +10:00
|
|
|
|
2021-09-11 22:47:44 +10:00
|
|
|
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;
|
2021-09-11 22:47:44 +10:00
|
|
|
} 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);
|
|
|
|
|
2021-09-11 22:47:44 +10:00
|
|
|
/* 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 */
|
2021-09-11 22:47:44 +10:00
|
|
|
/* 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 */
|
2021-09-11 22:47:44 +10:00
|
|
|
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);
|
|
|
|
|
2021-09-08 21:48:00 +10:00
|
|
|
#endif
|