Task 2 completed
This commit is contained in:
parent
b1697a0c30
commit
11b8feaa6e
18 changed files with 370 additions and 457 deletions
46
.vscode/launch.json
vendored
Normal file
46
.vscode/launch.json
vendored
Normal file
|
@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
26
Makefile
26
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:
|
# Link command:
|
||||||
voronoi2: common.o towers.o dcel.o voronoi.o input.o main.o
|
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
|
common.o: common.c
|
||||||
gcc -Wall -Wextra -Werror -pedantic -g -o common.o common.c -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
|
voronoi.o: voronoi.c
|
||||||
gcc -Wall -Wextra -Werror -pedantic -g -o voronoi.o voronoi.c -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
|
input.o: input.c
|
||||||
gcc -Wall -Wextra -Werror -pedantic -g -o input.o input.c -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
|
||||||
|
|
7
common.h
7
common.h
|
@ -19,13 +19,6 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MATH_HEADER
|
|
||||||
#define MATH_HEADER
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef COMMON_HEADER
|
#ifndef COMMON_HEADER
|
||||||
#define COMMON_HEADER
|
#define COMMON_HEADER
|
||||||
|
|
||||||
|
|
BIN
common.o
BIN
common.o
Binary file not shown.
441
dcel.c
441
dcel.c
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* Created by Rory Healy (healyr@student.unimelb.edu.au)
|
* Created by Rory Healy (healyr@student.unimelb.edu.au)
|
||||||
* Created on 25th August 2021
|
* Created on 25th August 2021
|
||||||
* Last modified 11th September 2021
|
* Last modified 13th September 2021
|
||||||
*
|
*
|
||||||
* Contains functions for the DCEL data structure, including initialisation,
|
* Contains functions for the DCEL data structure, including initialisation,
|
||||||
* splitting an edge, and identifying towers in faces.
|
* splitting an edge, and identifying towers in faces.
|
||||||
|
@ -16,74 +16,145 @@
|
||||||
#include "dcel.h"
|
#include "dcel.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deprecated by Grady's sample solution */
|
void freePoints(vertex_t **points, int numPoints) {
|
||||||
vertex_t **readPolygon(vertex_t **vertices, FILE *polygonFile, \
|
for (int i = 0; i < numPoints; i++) {
|
||||||
int *numVertices) {
|
free(points[i]);
|
||||||
double currentX, currentY;
|
}
|
||||||
int maxSizeVertices = 1;
|
free(points);
|
||||||
while ((fscanf(polygonFile, "%lf %lf", ¤tX, ¤tY)) != EOF) {
|
}
|
||||||
/* Check if there enough space in the towers array */
|
|
||||||
if (*numVertices == maxSizeVertices) {
|
void freeBisectors(bisector_t **bisectors, int numBisectors) {
|
||||||
maxSizeVertices *= 2;
|
for (int i = 0; i < numBisectors; i++) {
|
||||||
vertex_t **temp = realloc(vertices, \
|
free(bisectors[i]->mid);
|
||||||
maxSizeVertices * sizeof(*vertices));
|
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);
|
checkNullPointer(temp);
|
||||||
vertices = temp;
|
points = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The current vertex being filled in with information */
|
double xCoordinateA, yCoordinateA, xCoordinateB, yCoordinateB;
|
||||||
vertices[*numVertices] = malloc(sizeof(*vertices[*numVertices]));
|
sscanf(lineBuffer, "%lf %lf %lf %lf", &xCoordinateA, &yCoordinateA, \
|
||||||
vertices[*numVertices]->x = currentX;
|
&xCoordinateB, &yCoordinateB);
|
||||||
vertices[*numVertices]->y = currentY;
|
|
||||||
*numVertices += 1;
|
points[*numPoints] = malloc(sizeof(*points[*numPoints]));
|
||||||
}
|
points[*numPoints]->x = xCoordinateA;
|
||||||
return vertices;
|
points[*numPoints]->y = yCoordinateA;
|
||||||
}
|
*numPoints += 1;
|
||||||
|
|
||||||
void freeVertices(vertex_t **vertices, int numVertices) {
|
points[*numPoints] = malloc(sizeof(*points[*numPoints]));
|
||||||
for (int i = 0; i < numVertices; i++) {
|
points[*numPoints]->x = xCoordinateB;
|
||||||
free(vertices[i]);
|
points[*numPoints]->y = yCoordinateB;
|
||||||
}
|
*numPoints += 1;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return newBisector;
|
free(lineBuffer);
|
||||||
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Here on out is the base code from Grady, with some alterations from me */
|
/* 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 OUTSIDE (-1)
|
||||||
#define NODIAMETER (-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
|
This intersection is based on code by Joseph O'Rourke and is provided for use in
|
||||||
COMP20003 Assignment 2.
|
COMP20003 Assignment 2.
|
||||||
|
@ -246,15 +275,18 @@ enum intersectType intersects(halfEdge_t *he, bisector_t *b, \
|
||||||
double heEy = dcel->vertices[he->endVertex].y;
|
double heEy = dcel->vertices[he->endVertex].y;
|
||||||
|
|
||||||
/* Bisector x, y twin */
|
/* Bisector x, y twin */
|
||||||
double bSx = b->startX;
|
vertex_t *startPoint = getBisectorPoint(minLength, b, -1);
|
||||||
double bSy = b->startY;
|
vertex_t *endPoint = getBisectorPoint(minLength, b, 1);
|
||||||
double bEx = b->endX;
|
double bSx = startPoint->x;
|
||||||
double bEy = b->endY;
|
double bSy = startPoint->y;
|
||||||
|
double bEx = endPoint->x;
|
||||||
|
double bEy = endPoint->y;
|
||||||
|
|
||||||
|
free(startPoint);
|
||||||
|
free(endPoint);
|
||||||
|
|
||||||
/* Fill in segment. */
|
/* Fill in segment. */
|
||||||
// min-length not used here?
|
|
||||||
printf("In intersets(): minlength = %lf\n", minLength);
|
|
||||||
|
|
||||||
/* Parametric equation parameters */
|
/* Parametric equation parameters */
|
||||||
double t1, t2;
|
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() {
|
DCEL_t *newDCEL() {
|
||||||
/* Setup DCEL. */
|
/* Setup DCEL. */
|
||||||
DCEL_t *dcel = malloc(sizeof(*dcel));
|
DCEL_t *dcel = malloc(sizeof(*dcel));
|
||||||
|
@ -1026,82 +1011,72 @@ int inFace(DCEL_t *dcel, double x, double y, int faceIndex) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getDCELPointCount(DCEL_t *dcel) {
|
intersection_t **getIntersections(intersection_t **intersections, \
|
||||||
if (!dcel) {
|
int *numIntersections, bisector_t **bisectors, int numBisectors, \
|
||||||
return 0;
|
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 intersections;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double getDiameter(DCEL_t *dcel, int faceIndex) {
|
double getDiameter(DCEL_t *dcel, int faceIndex) {
|
||||||
|
|
139
dcel.h
139
dcel.h
|
@ -20,25 +20,15 @@ typedef struct vertex {
|
||||||
} vertex_t;
|
} vertex_t;
|
||||||
|
|
||||||
typedef struct bisector {
|
typedef struct bisector {
|
||||||
double startX;
|
vertex_t *mid;
|
||||||
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;
|
|
||||||
|
|
||||||
int isSlopeInfinite;
|
int isSlopeInfinite;
|
||||||
double slope;
|
double slope;
|
||||||
} bisector_t;
|
} bisector_t;
|
||||||
|
|
||||||
typedef struct halfEdgeLabel {
|
typedef struct halfEdge {
|
||||||
struct halfEdgeLabel *previous;
|
struct halfEdge *previous;
|
||||||
struct halfEdgeLabel *next;
|
struct halfEdge *next;
|
||||||
struct halfEdgeLabel *twin;
|
struct halfEdge *twin;
|
||||||
int face;
|
int face;
|
||||||
int edge;
|
int edge;
|
||||||
int startVertex;
|
int startVertex;
|
||||||
|
@ -47,6 +37,7 @@ typedef struct halfEdgeLabel {
|
||||||
|
|
||||||
typedef struct edge {
|
typedef struct edge {
|
||||||
halfEdge_t *halfEdge;
|
halfEdge_t *halfEdge;
|
||||||
|
tower_t *tower;
|
||||||
} edge_t;
|
} edge_t;
|
||||||
|
|
||||||
typedef struct face {
|
typedef struct face {
|
||||||
|
@ -63,7 +54,10 @@ typedef struct split {
|
||||||
} split_t;
|
} split_t;
|
||||||
|
|
||||||
typedef struct intersection {
|
typedef struct intersection {
|
||||||
vertex_t intersectionPoint;
|
int fromEdge;
|
||||||
|
int toEdge;
|
||||||
|
vertex_t *fromPoint;
|
||||||
|
vertex_t *toPoint;
|
||||||
} intersection_t;
|
} intersection_t;
|
||||||
|
|
||||||
typedef struct DCEL {
|
typedef struct DCEL {
|
||||||
|
@ -136,9 +130,6 @@ int vertexMatch(vertex_t *v1, vertex_t *v2);
|
||||||
/* Gets the string for the given bisector equation. */
|
/* Gets the string for the given bisector equation. */
|
||||||
char *getBisectorEquation(bisector_t *b);
|
char *getBisectorEquation(bisector_t *b);
|
||||||
|
|
||||||
/* Frees the given bisector. */
|
|
||||||
void freeBisector(bisector_t *bisector);
|
|
||||||
|
|
||||||
/* Representation of no face */
|
/* Representation of no face */
|
||||||
#define NOFACE (-1)
|
#define NOFACE (-1)
|
||||||
|
|
||||||
|
@ -148,18 +139,6 @@ void freeBisector(bisector_t *bisector);
|
||||||
/* Default minimum length for bisector in each direction */
|
/* Default minimum length for bisector in each direction */
|
||||||
#define DEFAULTMINLENGTH (200)
|
#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. */
|
/* Applies a given split to the DCEL. */
|
||||||
void applySplit(split_t *split, DCEL_t *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. */
|
/* Returns 1 if the given x,y point is inside the given face. */
|
||||||
int inFace(DCEL_t *dcel, double x, double y, int faceIndex);
|
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. */
|
/* Gets the diameter of the given face. */
|
||||||
double getDiameter(DCEL_t *dcel, int faceIndex);
|
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);
|
void incrementalVoronoi(DCEL_t *dcel, tower_t *watchTower);
|
||||||
|
|
||||||
/* Returns the number of vertices in the DCEL. */
|
/* O'Rourke's intersection functions */
|
||||||
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 */
|
|
||||||
/* Returns -1, 0 or 1, based on the area enclosed by the three points. 0 corresponds
|
/* Returns -1, 0 or 1, based on the area enclosed by the three points. 0 corresponds
|
||||||
to no area enclosed.
|
to no area enclosed.
|
||||||
*/
|
*/
|
||||||
|
@ -254,8 +187,42 @@ enum intersectType parallelIntersects(double heSx, double heSy, \
|
||||||
double heEx, double heEy, double bSx, double bSy, \
|
double heEx, double heEy, double bSx, double bSy, \
|
||||||
double bEx, double bEy, double *x, double *y);
|
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, \
|
enum intersectType intersects(halfEdge_t *he, bisector_t *b, \
|
||||||
DCEL_t *dcel, double minLength, double *x, double *y);
|
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
|
#endif
|
||||||
|
|
BIN
dcel.o
BIN
dcel.o
Binary file not shown.
2
input.c
2
input.c
|
@ -5,7 +5,7 @@
|
||||||
* Last modified 9th September 2021
|
* Last modified 9th September 2021
|
||||||
*
|
*
|
||||||
* Contains functions for ensuring correct input arguments are given for
|
* 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.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
BIN
input.o
BIN
input.o
Binary file not shown.
42
main.c
42
main.c
|
@ -12,14 +12,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DCEL_HEADER
|
|
||||||
#include "dcel.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef COMMON_HEADER
|
|
||||||
#include "common.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VORONOI_HEADER
|
#ifndef VORONOI_HEADER
|
||||||
#include "voronoi.h"
|
#include "voronoi.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,38 +20,6 @@
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#endif
|
#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) {
|
int main(int argc, char **argv) {
|
||||||
/* Ensure input arguments are correct */
|
/* Ensure input arguments are correct */
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
|
@ -96,7 +56,7 @@ int main(int argc, char **argv) {
|
||||||
/* Return error if stage number isn't defined. */
|
/* Return error if stage number isn't defined. */
|
||||||
case STAGE_ERROR:
|
case STAGE_ERROR:
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Stage was not handled ENUM value (%d)\n", stage);
|
printArgError(stage, "Invalid stage entered.");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
BIN
main.o
BIN
main.o
Binary file not shown.
|
@ -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)
|
17
towers.c
17
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
|
#ifndef TOWERS_HEADER
|
||||||
#include "towers.h"
|
#include "towers.h"
|
||||||
|
@ -10,7 +19,7 @@
|
||||||
#define NUM_CSV_FIELDS 6
|
#define NUM_CSV_FIELDS 6
|
||||||
|
|
||||||
tower_t **readTowers(tower_t **towers, FILE *datasetFile, int *numTowers) {
|
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;
|
size_t lineBufferSize = MAX_CSV_ENTRY_LEN + 1;
|
||||||
|
|
||||||
/* Stores the current line from the CSV */
|
/* 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 */
|
/* Discard the header line, then read the rest of the CSV */
|
||||||
getline(&lineBuffer, &lineBufferSize, datasetFile);
|
getline(&lineBuffer, &lineBufferSize, datasetFile);
|
||||||
while (getline(&lineBuffer, &lineBufferSize, datasetFile) > 0) {
|
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) {
|
if (*numTowers == maxSizetowers) {
|
||||||
maxSizetowers *= 2;
|
maxSizetowers *= 2;
|
||||||
tower_t **temp = realloc(towers, maxSizetowers * sizeof(*towers));
|
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]));
|
towers[*numTowers] = malloc(sizeof(*towers[*numTowers]));
|
||||||
|
|
||||||
readCurrentTower(lineBuffer, towers[*numTowers]);
|
readCurrentTower(lineBuffer, towers[*numTowers]);
|
||||||
*numTowers += 1;
|
*numTowers += 1;
|
||||||
}
|
}
|
||||||
free(lineBuffer);
|
free(lineBuffer);
|
||||||
return towers;
|
return towers;
|
||||||
|
|
BIN
towers.o
BIN
towers.o
Binary file not shown.
94
voronoi.c
94
voronoi.c
|
@ -2,75 +2,32 @@
|
||||||
*
|
*
|
||||||
* Created by Rory Healy (healyr@student.unimelb.edu.au)
|
* Created by Rory Healy (healyr@student.unimelb.edu.au)
|
||||||
* Created on 12th August 2021
|
* 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
|
* Contains functions involving the generation of the Voronoi diagram, and
|
||||||
* running each stage of the assignment.
|
* running each stage of the assignment.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef COMMON_HEADER
|
|
||||||
#include "common.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VORONOI_HEADER
|
#ifndef VORONOI_HEADER
|
||||||
#include "voronoi.h"
|
#include "voronoi.h"
|
||||||
#endif
|
#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) {
|
void stage1PrintBisector(bisector_t *bisector, FILE *outputFile) {
|
||||||
if (bisector->isSlopeInfinite) {
|
if (bisector->isSlopeInfinite) {
|
||||||
/* Cannot print infinite slope, so print only x-intercept */
|
/* 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 {
|
} else {
|
||||||
fprintf(outputFile, "y = %lf * (x - %lf) + %lf\n", \
|
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) {
|
void stage2PrintIntersection(intersection_t *intersection, FILE *outputFile) {
|
||||||
for (int i = 0; i < numPoints; i++) {
|
fprintf(outputFile, "From Edge %d (%lf, %lf) to Edge %d (%lf, %lf)\n", \
|
||||||
free(points[i]);
|
intersection->fromEdge, intersection->fromPoint->x, \
|
||||||
}
|
intersection->fromPoint->y, intersection->toEdge, \
|
||||||
free(points);
|
intersection->toPoint->x, intersection->toPoint->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stage1(char *pointsFileName, char *outputFileName) {
|
void stage1(char *pointsFileName, char *outputFileName) {
|
||||||
|
@ -84,23 +41,27 @@ void stage1(char *pointsFileName, char *outputFileName) {
|
||||||
int numPoints = 0;
|
int numPoints = 0;
|
||||||
points = readPoints(points, pointsFile, &numPoints);
|
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 each pair, calculate and print the bisector to outputFile */
|
||||||
for (int i = 0; i < numPoints; i += 2) {
|
for (int i = 0; i < numBisectors; i++) {
|
||||||
bisector_t *currBisector = getBisector(points[i], points[i + 1]);
|
stage1PrintBisector(bisectors[i], outputFile);
|
||||||
stage1PrintBisector(currBisector, outputFile);
|
|
||||||
free(currBisector);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
freePoints(points, numPoints);
|
freePoints(points, numPoints);
|
||||||
|
freeBisectors(bisectors, numBisectors);
|
||||||
fclose(pointsFile);
|
fclose(pointsFile);
|
||||||
fclose(outputFile);
|
fclose(outputFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stage2(char *pointsFileName, char *polygonFileName, char *outputFileName) {
|
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");
|
pointsFile = safeFileOpen(&pointsFile, pointsFileName, "r");
|
||||||
polygonFile = safeFileOpen(&polygonFile, polygonFileName, "r");
|
|
||||||
outputFile = safeFileOpen(&outputFile, outputFileName, "w");
|
outputFile = safeFileOpen(&outputFile, outputFileName, "w");
|
||||||
|
|
||||||
/* Points are given as pairs, so initialise 2 points */
|
/* Points are given as pairs, so initialise 2 points */
|
||||||
|
@ -109,17 +70,32 @@ void stage2(char *pointsFileName, char *polygonFileName, char *outputFileName) {
|
||||||
int numPoints = 0;
|
int numPoints = 0;
|
||||||
points = readPoints(points, pointsFile, &numPoints);
|
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 */
|
/* Construct the DCEL from the polygon file */
|
||||||
DCEL_t *dcel = readPolygonFile(polygonFileName);
|
DCEL_t *dcel = readPolygonFile(polygonFileName);
|
||||||
|
|
||||||
/* Calculate and print intersections to the output file */
|
/* 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 */
|
/* Clean up */
|
||||||
freePoints(points, numPoints);
|
freePoints(points, numPoints);
|
||||||
|
freeBisectors(bisectors, numBisectors);
|
||||||
|
freeIntersections(intersections, numIntersections);
|
||||||
freeDCEL(dcel);
|
freeDCEL(dcel);
|
||||||
fclose(pointsFile);
|
fclose(pointsFile);
|
||||||
fclose(polygonFile);
|
|
||||||
fclose(outputFile);
|
fclose(outputFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,11 @@
|
||||||
#ifndef VORONOI_HEADER
|
#ifndef VORONOI_HEADER
|
||||||
#define 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 */
|
/* Prints bisectors to an output file */
|
||||||
void stage1PrintBisector(bisector_t *bisector, FILE *outputFile);
|
void stage1PrintBisector(bisector_t *bisector, FILE *outputFile);
|
||||||
|
|
||||||
/* Frees all points from a points array */
|
/* Prints intersections to an output file */
|
||||||
void freePoints(vertex_t **points, int numPoints);
|
void stage2PrintIntersection(intersection_t *intersection, FILE *outputFile);
|
||||||
|
|
||||||
/* Outputs the bisector equations from pointsFile into outputFile */
|
/* Outputs the bisector equations from pointsFile into outputFile */
|
||||||
void stage1(char *pointsFileName, char *outputFileName);
|
void stage1(char *pointsFileName, char *outputFileName);
|
||||||
|
|
BIN
voronoi.o
BIN
voronoi.o
Binary file not shown.
BIN
voronoi2
BIN
voronoi2
Binary file not shown.
Loading…
Reference in a new issue