From aa2690dbd3724b7ac2e16047fc86dc86bfc9b329 Mon Sep 17 00:00:00 2001 From: Rory Healy Date: Thu, 9 Sep 2021 21:23:53 +1000 Subject: [PATCH] Completed stage 1 --- dcel.o | Bin 7352 -> 7352 bytes geometry.c | 39 ++++++++++++++++++++++++++++++++++++--- geometry.h | 10 ++++++++++ geometry.o | Bin 3864 -> 4600 bytes output.txt | 6 ++++++ voronoi.c | 29 +++++++++++++++++------------ voronoi.h | 16 +++++++++++++--- voronoi.o | Bin 16024 -> 16920 bytes voronoi2 | Bin 33712 -> 34256 bytes 9 files changed, 82 insertions(+), 18 deletions(-) diff --git a/dcel.o b/dcel.o index bda734f713c1d1a341d894a0b4ff16c59e7b38d0..88feeaf856fd518146eab4412821c9420a839f97 100644 GIT binary patch delta 182 zcmdmCxx;e9au!CN$tzf7^>pOanHdd6)$@8*{XZ005#D B9k2iZ delta 182 zcmdmCxx;e9au!Cd$tzf7^|a*FnHdd6@Y(8*{XZ006^l B9v1)r diff --git a/geometry.c b/geometry.c index 8dfe276..ea75e12 100644 --- a/geometry.c +++ b/geometry.c @@ -17,7 +17,40 @@ #include "common.h" #endif -char *getBisectorEquation(vertex_t *vertexA, vertex_t *vertexB) { - printf("x: %lf y: %lf\n", vertexA->x, vertexB->y); - return "hi"; +bisector_t getBisector(vertex_t *pointA, vertex_t *pointB) { + bisector_t newBisector; + double midpointX = (pointA->x + pointB->x) / 2; + double midpointY = (pointA->y + pointB->y) / 2; + + newBisector.x = midpointX; + newBisector.y = 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 { + /* Slope of the line segment AB */ + double segmentSlope = \ + (pointB->y - pointA->y) / (pointB->x - pointA->x); + + /* Calculate orthogonal slope */ + newBisector.isSlopeInfinite = 0; + newBisector.slope = -1 / segmentSlope; + } + + return newBisector; } diff --git a/geometry.h b/geometry.h index ddd4b3d..f199c17 100644 --- a/geometry.h +++ b/geometry.h @@ -6,4 +6,14 @@ typedef struct vertex { double y; } vertex_t; +typedef struct bisector { + int isSlopeInfinite; + double slope; + double x; + double y; +} bisector_t; + +/* Calculates and returns the equation of a bisector of two points */ +bisector_t getBisector(vertex_t *vertexA, vertex_t *vertexB); + #endif \ No newline at end of file diff --git a/geometry.o b/geometry.o index 46d9a01e5cae9d3490b76db79a450b5440fa4d4f..5e75cfe7c709b6d43210cfa908550865093c81cb 100644 GIT binary patch literal 4600 zcmbVOVQdsd6rSC^ZMWRDckPwZT7nm$DuLU!KoC&sK|Q$=Fd#N5K_u7f_U>Z4S9kZI zC6b!{P#R*=OGqHbL@_Zzqe+easEGm%i4xSrs6UAQAtoj$F;@H`Dha+f`{sHb?iVk) zo%en7zIktEXJ>9Qx#wwBQJ64=^{_=GSjNUfi++N;3D&}vv%kWt{_Rgq|B{+MF_)Sy z&ZegO&!{j>%@Eem?C@3YO5=OPKZ$X#5f`SF~05&FX zla$f;#&Fo2Ki-PZV$*Q=k4qSI6X+ zaHJCA83HO71Ps4Xe3Fna=PIQ+^d73o#B7x}Ux#_uA*(b$guYgKdy?=bAD^9E#`~8? za0Ioq&xb9%Zml#&-77d&ONk&xqwVn<=EryP)l^F<#zMvbb}5ZYM?*BIHMBQ0DowSK z6)<{K(HermZNbNbTZ2jz%Bg3X;lsY@78p9Ph6RH?AYx2!VOoRegGGkWGQ`kY3WWtQ zOy$Wo(fdeSUlbE2TF>lk!z6Wjg;H&0Y}qD>2nM0pCRq4T7}EEFhOLJmf8&fVFiwb@ zSXzNa`yn_Q>x8GG{MS$qPkv0mk}E806-F)3nJ_aLT}C-XOn-va`H28%QAK~y=+W0r z>8q#o&~5-xecg<{dImw%Xnso%pVL=P>Bf}aenIaj=`AJf4A1Bt7xeZCy?IuT&FHN& zy1855Hl=Tv(j$F($7wxQ)Z4G|Mem$}jGip590qHS%@TDIln zGXT?0CbxZj%jWpzO|f`379UQ#6Lu!&6zoFLjTh}>d3z}CrJ-CGI$bZFc`-ib6g%H^ zyH&a%C-&ZJntw>%)1mq2Y!$wGevOrnswEnY@vC(ShxbKOMLp%Oy!^3dmh2Kd9nkQ@ z#kIS0*S7;mg2{Y@rYd-Txj-C0&!NRLlppcXqG3H~$m4y`L;6M}!36(?58^n-~aj&BS_(aT4T|&pX2OdPEp& z2M^y*qRjY?K}TXabc3bEDJZ=Xm+6T|hxcO+=Be!GE_#{`P4C*1`E z6(+|XhCZ3Y@ZU(^RiQ;!jvWB5YW;M@3O&|e2S2&~m#T~j6nlU^`i~G)n4EtE`l{uB zh4PDa!u&|d`A-0cV~RS#<@Ocj|5{2YplDA*bT$1M`k-)sSDMg?wgjERuZ;Vg^pza? za_l+a@IIFJ?2h&p%?F^T5e3$ sijxAn<~RKRCu(Iq?kV}(N67-|MIPkPxmo_>lGg17G?WAOHXW delta 1260 zcmZ8hT}TvB6uvXNvvX&6c6WAHT+PUpMzdARhtO2~*_G8XEXhR39#m}qKz4224a3Sr zC`_#MKv?(?K@X7-VZnw3f-m(F(OW&$TY?YT(?WsWJ9Cqo1NWZuecwIjp1IsRg`+D+ z9#r!y(o(Rze{M(7=5G|V`P{Cy5ZV3dRyr^V3fcmSxvSsDGMxv(wQt&2#29lsH-}V#uB3$q)+i^Hk_P{j%CxC z$d%k^HknSrg3#f<8qH**Qz2ydFko9A-q|#THXU&(xA{(|?WQbZ(s&uvi*IH2H38xk zI4}By20faUi(pSI4*o5UhP!+F!lB;bzOJqdk%8fXP`EcTj3zRq{}`=N4;9#dyqSi? ztYp~9_`Ppfh?2zU30cT+Ko34yx<@Hu9>eJwB8ewp3H!No@Emu;Hwi-lD>JXznv15j zFBp!S_%eo5Cf>zx&cshMeBH!v7ZJk3j2d!P3m`sw@v&uT0i5s&q0OggB@Arkqx}gc6zVL^{~RY zv+^KbbE?uEmhNQujw{wQDwms^($H)c}eMbD)cBE>)^w4~5(rx~og& zCop*3ZPFzs4C%tSTjif%SSG?7Cd|MWccXNQUN2%*#&(Lz4_Qf<#YV>jj#yz?Y2$BM n;WKf0Qry#K&$BGj$&jZ(+SGq32(=n*c~t2Wd)!+_TeAEIzwF!^ diff --git a/output.txt b/output.txt index e69de29..7c243ae 100644 --- a/output.txt +++ b/output.txt @@ -0,0 +1,6 @@ +y = 0.000000 * (x - 145.600000) + -34.700000 +y = 0.000000 * (x - 145.600000) + -35.200000 +x = 147.100000 +x = 147.100000 +x = 147.600000 +y = 1.000000 * (x - 147.600000) + -33.200000 diff --git a/voronoi.c b/voronoi.c index 816641e..c012bb0 100644 --- a/voronoi.c +++ b/voronoi.c @@ -22,15 +22,6 @@ #define MAX_FIELD_LEN 128 #define NUM_CSV_FIELDS 6 -struct tower { - char *id; - char *postcode; - char *manager; - int population; - double x; - double y; -}; - 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; @@ -120,7 +111,7 @@ void freeTowers(tower_t **towers, int numTowers) { vertex_t **readPoints(vertex_t **points, FILE *pointsFile, int *numPoints) { /* Current length of a single points line */ - size_t lineBufferSize = 1; + size_t lineBufferSize = 50; /* Stores the current line from the points file */ char *lineBuffer = malloc(lineBufferSize * sizeof(*lineBuffer)); @@ -169,10 +160,24 @@ void stage1(char *pointsFileName, char *outputFileName) { pointsFile = safeFileOpen(&pointsFile, pointsFileName, "r"); outputFile = safeFileOpen(&outputFile, outputFileName, "w"); - vertex_t **points = malloc(sizeof(*points)); + /* 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); + 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]); + + /* Cannot print infinite slope, so print only x-intercept */ + if (currBisector.isSlopeInfinite) { + fprintf(outputFile, "x = %lf\n", currBisector.x); + } else { + fprintf(outputFile, "y = %lf * (x - %lf) + %lf\n", \ + currBisector.slope, currBisector.x, currBisector.y); + } + } freePoints(points, numPoints); fclose(pointsFile); diff --git a/voronoi.h b/voronoi.h index a5e8d0c..905c1b8 100644 --- a/voronoi.h +++ b/voronoi.h @@ -5,20 +5,30 @@ #ifndef VORONOI_HEADER #define VORONOI_HEADER -typedef struct tower tower_t; +typedef struct tower { + char *id; + char *postcode; + char *manager; + int population; + double x; + double y; +} tower_t; /* Reads the CSV file and stores the information in the towers array */ tower_t **readTowers(tower_t **towers, FILE *datasetFile, int *numTowers); -/* Reads the current row from the CSV into a new tower */ +/* Reads the current row from the CSV and converts it 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 */ +/* Frees all towers in a towers array */ 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); +/* Frees all points from a points array */ +void freePoints(vertex_t **points, int numPoints); + /* Outputs the bisector equations from pointsFile into outputFile */ void stage1(char *pointsFileName, char *outputFileName); diff --git a/voronoi.o b/voronoi.o index 7a5cc090f4018ec4a16809219fbc4514b8498fa0..707d2cc7a57608821c2dc9f1e5d43e9f6a687335 100644 GIT binary patch delta 5452 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 delta 4544 zcmZ`+3v3is6n$^D-R`GA+ZCouyY12zDb;qn1-1xfKL}D{K}h^yB!WaiVk3gleiVix zQQO++y7q8J5R(?&?F3P=J8Vqz3OkrGAl|K7a&w#1^h~e$ z$VCYGo*ksVed*cyPIk19So+A)lN|26;Uq`fk4YTH-1#u-(ZTCEg2z!fMWtgQH^rd zVeT_>Ebq^~I~j{+u0k~+)HSHq2z5PD5B(2yNruJD`00?HddN;aq)-prsfX>6!jRN857#0XUci+v6^-mY@}ku zdn|5;`8JNY&ra57Cwn7@r_#*zV&ZRF8$dG~h|?8d2B+&IwmxFvdsB7XD9T`U7_yFB z+FK|xtr2DP!t~sL@#5q=n6G9w65_KeZ^`CfQd}%K7us_#OD+OiO1Ou^d=&d>spjKw zm^-DO;Jyy?!VXdL1KE`i z*UY%c+6CUc;%gqw7d@?Fd7LiZiWtR~)F?h-7#G@eG}XbD0)DNTIEgKAPhP;dXJQgg z*9m5Kx(+cykuQpe z{vdgq3B3l(SWC!d7Eg(n7b|5A_hmwR1a(P}Tlp|iuM&&VEA_ZojBXr$8M5OPXJKvi zITi=40Mi%DsL_u)lkfU&r0n4Zr#;iO5eLkidV$VJ7EPVSI8{*yj-Vq z_^(lai4WgB(x)47zNG9yOv>58<>gEK3z#nb2h#W-Oyhq<;1xs?R9NW=Ih7{h7pv$$ z`LCZ1%o5&MAv%UFt z1_>#K-B?fraURcep2uyzLh*l>Pld@^1z(B8cPaQ}#2>J5_SBaZ{f&+tO29@8cv``G z5Pwy{w_^iuBhKA;1M-17a;ZQ6*O46@yVSsN*}=C8E<5;5!DRy(Sb%IyHsDim-T>z( zrHbKx)GP2TJCJ`B3B_ODF{>0@Hn2{?WdmC>2+Wx`b@>j(E(`8ba5?ek6rAO;EZo~RaSRM!DSUEAUsbueo(BE>!N~p2`b{^Z%$0)kmWsArr@*jez*d0Im>cwllS1YkH=Xy9D(Zf3x>uy~BP9<{?D}D+3Bf7CyiQ=zF`!hzL+C$8!Cy!J#R^`B{;Lreybzu5F*Yc! z+pwor1%D1F+Ga~Z$SsI>EB+rKF26ryOTS}&{3M!~!QB|}jgn{y4)cscEMGRo_v*xE zlf$3F{}-7^V)<|`vf*Ar_?tVIN?3iBZq%V!F3m$&?^;_JA%Ibv6n~M6kXFTC&Z9%Y zZ@{*n5x9}6R}ShmB|vVv_Y_?AJ*wc#aqW*IE*opbO3&E*SvA{W^MYUe@_FXM{&~Cn zD1ogDb?v+>*|D(7dIf*KF5+&UA(EBD#kyMRf$*Xj``x-I=FaBhXHpICEvnUeXT!Ng zQBNI$e`LXeXv9-pA$$&GLu)jmMe<;8H0o}&KKXcLTd@zaV`bXe2-L))o*pzDazJY= zq6KSVZ!GHGq>Ch-a4}ZvKF8mTnOtrKH^j@d{6hY*08bQWz+>^5v=H{jW9;`_JgUvF mg_=an6%Zi=S`xMH=Ah92wGtdol(}=}3xvHiv3d^IW&Z~<_FUiq diff --git a/voronoi2 b/voronoi2 index 8f53c7b2ddc6240ddac1def550f3ca2df8f4b273..9096ef93b097b522e87ba37a406423ddfcfdce12 100755 GIT binary patch delta 7920 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 OSmUD{yO)L^OZgw<^PABC delta 6866 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 H*L(f}cBG2p