#ifndef TOWERS_HEADER #include "towers.h" #endif #ifndef MATH_HEADER #include #endif #ifndef DCEL_HEADER #define DCEL_HEADER /* -------- Definitions, enums, and structs from Grady's base code --------- */ /* 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) 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 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; 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 DCEL { edge_t *edges; int edgesUsed; int edgesAllocated; face_t *faces; int facesUsed; int facesAllocated; vertex_t *vertices; int verticesUsed; int verticesAllocated; } DCEL_t; /* ------------------------------ My structs ------------------------------- */ typedef struct bisector { vertex_t *mid; int isSlopeInfinite; double slope; } bisector_t; typedef struct intersection { int fromEdge; int toEdge; vertex_t *fromPoint; vertex_t *toPoint; } intersection_t; /* ----------------------- My points functions start ----------------------- */ /* Creates a new point */ vertex_t *newPoint(); /* Gets a single point from an x-y pair */ vertex_t *getAPoint(double x, double y); /* Reads a points file and stores the information in the points array */ vertex_t **readPoints(vertex_t **points, FILE *pointsFile, int *numPoints); /* Frees an array of points */ void freePoints(vertex_t **points, int numPoints); /* Returns the distance between two points */ double distPoints(vertex_t *pointA, vertex_t *pointB); /* ------------------------ My points functions end ------------------------ */ /* -------------------- My intersection functions start -------------------- */ /* Create a new intersection */ intersection_t *newIntersection(); /* Fills in a single intersection structure */ intersection_t *getAnIntersection(intersection_t *intersection, DCEL_t *dcel, \ bisector_t *bisector, int face, int minLength); /* 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); /* Frees an array of intersections */ void freeIntersections(intersection_t **intersections, int numIntersections); /* --------------------- My intersection functions end --------------------- */ /* ---------------------- My bisector functions start ---------------------- */ /* Creates a new bisector */ bisector_t *newBisector(); /* Calculates and returns the equation of a bisector of two points */ bisector_t *getABisector(bisector_t *bisector, vertex_t *pointA, \ vertex_t *pointB); /* Returns a list of bisectors built from a list of 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); /* Frees an array of bisectors */ void freeBisectors(bisector_t **bisectors, int numBisectors); /* ----------------------- My bisector functions end ----------------------- */ /* ------------------------ My DCEL functions start ------------------------ */ /* Gets the diameter of the given face. */ double getDiameter(DCEL_t *dcel, int faceIndex); /* ------------------------- My DCEL functions end ------------------------- */ /* ---------------------------------------------------------------------------- * Here on out are the functions from Grady's base code on Ed * ---------------------------------------------------------------------------- */ /* Allocate a new DCEL and return it. */ DCEL_t *newDCEL(); /* Allocate a new halfEdge and return it. */ halfEdge_t *newHalfEdge(); /* 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); /* 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 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); /* Returns 1 if the given x,y point is inside the given face. */ int inFace(DCEL_t *dcel, double x, double y, int faceIndex); /* ------------------- 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); /* 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); #endif