#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