2021-09-08 21:48:00 +10:00
|
|
|
/* voronoi.c
|
|
|
|
*
|
|
|
|
* Created by Rory Healy (healyr@student.unimelb.edu.au)
|
|
|
|
* Created on 12th August 2021
|
2021-09-11 22:47:44 +10:00
|
|
|
* Last modified 11th September 2021
|
2021-09-08 21:48:00 +10:00
|
|
|
*
|
2021-09-09 17:10:24 +10:00
|
|
|
* Contains functions involving the generation of the Voronoi diagram, and
|
|
|
|
* running each stage of the assignment.
|
|
|
|
*
|
2021-09-08 21:48:00 +10:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef COMMON_HEADER
|
|
|
|
#include "common.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef VORONOI_HEADER
|
|
|
|
#include "voronoi.h"
|
|
|
|
#endif
|
|
|
|
|
2021-09-09 17:10:24 +10:00
|
|
|
vertex_t **readPoints(vertex_t **points, FILE *pointsFile, int *numPoints) {
|
2021-09-11 22:47:44 +10:00
|
|
|
/* Initial size of buffer is 1 as getline() reallocs as needed */
|
|
|
|
size_t lineBufferSize = 1;
|
2021-09-09 17:10:24 +10:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2021-09-11 22:47:44 +10:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-09 17:10:24 +10:00
|
|
|
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");
|
|
|
|
|
2021-09-09 21:23:53 +10:00
|
|
|
/* Points are given as pairs, so initialise 2 points */
|
|
|
|
vertex_t **points = malloc(sizeof(*points) * 2);
|
2021-09-09 17:10:24 +10:00
|
|
|
checkNullPointer(points);
|
|
|
|
int numPoints = 0;
|
2021-09-09 21:23:53 +10:00
|
|
|
points = readPoints(points, pointsFile, &numPoints);
|
|
|
|
|
|
|
|
/* For each pair, calculate and print the bisector to outputFile */
|
|
|
|
for (int i = 0; i < numPoints; i += 2) {
|
2021-09-11 22:47:44 +10:00
|
|
|
bisector_t *currBisector = getBisector(points[i], points[i + 1]);
|
|
|
|
stage1PrintBisector(currBisector, outputFile);
|
|
|
|
free(currBisector);
|
2021-09-09 21:23:53 +10:00
|
|
|
}
|
2021-09-09 17:10:24 +10:00
|
|
|
|
2021-09-11 22:47:44 +10:00
|
|
|
/* Clean up */
|
2021-09-09 17:10:24 +10:00
|
|
|
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");
|
|
|
|
|
2021-09-11 22:47:44 +10:00
|
|
|
/* 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 */
|
2021-09-09 17:10:24 +10:00
|
|
|
|
|
|
|
|
2021-09-11 22:47:44 +10:00
|
|
|
/* Clean up */
|
|
|
|
freePoints(points, numPoints);
|
|
|
|
freeDCEL(dcel);
|
2021-09-09 17:10:24 +10:00
|
|
|
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");
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-09-11 22:47:44 +10:00
|
|
|
/* Clean up */
|
2021-09-09 17:10:24 +10:00
|
|
|
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");
|
|
|
|
|
|
|
|
|
2021-09-11 22:47:44 +10:00
|
|
|
|
|
|
|
/* Clean up */
|
2021-09-09 17:10:24 +10:00
|
|
|
fclose(dataFile);
|
|
|
|
fclose(polygonFile);
|
|
|
|
fclose(outputFile);
|
|
|
|
}
|