From 11b8feaa6ece03e934684c44db910d116e07cfdb Mon Sep 17 00:00:00 2001 From: Rory Healy Date: Mon, 13 Sep 2021 12:27:17 +1000 Subject: [PATCH] Task 2 completed --- .vscode/launch.json | 46 +++++ Makefile | 26 +-- common.h | 7 - common.o | Bin 6616 -> 6536 bytes dcel.c | 441 +++++++++++++++++++++----------------------- dcel.h | 139 ++++++-------- dcel.o | Bin 42528 -> 41232 bytes input.c | 2 +- input.o | Bin 8832 -> 8752 bytes main.c | 42 +---- main.o | Bin 7328 -> 4960 bytes output.txt | 6 + towers.c | 17 +- towers.o | Bin 9848 -> 9816 bytes voronoi.c | 94 ++++------ voronoi.h | 7 +- voronoi.o | Bin 15384 -> 14544 bytes voronoi2 | Bin 63952 -> 61896 bytes 18 files changed, 370 insertions(+), 457 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..884d5dd --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,46 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Voronoi2 - 1", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/voronoi2", + "args": ["1", "pp_inside.txt", "output.txt"], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + }, + { + "name": "Voronoi2 - 2", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/voronoi2", + "args": ["2", "pp_inside.txt", "polygon_square.txt", "output.txt"], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} diff --git a/Makefile b/Makefile index e725bfa..a96ce28 100644 --- a/Makefile +++ b/Makefile @@ -1,24 +1,8 @@ -# Link command: -#voronoi1: common.o dcel.o voronoi.o main.o -# gcc -Wall -Wextra -Werror -pedantic -g -o voronoi1 main.o voronoi.o dcel.o common.o - -# Compilation commands: -#common.o: common.c -# gcc -Wall -Wextra -Werror -pedantic -g -o common.o common.c -c -# -#dcel.o: dcel.c -# gcc -Wall -Wextra -Werror -pedantic -g -o dcel.o dcel.c -c -# -#voronoi.o: voronoi.c -# gcc -Wall -Wextra -Werror -pedantic -g -o voronoi.o voronoi.c -c -# -#main.o: main.c -# gcc -Wall -Wextra -Werror -pedantic -g -o main.o main.c -c - # Link command: voronoi2: common.o towers.o dcel.o voronoi.o input.o main.o - gcc -Wall -Wextra -Werror -pedantic -g -o voronoi2 main.o input.o voronoi.o dcel.o towers.o common.o -lm + gcc -Wall -Wextra -Werror -pedantic -g -o voronoi2 main.o input.o voronoi.o dcel.o towers.o common.o +# Compilation commands common.o: common.c gcc -Wall -Wextra -Werror -pedantic -g -o common.o common.c -c @@ -31,8 +15,8 @@ dcel.o: dcel.c voronoi.o: voronoi.c gcc -Wall -Wextra -Werror -pedantic -g -o voronoi.o voronoi.c -c -main.o: main.c - gcc -Wall -Wextra -Werror -pedantic -g -o main.o main.c -c - input.o: input.c gcc -Wall -Wextra -Werror -pedantic -g -o input.o input.c -c + +main.o: main.c + gcc -Wall -Wextra -Werror -pedantic -g -o main.o main.c -c diff --git a/common.h b/common.h index 8527956..7709843 100644 --- a/common.h +++ b/common.h @@ -19,13 +19,6 @@ #endif -#ifndef MATH_HEADER -#define MATH_HEADER - -#include - -#endif - #ifndef COMMON_HEADER #define COMMON_HEADER diff --git a/common.o b/common.o index d255b408f06158bb9091861590835434d41b065e..734d90fe2cbc13637b2445741bbe533d8901260f 100644 GIT binary patch delta 755 zcmZ9JKWG$D5XN`j9o}8!_Rned?K7aI7Z8^-#a%>hPn)QfHWCm5DYUY1gQQ4j6GE!w zzBa_1*cgK0vKA-NBApUJ)^A~csR=AZsFGON%XfmhrWc_->`sbTdJo_?-{g(Wjmxh*wOJJQhP%D6gcmkRWI1^ z-7w7Iz9Z3ci&%52s?D^@+a7M&#%D*W*Gw-NbO6r{X%81&sSa2(YiQbtHQnUyl0i?P zqiH^unb!@vinn_HD9DrQG2gLgXwISLNqT}S-UMC7vR3}$P0q06@RkqQ(ex4fZyNL+ zQa$GtN|kVYirI>x*=BFY=wIi01D%Sz`o^F!*B_1k7oPUR==Zrk5Q#W8AZjG(@dD8) z{2s2C+;VnZ595BFZXos}9lL%cURLnUZ_+$!G7|e0%*bYG{Ya*^@l4jKhg3%Tch!PO gd@5lkXyR^AL@#KNi!_L65;YakE@B;9=&I9y0M?>=$p8QV delta 830 zcmZ9IK}Zx)7{}+E8C}=} z{skR^Z3u$wAnQm(blF>Vlf8J!+Djx-PL=*fKB;XRn|b&7H7GxHux6jPx~lUF(Gt#Os@<~-cW%tzOkQLz zn#z-W$xd0)qob^0cxf|wRnMqz2Ng${T_$ch)6~Q#C!kl@cLMocMUPgLw*P^rxRevJ z$#hAh*RYriXc@7ptJug*n3jbT?rHg%1G`$_AtG1M9+ureK4VtoSvxb<(R77uF}NTfW7X<_Y0>g4R*; zCg?gAJt1v&jB=uLmv4v_Z7`kE=vQp0|7>F03+8S!d#-sta`vUBKj!yY(ey*sS2cZ_ z_wP~Z7gx75dY|_{HT^H2Zt-h%?)9hRvy!#`Uqq8hd^|&R3aK78kPby3@cA=0urVh($>IXp0ateh-TNIGse~hcu(& RA>Bh;)jbqsNHs)qmid); + free(bisectors[i]); + } + free(bisectors); +} + +void freeIntersections(intersection_t **intersections, int numIntersections) { + for (int i = 0; i < numIntersections; i++) { + free(intersections[i]->fromPoint); + free(intersections[i]->toPoint); + free(intersections[i]); + } + free(intersections); +} + +bisector_t **getBisectors(bisector_t **bisectors, vertex_t **points, \ + int numBisectors) { + for (int i = 0; i < numBisectors; i++) { + bisectors[i] = malloc(sizeof(*bisectors[i])); + bisectors[i]->mid = malloc(sizeof(*bisectors[i]->mid)); + + /* Calculate midpoint of the two points */ + bisectors[i]->mid->x = (points[2 * i]->x + points[2 * i + 1]->x) / 2; + bisectors[i]->mid->y = (points[2 * i]->y + points[2 * i + 1]->y) / 2; + + /* Calculating bisector slope according to slope of AB */ + if (points[2 * i]->x == points[2 * i + 1]->x) { + /* The line segment AB has an infinite gradient, + * so the orthogonal line will have zero slope. + */ + bisectors[i]->slope = 0; + bisectors[i]->isSlopeInfinite = 0; + } else if (points[2 * i]->y == points[2 * i + 1]->y) { + /* The line segment AB has gradient of zero, so + * the orthogonal line will have an infinite slope. + */ + bisectors[i]->isSlopeInfinite = 1; + + /* Not actually zero, just a placeholder to prevent + * accidental errors + */ + bisectors[i]->slope = 0; + } else { + /* The line segment AB has a non-zero and finite gradient, + * so the gradient of the bisector can be calculated. + */ + bisectors[i]->isSlopeInfinite = 0; + bisectors[i]->slope = -1 / \ + ((points[2 * i + 1]->y - points[2 * i]->y) / \ + (points[2 * i + 1]->x - points[2 * i]->x)); + } + } + + return bisectors; +} + +vertex_t *getBisectorPoint(double distance, bisector_t *b, int direction) { + vertex_t *returnPoint = malloc(sizeof(*returnPoint)); + + if (b->isSlopeInfinite) { + /* Vertical line - just add vertical distance */ + returnPoint->x = b->mid->x; + returnPoint->y = b->mid->y + (distance * direction); + } else if (b->slope == 0) { + /* Horizontal line - just add horizontal distance */ + returnPoint->x = b->mid->x + (distance * direction); + returnPoint->y = b->mid->y; + } else { + /* Not horizontal or vertical - add distance to x, then find + * y-intercept of the bisector, and plug it in to y = mx + c to find + * the corresponding y-value. + */ + double c = b->mid->y - b->slope * b->mid->x; + returnPoint->x = b->mid->x + (distance * direction); + returnPoint->y = b->slope * returnPoint->x + c; + } + + return returnPoint; +} + +intersection_t *newIntersection() { + intersection_t *intersection = malloc(sizeof(*intersection)); + checkNullPointer(intersection); + + intersection->fromPoint = malloc(sizeof(*intersection->fromPoint)); + checkNullPointer(intersection->fromPoint); + + intersection->toPoint = malloc(sizeof(*intersection->toPoint)); + checkNullPointer(intersection->toPoint); + + return intersection; +} + +vertex_t **readPoints(vertex_t **points, FILE *pointsFile, int *numPoints) { + /* Initial size of buffer is 1 as getline() reallocs as needed */ + size_t lineBufferSize = 1; + + /* Stores the current line from the points file */ + char *lineBuffer = malloc(lineBufferSize * sizeof(*lineBuffer)); + checkNullPointer(lineBuffer); + + /* Assuming that pointsFile is valid, there must be at least two points */ + int maxSizePoints = 2; + + while (getline(&lineBuffer, &lineBufferSize, pointsFile) > 0) { + /* Ensure there is enough space in the points array */ + if (*numPoints == maxSizePoints) { + maxSizePoints *= 2; + vertex_t **temp = realloc(points, maxSizePoints * sizeof(*points)); checkNullPointer(temp); - vertices = temp; + points = temp; } - /* The current vertex being filled in with information */ - vertices[*numVertices] = malloc(sizeof(*vertices[*numVertices])); - vertices[*numVertices]->x = currentX; - vertices[*numVertices]->y = currentY; - *numVertices += 1; - } - return vertices; -} + double xCoordinateA, yCoordinateA, xCoordinateB, yCoordinateB; + sscanf(lineBuffer, "%lf %lf %lf %lf", &xCoordinateA, &yCoordinateA, \ + &xCoordinateB, &yCoordinateB); + + points[*numPoints] = malloc(sizeof(*points[*numPoints])); + points[*numPoints]->x = xCoordinateA; + points[*numPoints]->y = yCoordinateA; + *numPoints += 1; -void freeVertices(vertex_t **vertices, int numVertices) { - for (int i = 0; i < numVertices; i++) { - free(vertices[i]); - } - free(vertices); -} - -bisector_t *getBisector(vertex_t *pointA, vertex_t *pointB) { - bisector_t *newBisector = malloc(sizeof(*newBisector)); - checkNullPointer(newBisector); - - double midpointX = (pointA->x + pointB->x) / 2; - double midpointY = (pointA->y + pointB->y) / 2; - - newBisector->midX = midpointX; - newBisector->midY = midpointY; - - /* Calculating bisector slope according to slope of AB */ - if (pointA->x == pointB->x) { - /* The line segment AB has an infinite gradient, - * so the orthogonal line will have zero slope. - */ - newBisector->slope = 0; - newBisector->isSlopeInfinite = 0; - } else if (pointA->y == pointB->y) { - /* The line segment AB has gradient of zero, so - * the orthogonal line will have an infinite slope. - */ - newBisector->isSlopeInfinite = 1; - - /* Not actually zero, just a placeholder to prevent - * accidental errors - */ - newBisector->slope = 0; - } else { - /* The line segment AB has a non-zero and finite gradient, - * so the gradient of the bisector can be calculated. - */ - newBisector->isSlopeInfinite = 0; - newBisector->slope = -1 / \ - ((pointB->y - pointA->y) / (pointB->x - pointA->x)); + points[*numPoints] = malloc(sizeof(*points[*numPoints])); + points[*numPoints]->x = xCoordinateB; + points[*numPoints]->y = yCoordinateB; + *numPoints += 1; } - return newBisector; + free(lineBuffer); + return points; } /* Here on out is the base code from Grady, with some alterations from me */ @@ -99,48 +170,6 @@ bisector_t *getBisector(vertex_t *pointA, vertex_t *pointB) { #define OUTSIDE (-1) #define NODIAMETER (-1) -double dist_2D(double x1, double y1, double x2, double y2) { - return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); -} - -double inv_dist_2D(double x1, double y1, double m, double c1, double d) { - /* Solve sqrt((y - y1)^2 + (x - x1)^2) = d^2 for x by substituting - * y = mx + c1, which gives an equation for x - * Using this, you can find a point that lies on the line y = mx + c1 - * that is of distance d away from (x1, y1). - */ - double a = m * m + 1; - double b = 2 * c1 * m - 2 * x1 - 2 * m * y1; - double c = c1 * c1 + x1 * x1 + y1 * y1 - 2 * c1 * y1 - d * d; - return (-b + sqrt(b * b - 4 * a * c)) / (2 * a); -} - -vertex_t *getBisectorPoint(double distance, bisector_t *b) { - vertex_t *returnPoint = malloc(sizeof(*returnPoint)); - if (b->isSlopeInfinite) { - returnPoint->x = b->midX; - returnPoint->y = b->midY + distance; - } else if (b->slope == 0) { - returnPoint->x = b->midX + distance; - returnPoint->y = b->midY; - } else { - /* Find the y-intercept of the bisector, use it to find the general - * form of the bisector in the form of y = mx + c - */ - double c = b->midY - b->slope * b->midX; - returnPoint->x = inv_dist_2D(b->midX, b->midY, b->slope, c, distance); - returnPoint->y = b->slope * returnPoint->x + c; - } - - /* Due to floating-point precision, there may be a situation where the - * distance between the bisector midpoint and returnPoint is slightly less - * than distance, but unless getBisectorPoint needs to guarentee that this - * distance is greater than distance, it shouldn't be an issue. - */ - - return returnPoint; -} - /* This intersection is based on code by Joseph O'Rourke and is provided for use in COMP20003 Assignment 2. @@ -246,15 +275,18 @@ enum intersectType intersects(halfEdge_t *he, bisector_t *b, \ double heEy = dcel->vertices[he->endVertex].y; /* Bisector x, y twin */ - double bSx = b->startX; - double bSy = b->startY; - double bEx = b->endX; - double bEy = b->endY; + vertex_t *startPoint = getBisectorPoint(minLength, b, -1); + vertex_t *endPoint = getBisectorPoint(minLength, b, 1); + double bSx = startPoint->x; + double bSy = startPoint->y; + double bEx = endPoint->x; + double bEy = endPoint->y; + + free(startPoint); + free(endPoint); /* Fill in segment. */ - // min-length not used here? - printf("In intersets(): minlength = %lf\n", minLength); - + /* Parametric equation parameters */ double t1, t2; @@ -344,53 +376,6 @@ enum intersectType intersects(halfEdge_t *he, bisector_t *b, \ } } -char *getIntersectionString(intersection_t *intersection) { - /* - - - - FILL IN - - - - */ - if (!intersection) { - return NULL; - } - char *returnString = NULL; - if (0 <= 0) { - /* Find out memory needed. */ - int stringLength = snprintf(returnString, 0, - "From Edge %d (%lf, %lf) to Edge %d (%lf, %lf)", - 0, 0.0, 0.0, - 0, 0.0, 0.0); - returnString = malloc(sizeof(*returnString) * (stringLength + 1)); - checkNullPointer(returnString); - sprintf(returnString, "From Edge %d (%lf, %lf) to Edge %d (%lf, %lf)", - 0, 0.0, 0.0, - 0, 0.0, 0.0); - } else { - /* Find out memory needed. */ - int stringLength = snprintf(returnString, 0, - "From Edge %d (%lf, %lf) to Edge %d (%lf, %lf)", - 0, 0.0, 0.0, - 0, 0.0, 0.0); - returnString = malloc(sizeof(*returnString) * (stringLength + 1)); - checkNullPointer(returnString); - sprintf(returnString, "From Edge %d (%lf, %lf) to Edge %d (%lf, %lf)", - 0, 0.0, 0.0, - 0, 0.0, 0.0); - } - return returnString; -} - -void freeIntersection(intersection_t *intersection) { - if (!intersection) { - return; - } - free(intersection); -} - DCEL_t *newDCEL() { /* Setup DCEL. */ DCEL_t *dcel = malloc(sizeof(*dcel)); @@ -1026,82 +1011,72 @@ int inFace(DCEL_t *dcel, double x, double y, int faceIndex) { return 1; } -int getDCELPointCount(DCEL_t *dcel) { - if (!dcel) { - return 0; +intersection_t **getIntersections(intersection_t **intersections, \ + int *numIntersections, bisector_t **bisectors, int numBisectors, \ + DCEL_t *dcel, int face, double minLength) { + int maxSizeIntersections = 1; + + for (int i = 0; i < numBisectors; i++) { + intersection_t *currentIntersection = NULL; + + /* Intersection coordinates */ + double x, y; + + /* Flag is raised when first intersection is found */ + int isIntersectionFound = 0; + + halfEdge_t *startHE = (dcel->faces)[face].start; + halfEdge_t *currentHE = startHE; + int startVertex = startHE->startVertex; + int first = 1; + + /* Loop through the face until the starting vertex is reached */ + while (first || currentHE->startVertex != startVertex) { + enum intersectType typeOfIntersection = \ + intersects(currentHE, bisectors[i], dcel, minLength, &x, &y); + + switch (typeOfIntersection) { + case INTERSECT: + case SAME_LINE_OVERLAP: + case ENDS_OVERLAP: + if (!isIntersectionFound) { + /* First point of intersection */ + isIntersectionFound = 1; + currentIntersection = newIntersection(); + currentIntersection->fromPoint->x = x; + currentIntersection->fromPoint->y = y; + currentIntersection->fromEdge = currentHE->edge; + } else { + /* Second point of intersection */ + currentIntersection->toPoint->x = x; + currentIntersection->toPoint->y = y; + currentIntersection->toEdge = currentHE->edge; + } + break; + case DOESNT_INTERSECT: + default: + break; + } + currentHE = currentHE->next; + first = 0; + } + + /* If there is an intersection, add it to the array */ + if (currentIntersection != NULL) { + /* Ensure there is enough space in the array */ + if (*numIntersections == maxSizeIntersections) { + maxSizeIntersections *= 2; + intersection_t **temp = realloc(intersections, maxSizeIntersections * sizeof(*intersections)); + checkNullPointer(temp); + intersections = temp; + } + + intersections[*numIntersections] = currentIntersection; + *numIntersections += 1; + } } - return dcel->verticesUsed; -} -double getDCELVertexX(DCEL_t *dcel, int vertex) { - return (dcel->vertices)[vertex].x; -} - -double getDCELVertexY(DCEL_t *dcel, int vertex) { - return (dcel->vertices)[vertex].y; -} - -int getDCELEdgeCount(DCEL_t *dcel) { - if (!dcel) { - return 0; - } - return dcel->edgesUsed; -} - -int getDCELEdgeVertexStart(DCEL_t *dcel, int edge) { - if (!dcel) { - return 0; - } - return (dcel->edges)[edge].halfEdge->startVertex; -} - -int getDCELEdgeVertexEnd(DCEL_t *dcel, int edge) { - if (!dcel) { - return 0; - } - return (dcel->edges)[edge].halfEdge->endVertex; -} - -int getDCELEdgeVertexPairStart(DCEL_t *dcel, int edge) { - if (!dcel) { - return 0; - } - return (dcel->edges)[edge].halfEdge->twin->startVertex; -} - -int getDCELEdgeVertexPairEnd(DCEL_t *dcel, int edge) { - if (!dcel) { - return 0; - } - return (dcel->edges)[edge].halfEdge->twin->endVertex; -} - -int DCELhasEdge(DCEL_t *dcel, int edge) { - if ((dcel->edges)[edge].halfEdge->face != NOFACE) { - return 1; - } else { - return 0; - } -} - -int DCELhasEdgePair(DCEL_t *dcel, int edge) { - if ((dcel->edges)[edge].halfEdge->face == NOFACE) { - return 0; - } - if ((dcel->edges)[edge].halfEdge->twin) { - return 1; - } else { - return 0; - } -} - -intersection_t *getIntersection(bisector_t *b, DCEL_t *dcel, int face, - double minLength) { - // FILL IN - printf("In getIntersection(): bisector start: %lf, dcel numfaces = %d" \ - "face = %d, minLength = %lf\n", b->startX, dcel->facesAllocated, \ - face, minLength); - return NULL; + return intersections; } double getDiameter(DCEL_t *dcel, int faceIndex) { diff --git a/dcel.h b/dcel.h index d13827a..25672ae 100644 --- a/dcel.h +++ b/dcel.h @@ -20,25 +20,15 @@ typedef struct vertex { } 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; - + vertex_t *mid; int isSlopeInfinite; double slope; } bisector_t; -typedef struct halfEdgeLabel { - struct halfEdgeLabel *previous; - struct halfEdgeLabel *next; - struct halfEdgeLabel *twin; +typedef struct halfEdge { + struct halfEdge *previous; + struct halfEdge *next; + struct halfEdge *twin; int face; int edge; int startVertex; @@ -47,6 +37,7 @@ typedef struct halfEdgeLabel { typedef struct edge { halfEdge_t *halfEdge; + tower_t *tower; } edge_t; typedef struct face { @@ -63,7 +54,10 @@ typedef struct split { } split_t; typedef struct intersection { - vertex_t intersectionPoint; + int fromEdge; + int toEdge; + vertex_t *fromPoint; + vertex_t *toPoint; } intersection_t; typedef struct DCEL { @@ -136,9 +130,6 @@ 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) @@ -148,18 +139,6 @@ void freeBisector(bisector_t *bisector); /* 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); @@ -172,6 +151,13 @@ 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 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); @@ -180,60 +166,7 @@ double getDiameter(DCEL_t *dcel, int faceIndex); */ 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 */ +/* 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. */ @@ -254,8 +187,42 @@ 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 */ +/* 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); +/* 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 diff --git a/dcel.o b/dcel.o index aca2613661e378d5ea3080a60ef625dbcc94bec5..78c1473ec0047feb09396d7756740da098999e80 100644 GIT binary patch literal 41232 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 W=Y2@0uF7|O-f+F-Wk%XA|9=5Yll7?p literal 42528 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�U)pP?|wdruYo{ymlRdo}W`8h%O*IfY(&Mh(Vb zh-Sygc>o>tM=JM#nsi*Q{s_g@_#;#T z)Q>-=rXHiP89y(sM!lu7c2j=LRTy^jb`er|h899&Pf;w6JEq1QQ4?V?6dhBA$H;eM zk#odbD)1S~26W7iR0u7hrwR3}8W6Z!Wxc0{qTKUp(maLbS=KHhuQ{)L9ct7~)CUK3 z(&{Cw&3`WzZq&WeQuKk2MXMMnMfbp@lY19UB%H>8y;CU+=Kc+@DW5+-q(YeW;G{SW z$(UpomS7$8`BSH`vO@ckKG+z<$|f7*NZ^|^G@u{mKZf5ODtORCWFPzxfjs|!18VdE zm3cr7ZKuvU;w;iA=+`Rqn94h%2E&Lqu~gbjLp>2kVA9>{W>|PeFK>N2Rd5}!yVU#= zETWH*|7eZnt57%4$4<3?K91^zfNvg+f}=ZVt(tQbQ5;t}Eo$H{mAO*oZ%~u5^2SPJ zF|GVQvQyoRG&)Aw#C%nR9g@$e>xhPV0lAvaphMMVG*j+UfbzG5bD= z<^7ByRAJOn1t?seQNB}ZRtu<`lrL>uUYZ|UzM8rwT>Qi>P$!BzsLc*tBVAwBOczqi zs_L4Y%I5WrO|iA{TBmaH^2++g>U%0qs zDx(cG&f?qe2!Cuv_|`j|O-<33y2f}jWnV$pOe5ht8kg18=yDqCYczIybc@yxoY*MF zm;sHOo9bdwtux-xT(_3Z z0_v@eafnvd)>o}-cA^ch<%nk)L+M%+R!Tp=q^M&08C)*V852c=NP)!{)k%nrSh*QrrwC zY^c6x+NP$)n7$M|4O{KT2Fhg^)%8`)>xGTb0i(LsLp$rEc+-GiTXiHfSGAaC3*WwQ zMdk93hd;J-L77uq-&hrMnoX0Tb*mfE0xdCTV^u@dx@Z&pT2({AU>X(SL7{*Ma_Y$x z{VOR9>Ka-qYtZ7AGZs2k$h_i{+G*6XI7x6e*41pH_F9P)UtD%-;kb23>=4iCR z1TN|x-&DD_su|H8#Vdiz#@brk;-*ldYt2#IYo=C5=EzT>Y5kSY=8%; zN5?l(eJI}D@x}BDQzva|!WBfi?OUM>F++uJLO8%U2O|nKK_YzMEGjD6L_Me?kwhN+k}bo}Ks;qvf`+wZ7M41KkAP0glLUo}LKr?tzS=K97> zQ65iL#G2|F)*(WXkJ}a%F%cr;8x6|d+8Hg?@uns?vBKfRO5?c-^MSfmZmO!e-ie{d zQ|={b)JRx2H^l@RJ9%`}4GyE-2BoP&27NOXB!+6IvPF*}(qmRESQf5ay7>06+w0Mx zw$MaSQ&){BUP(dV)y&ndsxgzx#;PqV&_CQ@!0^)~?jT>Fd<{jyiO@o4pbh~@&s=(n zV5jToF*AW4cc|Z*c%V>#klRzp#b)4vu;L@Q4+IcElui)VTz-uu^#8WQS|exM_P}W#+e?#*iGR?wpYSg5(|8uOTM9l zTBmq@! z*H@wMYA4drM@^{LH8ae-heGuP1i^R{EUb@jY@pzy4r7|9BAKKy0p{N@lQhK};#if; z(Egz%9FKs_F`Azp=Oee?dSj@td@WW}ab9dpn;zHX^lKTQQ+M;78eBke@JfzWCv;-p zO(*YsSHi&?a{c)3{g~t167-G8>>t>R6aElT{SFVG`n_E^EBKkTTL<+E@ACU6`ygfb zrQp+}-yn)i+A^2FMspoUzsnT9|1Pb7^zUH)7wJ>@X`gfRcQ9YS_Z7Z>qMN^)`K7Sg z&F`P(^3O5yw0*9AdYeIyet+-szvc2n%->8xF2BL$>vF-;w$^fOzscqEt13s| zKXUnxyZjKpp3(Q2T>e3qU&{Pc`PVT2GhX}Cwz>ItF#p?0{BOAY4(99YZ&JR$&h=k6 z^HbKJ`IEf*S8MeqzPTe*diiM|cgqhkU*B_e%YP%21gL#WnXhlry8OXz{HO-dwxV~`^A~#gpECA^fURM^{%(ut-(>idCDlXSHr;vW{l54( zFz5?*{CbqXn&o%giylc#zx9S%n0^O$2>N*Z=KFC;983ea;+L>T?s(9=Li3LOP#pJ# z&q#sangU;v0>3K-eh+Z6Q|yx)FI!T`Z)5q-ant_6;_y!I=dj7)a5Aj3t zCmEMpe*en&&-J$}6PGC=+Nb>&Sbm27%B17y`3u-z@Y7d)`=`*84V>)x57wjSIp_#6 zK9sLn>+u~p{a*_t|2X4v2X-dofgSpjA*AQiY^=!BpROl- zDz3ZIqvtJr()ddFQ;h5R3ix)$qqwz7k6hD!1bAP5cr*pRKL!4k6!@VO_&0%*oo8?% zkRI{d_ZT-fL>))Zhv1)J{BuLKxTEJmB!9~IZy1;FdAz~+;E6_FzDe^N#($-mOs@rI8Mv*e(v@*_)^-?Ct7+ALQ7>8^d4PIGU*W6e=XHI2pb9Ge%4x%fu z6~{Sr_4<1%Ypd$&_2HSjx1w#6cdw0eo6S!1C!1(X^W;3pj3~B2mM}gQl z@ea6;Gc9+Y*GxrucWHcr(cG{JJJMJ!4mi!{Rl7NC%Jp#$KHZbV!5(DXVGKUe6_9O2nOARfXq@FVya2*g7; zebr5HbaDNl+hN_6zy~o-@-(H1yv*-})6^w6%{TNAPV@JOtsOpGl$ryhom{fQz0% zyndu|z5TAxgL})J?ZLg}KJCH1@~1qwS3b<^P%76ezs7@m<-hE~z2ntU5AK!!od@^o zAH<7MD%UH2y9f8`ukqks`NurCSN~BD?v=md!M*zPcpYuqv&4f>@U+(_Joq>d{*ni$ zC8@OUgS;Lm{bN1&ml&7$l={z+<7#=UXAWr@-G%fq#w$#FF3;E{4? z@;YQH<950IjJRI2^O8*?G$znPa|4<83; zd9i_bMJyoY?w~;z&ph+t>L1JcZ?*7$WO}KEzrpe=EIiKZLYc3m+*OQMS@N&5v5gk) z<8^J!!WXfg9Tu*rAUt0%A8x&7QUl@nlKF7)O>FKSlKf=O?a4^!jBt0UZ#dcnA;q=Gx z=()whi0Gk#r`Z3!7XA+7iv2Bm7IU1)xwqii zl)w|Rk=$vKtyb34c98gn@hR$NzX=0UfvJgYvEt#azAU~ z60cvd@V#8_K@0y5`{zju-^KPHv+&2cT~1o~bfzy@_|qI$zq9Zf)^mk%A}JK){mx*{ zC;s^r$H{mLmw3C;!l$r*7BMdR<-L-OqqhEymY&;K&wUm?k?995{qjERo0h!T|D1(O z|N4oAzsvQ#Y~g&|mg^T`} zg)iiOw8PRb?-Rdh$&3ESEnM_>S@d5`(JB`^9fS-9xGV&M-lZT^_8{xb$T zZsq;y7_Oh~|6&Ul{iPPZj2w<nZeHvT#|ST(R)CS$}{(#Siixd<^4KFR`=O!bN|nh0EWe zS!(H*_wUt~yy%Zv_;q)1V7I?(ZG9L`FaM^cFvhXRaXO@M_J|tq{*PG&;l@>1hvJDn4`?612xa`Xw zvT)g#{g;K)eII(V=p_UmsqX`ZbjDctQuf;{3%|^MzLjz5r*bcAt0g~_+wp!&Uha48 zv*e{8eci&p#Pl_e7GBHsx@_T>dA)SS!o{9J{Jv8BHiz4N7~|px zxnEae$^VS~u)xA)eE6t^|2_A+Z5A&3%FkK2>?`mP74=5bX)ip_VddY{w=ou zUl^DA%00s#OJ3@Q|KLqO;y0PULKglgw^t$KqF?Se-fYQ>{^b@f{;9NZ@lT_LpXYjQ zxA1Ftp51HVd5rI4T;xykYT&paNEO@WtK_yP9wT*k$3a-X@; zk{7?3zgnLdw`E`Xge70j{r8xK(|;>N&yOs;k^T0%g^y-CBYYn~;^%!H_bM!WAp32- zg&(5|;@NKD%UREZjEf)SzV|^(Uh36p;Zm>XEL`gKl7&mXX6G5Zq+awxvhz;s4N*FJ$?*EPMgC z%kM2ccXK-q;rj{VpHmz^A;!gi`Ch=+EcpxLPC18s*pip?xBV9W1&;qGEIqez zyS!}4cd`Ayu;fjYInH~Qyp-#wOM7_4&$6xxLkcCu@94xZModfzSYLq$KUcS4+?aOIHI$U+O3_NuXPiMQPrE^+%+ z3zzsmZsF1&&s(_k_jGP&u~Wv42^KEn&q52AaZ=7-MUTuQyDfQ{2fu3JGS42jaGA%? zTez$T(%HFEuBKG+N91L_RAb??{@88dvd;Xfh0A*TxP{BU;Jk&)z9XIc z6S3(>_Ae7GT=x45EnLnMYAjsND|TDBoRfUj!sUGCxP{BP(|HS*bFK7r@@B%Ha-KH9 z!sQ%qp@qviVU2~$`Q&a3mvhmtTDY9Y9=C8g2R?7%a{ipo@8A?QZ{3K$E`iTjllfdPsV4j#ks^GxKjswaKec)-q2MU~`2K;%PB7C(Se;x;4 zM`0R&AGZj9IA;^SHnElUMAzd_64Bpb_uFNvw=G)%xG(!3_~j#jK0e6;_}7)R6ZT0+U0KpM&*m0Nb0BfPV$^Q%u=?ACU9FM*595 ax0qC(_aU1s5zRjPn34LvR~TtK|NjM)S?YNJ diff --git a/input.c b/input.c index bfae7eb..1bec771 100644 --- a/input.c +++ b/input.c @@ -5,7 +5,7 @@ * Last modified 9th September 2021 * * Contains functions for ensuring correct input arguments are given for - * each stage of the voronoi2 program. + * each stage of the voronoi2 program. Adapted from Grady's base code on Ed. * */ diff --git a/input.o b/input.o index a46796f0a8ae85dd177e258f6564522d68593110..325dbb47f8f935acdcbeb60b68960fe5217e05f2 100644 GIT binary patch delta 938 zcmZ9KOK1~e6oq?}hGuLrhMM_%Q}eJOq=g!~G0QRdh=K~bG7E|6LWF`YbR!DBHc~+o z4=%DPjUbAvDdWP85ML`7HX>pdg2hcm7cDL5(m&3Pi#ssqGUq%0y>pqlamYW|C`9~S zOH&VHG#7MY%MmQZvlPY4_%!Vge#U7q*c{nGfwTP)1%Bd4j6c!9zbhG*fo--9+4~lf zDMJgGOx5^{u)`|z4egZSHE~ZVx{j{xFohqfB2UYdt12^!8Q1V!B((1;dK`7PNLSEw zEBs6{?^Nb7He5sR;g}jfm&~wC>+j;>rZMb^yGPLmmQ3a7S#hh1Zc5K{%6~2XCFRee zJXYb$;yzLIE!ty6YNBiP0*DPQgSp7LXt-8Fy7u2ZiaHz4OP5JSKcH#pHK7L-{f<|b zE{c0b(GE83^gnRYMZPWUh06TG$#jW7DmN}ay4j?M?|@!v#+pp_XSx`=kRI1A;y#vmBPI@HFo~+>UG^3ojzO=!iEPq2SuHrI9m3=e*fAi$a4#rGd-d zpY@L@U>M$=*rAY|r{+$>u>593RS&DDf~9srk7369^c$EFWQBI2M0lsPLhE-NKYCO&Fl6%wE9DJ8kc5D9D z97p3n`7}p;Zm<4a-E2JB>{v=|vMy*_t6tycWujisO@)cBp)Xx98|{AnG^*(W?MFTB z&_$S?4n2jd>I5pPPNUxGn7KCJdkR*jKx1$-PT*M#wGJB-nH)``o^hxFGwaYITvdBf TQFRXWtYhx$@Hf9hHP!haL57Ro diff --git a/main.c b/main.c index 24d23a2..1a0c4f0 100644 --- a/main.c +++ b/main.c @@ -12,14 +12,6 @@ * */ -#ifndef DCEL_HEADER -#include "dcel.h" -#endif - -#ifndef COMMON_HEADER -#include "common.h" -#endif - #ifndef VORONOI_HEADER #include "voronoi.h" #endif @@ -28,38 +20,6 @@ #include "input.h" #endif -// int main(int argc, char **argv) { -// /* Input and output files */ -// FILE *datasetFile = NULL, *polygonFile = NULL, *outputFile = NULL; -// checkInputArgs(argc, argv, &datasetFile, &polygonFile, &outputFile); - -// /* Stores information about the towers given in dataset file */ -// tower_t **towers = malloc(sizeof(*towers)); -// checkNullPointer(towers); -// int numTowers = 0; -// towers = readTowers(towers, datasetFile, &numTowers); - -// /* Stores information about the vertices in the polygon file */ -// vertex_t **vertices = malloc(sizeof(*vertices)); -// checkNullPointer(vertices); -// int numVertices = 0; -// vertices = readPolygon(vertices, polygonFile, &numVertices); - -// /* Create DCEL structure from vertices */ - -// /* Check for splits, split the polygon if needed */ - -// /* Counts towers in each polygon, outputs to outputFile */ - -// /* Cleaning up data */ -// freeTowers(towers, numTowers); -// freeVertices(vertices, numVertices); -// fclose(datasetFile); -// fclose(polygonFile); -// fclose(outputFile); -// return 0; -// } - int main(int argc, char **argv) { /* Ensure input arguments are correct */ if (argc == 1) { @@ -96,7 +56,7 @@ int main(int argc, char **argv) { /* Return error if stage number isn't defined. */ case STAGE_ERROR: default: - fprintf(stderr, "Stage was not handled ENUM value (%d)\n", stage); + printArgError(stage, "Invalid stage entered."); exit(EXIT_FAILURE); } diff --git a/main.o b/main.o index d5ba5aca223ac906d1433353b9f2aade36c06042..4cceff861a9ebde742b04165eeb6c3f7ce7353d3 100644 GIT binary patch delta 1753 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 diff --git a/output.txt b/output.txt index e69de29..5080ec9 100644 --- a/output.txt +++ b/output.txt @@ -0,0 +1,6 @@ +From Edge 0 (140.900000, -34.700000) to Edge 2 (150.000000, -34.700000) +From Edge 0 (140.900000, -35.200000) to Edge 2 (150.000000, -35.200000) +From Edge 1 (147.100000, -33.900000) to Edge 3 (147.100000, -39.200000) +From Edge 1 (147.100000, -33.900000) to Edge 3 (147.100000, -39.200000) +From Edge 1 (147.600000, -33.900000) to Edge 3 (147.600000, -39.200000) +From Edge 1 (146.900000, -33.900000) to Edge 3 (141.600000, -39.200000) diff --git a/towers.c b/towers.c index 0d66bcb..e9dc503 100644 --- a/towers.c +++ b/towers.c @@ -1,4 +1,13 @@ - +/* voronoi.c + * + * Created by Rory Healy (healyr@student.unimelb.edu.au) + * Created on 11th September 2021 + * Last modified 13th September 2021 + * + * Contains functions for reading a CSV of watchtower information into an + * array of towers. + * + */ #ifndef TOWERS_HEADER #include "towers.h" @@ -10,7 +19,7 @@ #define NUM_CSV_FIELDS 6 tower_t **readTowers(tower_t **towers, FILE *datasetFile, int *numTowers) { - /* Maximum length of a single CSV line */ + /* Maximum length of a single CSV line (+1 for null char in string) */ size_t lineBufferSize = MAX_CSV_ENTRY_LEN + 1; /* Stores the current line from the CSV */ @@ -22,7 +31,7 @@ tower_t **readTowers(tower_t **towers, FILE *datasetFile, int *numTowers) { /* Discard the header line, then read the rest of the CSV */ getline(&lineBuffer, &lineBufferSize, datasetFile); while (getline(&lineBuffer, &lineBufferSize, datasetFile) > 0) { - /* Check if there enough space in the towers array */ + /* Ensure there is enough space in the towers array */ if (*numTowers == maxSizetowers) { maxSizetowers *= 2; tower_t **temp = realloc(towers, maxSizetowers * sizeof(*towers)); @@ -34,7 +43,7 @@ tower_t **readTowers(tower_t **towers, FILE *datasetFile, int *numTowers) { towers[*numTowers] = malloc(sizeof(*towers[*numTowers])); readCurrentTower(lineBuffer, towers[*numTowers]); - *numTowers += 1; + *numTowers += 1; } free(lineBuffer); return towers; diff --git a/towers.o b/towers.o index 04f55abc1666ad5e478016eeeb97b1303d5bb9df..32c15bb7a03a4bf6c21109ec958cbda33fb3d90d 100644 GIT binary patch delta 1172 zcmZ8fO-NKx6u##@d-HT`oR`Y&&5twrJA!4FHi*THwNOEbp&)+(eDE{bMX(IPi(jG&)Io3MN5otecwi*wI8-#O>|?tSlX|HuBN z7_2;RK34(@*&8LOm3f%3qlW3<#hB-0dRJpCx_^clzH%AHm~NKH4iPhEROrhh@W~j) z4S7g=>mCd;Lpoy>GK2A;j5TL~(x%IzsyXNV)XUZ=u&yw;f?(Va(yJSls1XC>_t@$$oBNl`|CWb{f@XAs8EW>jzB zL)m}k84aqk-QHVz_MPtm(cR_Mg-V5^;^*(kkjVOB>g zGy>mnG8DJ(E7(KgS;wCt-u6mCy@YNl^*5CNz|9a(|5nf~n%Yz97sNfJ8KhIT$(CWt z!*mvOo0PXG^?S6x%dO)^*s>>-o=!<5>>BQbxxJvE^DfAi(W>G0nt}#M_Y3S6=q8~B zwKs`<2PbQI-**M2#Z1qCea6(gR4Vli;;O@(;5x3Lr-H%)n9BA= zJQ{q!)S*3Kn5yl8JGfdKFJ0oUsAu@8HV*sHs!KowQ^F_F5&kUZgujkfeWLV9x!b#l ngY|LfK&L(d!LRo#sTHh+f{38;0c{s*3sngyH4BLk zD2kPKIEsZ9@v$j_LWm0smC{|i6p9oVf^Kx-!XSw4M$gTh$zm?#+_pgRVz(Cx$gFA)!S(L4#gJ~A(|?)!W#<8Wt*TNgttn4 zNsEwN!&$uJt24(`A*$>=EZ2&a<`m!hqPcUSiv$&Gk`8N^iF>u}a)l1BJSc}+Do;fh zznANEL?04StmAgQjvjejvHEM}0q6|abkt6}f}JJtc(tT*YyyQG{c0uzbhC{MLexnJ z!GJXDjI`9!fW-&&FzkN8CaF-Zr5xv7x5=bxJ$Lecsa37{ob4dQ4%lB!$zLbgxAAVj zd=RR&k}Eq*mU;?d3nKbh;g5Dyfk2@zFs<&oGduusqhXn<}B7jGz@h04ZFfcnphS9sKBzjKEKvh$M}t{6d|ICg;x(qB^|77ZKf9acR7qZ{Wv> zp8MpY8=UXB_Se~$mwh@N&+xq~d0)!p(es=;&&Sb+c>kb1*9r$b;syg~MRnsU%N*Lv zZEoNi(HR%L%X9&YL|?mT6JKQ+n;UdvovCB=9{2r$CmZyk-!969MMde~E6Q%2YnZP6 z58P`%=BZboiyr1)L->_w+C^`2?{TbY)FE4FZ}cg!g^A{WpkX352y>W?CH?cdZE78t zV@U{NF_xmQHqnxTQOr<0jd_Z5SZqo8-vn*#6YPyAVE{An6pUlO6pIw^V`6U#mM}w6 Q!#u@qEK>Z1iPnAp0iI%`*#H0l diff --git a/voronoi.c b/voronoi.c index 78ef41f..abeedd6 100644 --- a/voronoi.c +++ b/voronoi.c @@ -2,75 +2,32 @@ * * Created by Rory Healy (healyr@student.unimelb.edu.au) * Created on 12th August 2021 - * Last modified 11th September 2021 + * Last modified 13th September 2021 * * Contains functions involving the generation of the Voronoi diagram, and * running each stage of the assignment. * */ -#ifndef COMMON_HEADER -#include "common.h" -#endif - #ifndef VORONOI_HEADER #include "voronoi.h" #endif -vertex_t **readPoints(vertex_t **points, FILE *pointsFile, int *numPoints) { - /* Initial size of buffer is 1 as getline() reallocs as needed */ - size_t lineBufferSize = 1; - - /* Stores the current line from the points file */ - char *lineBuffer = malloc(lineBufferSize * sizeof(*lineBuffer)); - checkNullPointer(lineBuffer); - - /* Assuming that pointsFile is valid, there must be at least two points */ - int maxSizePoints = 2; - - while (getline(&lineBuffer, &lineBufferSize, pointsFile) > 0) { - /* Check if there is enough space in the points array */ - if (*numPoints == maxSizePoints) { - maxSizePoints *= 2; - vertex_t **temp = realloc(points, maxSizePoints * sizeof(*points)); - checkNullPointer(temp); - points = temp; - } - - double xCoordinateA, yCoordinateA, xCoordinateB, yCoordinateB; - sscanf(lineBuffer, "%lf %lf %lf %lf", &xCoordinateA, &yCoordinateA, \ - &xCoordinateB, &yCoordinateB); - - points[*numPoints] = malloc(sizeof(*points[*numPoints])); - points[*numPoints]->x = xCoordinateA; - points[*numPoints]->y = yCoordinateA; - *numPoints += 1; - - points[*numPoints] = malloc(sizeof(*points[*numPoints])); - points[*numPoints]->x = xCoordinateB; - points[*numPoints]->y = yCoordinateB; - *numPoints += 1; - } - - free(lineBuffer); - return points; -} - void stage1PrintBisector(bisector_t *bisector, FILE *outputFile) { if (bisector->isSlopeInfinite) { /* Cannot print infinite slope, so print only x-intercept */ - fprintf(outputFile, "x = %lf\n", bisector->midX); + fprintf(outputFile, "x = %lf\n", bisector->mid->x); } else { fprintf(outputFile, "y = %lf * (x - %lf) + %lf\n", \ - bisector->slope, bisector->midX, bisector->midY); + bisector->slope, bisector->mid->x, bisector->mid->y); } } -void freePoints(vertex_t **points, int numPoints) { - for (int i = 0; i < numPoints; i++) { - free(points[i]); - } - free(points); +void stage2PrintIntersection(intersection_t *intersection, FILE *outputFile) { + fprintf(outputFile, "From Edge %d (%lf, %lf) to Edge %d (%lf, %lf)\n", \ + intersection->fromEdge, intersection->fromPoint->x, \ + intersection->fromPoint->y, intersection->toEdge, \ + intersection->toPoint->x, intersection->toPoint->y); } void stage1(char *pointsFileName, char *outputFileName) { @@ -84,23 +41,27 @@ void stage1(char *pointsFileName, char *outputFileName) { int numPoints = 0; points = readPoints(points, pointsFile, &numPoints); + /* There are half as many bisectors as points */ + int numBisectors = numPoints / 2; + bisector_t **bisectors = malloc(sizeof(*bisectors) * numBisectors); + checkNullPointer(bisectors); + bisectors = getBisectors(bisectors, points, numBisectors); + /* For each pair, calculate and print the bisector to outputFile */ - for (int i = 0; i < numPoints; i += 2) { - bisector_t *currBisector = getBisector(points[i], points[i + 1]); - stage1PrintBisector(currBisector, outputFile); - free(currBisector); + for (int i = 0; i < numBisectors; i++) { + stage1PrintBisector(bisectors[i], outputFile); } /* Clean up */ freePoints(points, numPoints); + freeBisectors(bisectors, numBisectors); fclose(pointsFile); fclose(outputFile); } void stage2(char *pointsFileName, char *polygonFileName, char *outputFileName) { - FILE *pointsFile = NULL, *polygonFile = NULL, *outputFile = NULL; + FILE *pointsFile = NULL, *outputFile = NULL; pointsFile = safeFileOpen(&pointsFile, pointsFileName, "r"); - polygonFile = safeFileOpen(&polygonFile, polygonFileName, "r"); outputFile = safeFileOpen(&outputFile, outputFileName, "w"); /* Points are given as pairs, so initialise 2 points */ @@ -109,17 +70,32 @@ void stage2(char *pointsFileName, char *polygonFileName, char *outputFileName) { int numPoints = 0; points = readPoints(points, pointsFile, &numPoints); + /* There are half as many bisectors as points */ + int numBisectors = numPoints / 2; + bisector_t **bisectors = malloc(sizeof(*bisectors) * numBisectors); + checkNullPointer(bisectors); + bisectors = getBisectors(bisectors, points, numBisectors); + /* Construct the DCEL from the polygon file */ DCEL_t *dcel = readPolygonFile(polygonFileName); /* Calculate and print intersections to the output file */ - + intersection_t **intersections = malloc(sizeof(*intersections)); + checkNullPointer(intersections); + int numIntersections = 0; + intersections = getIntersections(intersections, &numIntersections, bisectors, numBisectors, dcel, DEFAULT_FACE, \ + DEFAULTMINLENGTH); + + for (int i = 0; i < numIntersections; i++) { + stage2PrintIntersection(intersections[i], outputFile); + } /* Clean up */ freePoints(points, numPoints); + freeBisectors(bisectors, numBisectors); + freeIntersections(intersections, numIntersections); freeDCEL(dcel); fclose(pointsFile); - fclose(polygonFile); fclose(outputFile); } diff --git a/voronoi.h b/voronoi.h index 8f059ac..7088143 100644 --- a/voronoi.h +++ b/voronoi.h @@ -5,14 +5,11 @@ #ifndef VORONOI_HEADER #define VORONOI_HEADER -/* Reads a points file and stores the information in the points array */ -vertex_t **readPoints(vertex_t **points, FILE *pointsFile, int *numPoints); - /* Prints bisectors to an output file */ void stage1PrintBisector(bisector_t *bisector, FILE *outputFile); -/* Frees all points from a points array */ -void freePoints(vertex_t **points, int numPoints); +/* Prints intersections to an output file */ +void stage2PrintIntersection(intersection_t *intersection, FILE *outputFile); /* Outputs the bisector equations from pointsFile into outputFile */ void stage1(char *pointsFileName, char *outputFileName); diff --git a/voronoi.o b/voronoi.o index 4b32af21370979d2b2f98ede11da0fdb97c1df4d..bd233458d34b814f4f823169176895e37959bd9f 100644 GIT binary patch literal 14544 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 diff --git a/voronoi2 b/voronoi2 index a1adcbe65b075574874aac7b7252f5b83714411d..ed784ff39edd8ff621ca2c900c8ea34409a04ab2 100755 GIT binary patch literal 61896 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 H09yYK%t0js literal 63952 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 SNj~;#C4ajyRDoCd@Bam|(npv8