Refactored headers for cleaner design, started stage 1
This commit is contained in:
parent
f7b25ecb92
commit
fe1f457038
19 changed files with 229 additions and 135 deletions
7
Makefile
7
Makefile
|
@ -16,12 +16,15 @@
|
|||
# gcc -Wall -Wextra -Werror -pedantic -g -o main.o main.c -c
|
||||
|
||||
# Link command:
|
||||
voronoi2: common.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 common.o
|
||||
voronoi2: common.o geometry.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 geometry.o common.o
|
||||
|
||||
common.o: common.c
|
||||
gcc -Wall -Wextra -Werror -pedantic -g -o common.o common.c -c
|
||||
|
||||
geometry.o: geometry.c
|
||||
gcc -Wall -Wextra -Werror -pedantic -g -o geometry.o geometry.c -c
|
||||
|
||||
dcel.o: dcel.c
|
||||
gcc -Wall -Wextra -Werror -pedantic -g -o dcel.o dcel.c -c
|
||||
|
||||
|
|
12
common.c
12
common.c
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* Created by Rory Healy (healyr@student.unimelb.edu.au)
|
||||
* Created on 25th August 2021
|
||||
* Last modified 8th September 2021
|
||||
* Last modified 9th September 2021
|
||||
*
|
||||
* Contains functions for general use throughout other files.
|
||||
*
|
||||
|
@ -12,10 +12,18 @@
|
|||
#include "common.h"
|
||||
#endif
|
||||
|
||||
/* Checks if a given pointer is null. Used for malloc() and realloc(). */
|
||||
void checkNullPointer(void *ptr) {
|
||||
if (!ptr) {
|
||||
fputs("Error: Cannot allocate memory.\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
FILE *safeFileOpen(FILE **f, char *fileName, char *mode) {
|
||||
*f = fopen(fileName, mode);
|
||||
if (*f == NULL) {
|
||||
fprintf(stderr, "Error: Unable to open file %s\n", fileName);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return *f;
|
||||
}
|
||||
|
|
11
common.h
11
common.h
|
@ -12,9 +12,20 @@
|
|||
|
||||
#endif
|
||||
|
||||
#ifndef STRING_HEADER
|
||||
#define STRING_HEADER
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef COMMON_HEADER
|
||||
#define COMMON_HEADER
|
||||
|
||||
/* Checks if a pointer assigned through dynamic memory allocation is NULL */
|
||||
void checkNullPointer(void *ptr);
|
||||
|
||||
/* Opens a file and checks if the file is safe to use */
|
||||
FILE *safeFileOpen(FILE **f, char *fileName, char *mode);
|
||||
|
||||
#endif
|
||||
|
|
BIN
common.o
BIN
common.o
Binary file not shown.
29
dcel.c
29
dcel.c
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* Created by Rory Healy (healyr@student.unimelb.edu.au)
|
||||
* Created on 25th August 2021
|
||||
* Last modified 25th August 2021
|
||||
* Last modified 9th September 2021
|
||||
*
|
||||
* Contains functions for the DCEL data structure, including creating,
|
||||
* splitting an edge, and identifying towers in faces.
|
||||
|
@ -17,36 +17,17 @@
|
|||
#include "common.h"
|
||||
#endif
|
||||
|
||||
struct halfEdge {
|
||||
halfEdge_t *previous;
|
||||
halfEdge_t *next;
|
||||
halfEdge_t *twin;
|
||||
int face;
|
||||
int edge;
|
||||
};
|
||||
|
||||
struct vertex {
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
struct edge {
|
||||
halfEdge_t halfEdge;
|
||||
};
|
||||
|
||||
struct face {
|
||||
halfEdge_t start;
|
||||
};
|
||||
|
||||
/* Reads the polygon file and stores the information in the vertices array. */
|
||||
vertex_t **readPolygon(vertex_t **vertices, FILE *polygonFile, int *numVertices) {
|
||||
vertex_t **readPolygon(vertex_t **vertices, FILE *polygonFile, \
|
||||
int *numVertices) {
|
||||
double currentX, currentY;
|
||||
int maxSizeVertices = 1;
|
||||
while ((fscanf(polygonFile, "%lf %lf", ¤tX, ¤tY)) != EOF) {
|
||||
/* Check if there enough space in the towers array */
|
||||
if (*numVertices == maxSizeVertices) {
|
||||
maxSizeVertices *= 2;
|
||||
vertex_t **temp = realloc(vertices, maxSizeVertices * sizeof(*vertices));
|
||||
vertex_t **temp = realloc(vertices, \
|
||||
maxSizeVertices * sizeof(*vertices));
|
||||
checkNullPointer(temp);
|
||||
vertices = temp;
|
||||
}
|
||||
|
|
28
dcel.h
28
dcel.h
|
@ -1,20 +1,32 @@
|
|||
#ifndef GEOMETRY_HEADER
|
||||
#include "geometry.h"
|
||||
#endif
|
||||
|
||||
#ifndef STDIO_HEADER
|
||||
|
||||
#define STDIO_HEADER
|
||||
#include <stdio.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef DCEL_HEADER
|
||||
|
||||
#define DCEL_HEADER
|
||||
|
||||
typedef struct halfEdge halfEdge_t;
|
||||
typedef struct vertex vertex_t;
|
||||
typedef struct edge edge_t;
|
||||
typedef struct face face_t;
|
||||
typedef struct halfEdge {
|
||||
struct halfEdge *previous;
|
||||
struct halfEdge *next;
|
||||
struct halfEdge *twin;
|
||||
int face;
|
||||
int edge;
|
||||
} halfEdge_t;
|
||||
|
||||
typedef struct edge {
|
||||
halfEdge_t halfEdge;
|
||||
} edge_t;
|
||||
|
||||
typedef struct face {
|
||||
halfEdge_t start;
|
||||
} face_t;
|
||||
|
||||
vertex_t **readPolygon(vertex_t **vertices, FILE *polygonFile, \
|
||||
int *numVertices);
|
||||
void freeVertices(vertex_t **vertices, int numVertices);
|
||||
|
||||
#endif
|
||||
|
|
BIN
dcel.o
BIN
dcel.o
Binary file not shown.
23
geometry.c
Normal file
23
geometry.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* geometry.c
|
||||
*
|
||||
* Created by Rory Healy (healyr@student.unimelb.edu.au)
|
||||
* Created on 9th September 2021
|
||||
* Last modified 9th September 2021
|
||||
*
|
||||
* A small library of functions used in the geometric construction of a
|
||||
* Voronoi diagram.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GEOMETRY_HEADER
|
||||
#include "geometry.h"
|
||||
#endif
|
||||
|
||||
#ifndef COMMON_HEADER
|
||||
#include "common.h"
|
||||
#endif
|
||||
|
||||
char *getBisectorEquation(vertex_t *vertexA, vertex_t *vertexB) {
|
||||
printf("x: %lf y: %lf\n", vertexA->x, vertexB->y);
|
||||
return "hi";
|
||||
}
|
9
geometry.h
Normal file
9
geometry.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef GEOMETRY_HEADER
|
||||
#define GEOMETRY_HEADER
|
||||
|
||||
typedef struct vertex {
|
||||
double x;
|
||||
double y;
|
||||
} vertex_t;
|
||||
|
||||
#endif
|
BIN
geometry.o
Normal file
BIN
geometry.o
Normal file
Binary file not shown.
15
input.c
15
input.c
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* Created by Rory Healy (healyr@student.unimelb.edu.au)
|
||||
* Created on 8th September 2021
|
||||
* Last modified 8th September 2021
|
||||
* Last modified 9th September 2021
|
||||
*
|
||||
* Contains functions for ensuring correct input arguments are given for
|
||||
* each stage of the voronoi2 program.
|
||||
|
@ -13,6 +13,10 @@
|
|||
#include "input.h"
|
||||
#endif
|
||||
|
||||
#ifndef COMMON_HEADER
|
||||
#include "common.h"
|
||||
#endif
|
||||
|
||||
#define STAGE_1_ARG_COUNT 4
|
||||
#define STAGE_2_ARG_COUNT 5
|
||||
#define STAGE_3_ARG_COUNT 5
|
||||
|
@ -90,12 +94,3 @@ int getExpectedArgs(enum stages stage) {
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
FILE *safeFileOpen(FILE **f, char *fileName, char *mode) {
|
||||
*f = fopen(fileName, mode);
|
||||
if (*f == NULL) {
|
||||
fprintf(stderr, "Error: Unable to open file %s\n", fileName);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return *f;
|
||||
}
|
||||
|
|
24
input.h
24
input.h
|
@ -1,24 +1,3 @@
|
|||
#ifndef STDIO_HEADER
|
||||
#define STDIO_HEADER
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef STDLIB_HEADER
|
||||
#define STDLIB_HEADER
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef STRING_HEADER
|
||||
|
||||
#define STRING_HEADER
|
||||
#include <string.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef INPUT_HEADER
|
||||
#define INPUT_HEADER
|
||||
|
||||
|
@ -42,7 +21,4 @@ int getExpectedArgs(enum stages stage);
|
|||
/* Prints the corresponding usage strings for a given stage */
|
||||
void printArgError(enum stages stage, char *errorMessage);
|
||||
|
||||
/* Opens a file and checks if the file is safe to use */
|
||||
FILE *safeFileOpen(FILE **f, char *fileName, char *mode);
|
||||
|
||||
#endif
|
||||
|
|
BIN
input.o
BIN
input.o
Binary file not shown.
48
main.c
48
main.c
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* Created by Rory Healy (healyr@student.unimelb.edu.au)
|
||||
* Created on 25th August 2021
|
||||
* Last modified 8th September 2021
|
||||
* Last modified 9th September 2021
|
||||
*
|
||||
* Lists the watchtowers that are in each face of the polygon.
|
||||
* The polygon can be split using a pair of integers, which represent
|
||||
|
@ -74,54 +74,24 @@ int main(int argc, char **argv) {
|
|||
/* Then run the program according to the stage given */
|
||||
switch(stage) {
|
||||
/* Expected usage: ./voronoi2 1 pointsFile outputFile */
|
||||
case STAGE_1: {
|
||||
FILE *pointsFile = NULL, *outputFile = NULL;
|
||||
pointsFile = safeFileOpen(&pointsFile, argv[2], "r");
|
||||
outputFile = safeFileOpen(&outputFile, argv[3], "w");
|
||||
|
||||
fclose(pointsFile);
|
||||
fclose(outputFile);
|
||||
case STAGE_1:
|
||||
stage1(argv[2], argv[3]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Expected usage: ./voronoi2 2 pointsFile polygonFile outputFile */
|
||||
case STAGE_2: {
|
||||
FILE *pointsFile = NULL, *polygonFile = NULL, *outputFile = NULL;
|
||||
pointsFile = safeFileOpen(&pointsFile, argv[2], "r");
|
||||
polygonFile = safeFileOpen(&polygonFile, argv[3], "r");
|
||||
outputFile = safeFileOpen(&outputFile, argv[4], "w");
|
||||
|
||||
fclose(pointsFile);
|
||||
fclose(polygonFile);
|
||||
fclose(outputFile);
|
||||
case STAGE_2:
|
||||
stage2(argv[2], argv[3], argv[4]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Expected usage: ./voronoi2 3 dataFile polygonFile outputFile */
|
||||
case STAGE_3: {
|
||||
FILE *dataFile = NULL, *polygonFile = NULL, *outputFile = NULL;
|
||||
dataFile = safeFileOpen(&dataFile, argv[2], "r");
|
||||
polygonFile = safeFileOpen(&polygonFile, argv[3], "r");
|
||||
outputFile = safeFileOpen(&outputFile, argv[4], "w");
|
||||
|
||||
fclose(dataFile);
|
||||
fclose(polygonFile);
|
||||
fclose(outputFile);
|
||||
case STAGE_3:
|
||||
stage3(argv[2], argv[3], argv[4]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Expected usage: /voronoi2 4 dataFile polygonFile outputFile */
|
||||
case STAGE_4: {
|
||||
FILE *dataFile = NULL, *polygonFile = NULL, *outputFile = NULL;
|
||||
dataFile = safeFileOpen(&dataFile, argv[2], "r");
|
||||
polygonFile = safeFileOpen(&polygonFile, argv[3], "r");
|
||||
outputFile = safeFileOpen(&outputFile, argv[4], "w");
|
||||
|
||||
fclose(dataFile);
|
||||
fclose(polygonFile);
|
||||
fclose(outputFile);
|
||||
case STAGE_4:
|
||||
stage4(argv[2], argv[3], argv[4]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return error if stage number isn't defined. */
|
||||
case STAGE_ERROR:
|
||||
|
|
BIN
main.o
BIN
main.o
Binary file not shown.
115
voronoi.c
115
voronoi.c
|
@ -2,9 +2,10 @@
|
|||
*
|
||||
* Created by Rory Healy (healyr@student.unimelb.edu.au)
|
||||
* Created on 12th August 2021
|
||||
* Last modified 25th August 2021
|
||||
* Last modified 9th September 2021
|
||||
*
|
||||
* Contains functions involving the reading of the dataset CSV file.
|
||||
* Contains functions involving the generation of the Voronoi diagram, and
|
||||
* running each stage of the assignment.
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -16,8 +17,6 @@
|
|||
#include "voronoi.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define BASE_10 10
|
||||
#define MAX_CSV_ENTRY_LEN 512
|
||||
#define MAX_FIELD_LEN 128
|
||||
|
@ -32,13 +31,12 @@ struct tower {
|
|||
double y;
|
||||
};
|
||||
|
||||
/* Reads the CSV file and stores the information in the towers array. */
|
||||
tower_t **readTowers(tower_t **towers, FILE *datasetFile, int *numTowers) {
|
||||
/* Maximum length of a single CSV line */
|
||||
size_t lineBufferSize = MAX_CSV_ENTRY_LEN + 1;
|
||||
|
||||
/* Stores the current line from the CSV */
|
||||
char *lineBuffer = malloc(lineBufferSize * sizeof(char));
|
||||
char *lineBuffer = malloc(lineBufferSize * sizeof(*lineBuffer));
|
||||
checkNullPointer(lineBuffer);
|
||||
|
||||
int maxSizetowers = 1;
|
||||
|
@ -57,15 +55,14 @@ tower_t **readTowers(tower_t **towers, FILE* datasetFile, int *numTowers) {
|
|||
/* The current tower being filled in with information */
|
||||
towers[*numTowers] = malloc(sizeof(*towers[*numTowers]));
|
||||
|
||||
readCurrentLine(lineBuffer, towers[*numTowers]);
|
||||
readCurrentTower(lineBuffer, towers[*numTowers]);
|
||||
*numTowers += 1;
|
||||
}
|
||||
free(lineBuffer);
|
||||
return towers;
|
||||
}
|
||||
|
||||
/* Takes a line from the CSV and converts the data into a tower_t format */
|
||||
void readCurrentLine(char* lineBuffer, tower_t* tower) {
|
||||
void readCurrentTower(char *lineBuffer, tower_t *tower) {
|
||||
/* Stores the current CSV field for the current line */
|
||||
char *token = strtok(lineBuffer, ",");
|
||||
size_t tokenLength;
|
||||
|
@ -120,3 +117,103 @@ void freeTowers(tower_t **towers, int numTowers) {
|
|||
}
|
||||
free(towers);
|
||||
}
|
||||
|
||||
vertex_t **readPoints(vertex_t **points, FILE *pointsFile, int *numPoints) {
|
||||
/* Current length of a single points line */
|
||||
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 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");
|
||||
|
||||
vertex_t **points = malloc(sizeof(*points));
|
||||
checkNullPointer(points);
|
||||
int numPoints = 0;
|
||||
// points = readPoints(points, pointsFile, &numPoints);
|
||||
|
||||
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");
|
||||
|
||||
|
||||
|
||||
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");
|
||||
|
||||
|
||||
|
||||
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");
|
||||
|
||||
|
||||
|
||||
fclose(dataFile);
|
||||
fclose(polygonFile);
|
||||
fclose(outputFile);
|
||||
}
|
||||
|
|
37
voronoi.h
37
voronoi.h
|
@ -1,25 +1,34 @@
|
|||
#ifndef STDIO_HEADER
|
||||
|
||||
#define STDIO_HEADER
|
||||
#include <stdio.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef STDLIB_HEADER
|
||||
|
||||
#define STDLIB_HEADER
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef DCEL_HEADER
|
||||
#include "dcel.h"
|
||||
#endif
|
||||
|
||||
#ifndef VORONOI_HEADER
|
||||
|
||||
#define VORONOI_HEADER
|
||||
|
||||
typedef struct tower tower_t;
|
||||
|
||||
/* Reads the CSV file and stores the information in the towers array */
|
||||
tower_t **readTowers(tower_t **towers, FILE *datasetFile, int *numTowers);
|
||||
void readCurrentLine(char* lineBuffer, tower_t* tower);
|
||||
|
||||
/* Reads the current row from the CSV into a new tower */
|
||||
void readCurrentTower(char *lineBuffer, tower_t *tower);
|
||||
|
||||
/* Takes a line from the CSV and converts the data into a tower_t format */
|
||||
void freeTowers(tower_t **towers, int numTowers);
|
||||
|
||||
/* Reads a points file and stores the information in the points array */
|
||||
vertex_t **readPoints(vertex_t **points, FILE *pointsFile, int *numPoints);
|
||||
|
||||
/* Outputs the bisector equations from pointsFile into outputFile */
|
||||
void stage1(char *pointsFileName, char *outputFileName);
|
||||
|
||||
/* Outputs the intersections the bisectors make with the polygon */
|
||||
void stage2(char *pointsFileName, char *polygonFileName, char *outputFileName);
|
||||
|
||||
/* Constructs a Voronoi diagram and prints the resulting diameters */
|
||||
void stage3(char *dataFileName, char *polygonFileName, char *outputFileName);
|
||||
|
||||
/* Same as stage3, but prints diameters in ascending order */
|
||||
void stage4(char *dataFileName, char *polygonFileName, char *outputFileName);
|
||||
|
||||
#endif
|
||||
|
|
BIN
voronoi.o
BIN
voronoi.o
Binary file not shown.
BIN
voronoi2
BIN
voronoi2
Binary file not shown.
Loading…
Reference in a new issue