/* voronoi.c * * Created by Rory Healy (healyr@student.unimelb.edu.au) * Created on 12th August 2021 * Last modified 11th 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); } else { fprintf(outputFile, "y = %lf * (x - %lf) + %lf\n", \ bisector->slope, bisector->midX, bisector->midY); } } void freePoints(vertex_t **points, int numPoints) { for (int i = 0; i < numPoints; i++) { free(points[i]); } free(points); } void stage1(char *pointsFileName, char *outputFileName) { FILE *pointsFile = NULL, *outputFile = NULL; pointsFile = safeFileOpen(&pointsFile, pointsFileName, "r"); outputFile = safeFileOpen(&outputFile, outputFileName, "w"); /* Points are given as pairs, so initialise 2 points */ vertex_t **points = malloc(sizeof(*points) * 2); checkNullPointer(points); int numPoints = 0; points = readPoints(points, pointsFile, &numPoints); /* 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); } /* Clean up */ freePoints(points, numPoints); fclose(pointsFile); fclose(outputFile); } void stage2(char *pointsFileName, char *polygonFileName, char *outputFileName) { FILE *pointsFile = NULL, *polygonFile = 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 */ vertex_t **points = malloc(sizeof(*points) * 2); checkNullPointer(points); int numPoints = 0; points = readPoints(points, pointsFile, &numPoints); /* Construct the DCEL from the polygon file */ DCEL_t *dcel = readPolygonFile(polygonFileName); /* Calculate and print intersections to the output file */ /* Clean up */ freePoints(points, numPoints); freeDCEL(dcel); fclose(pointsFile); fclose(polygonFile); fclose(outputFile); } void stage3(char *dataFileName, char *polygonFileName, char *outputFileName) { FILE *dataFile = NULL, *polygonFile = NULL, *outputFile = NULL; dataFile = safeFileOpen(&dataFile, dataFileName, "r"); polygonFile = safeFileOpen(&polygonFile, polygonFileName, "r"); outputFile = safeFileOpen(&outputFile, outputFileName, "w"); /* Clean up */ fclose(dataFile); fclose(polygonFile); fclose(outputFile); } void stage4(char *dataFileName, char *polygonFileName, char *outputFileName) { FILE *dataFile = NULL, *polygonFile = NULL, *outputFile = NULL; dataFile = safeFileOpen(&dataFile, dataFileName, "r"); polygonFile = safeFileOpen(&polygonFile, polygonFileName, "r"); outputFile = safeFileOpen(&outputFile, outputFileName, "w"); /* Clean up */ fclose(dataFile); fclose(polygonFile); fclose(outputFile); }