From 241b43fa1967197e3019650486a21e7ff53fbbc5 Mon Sep 17 00:00:00 2001 From: AZEN-SGG Date: Sun, 15 Dec 2024 13:42:03 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB=2010?= =?UTF-8?q?=D1=8E=20=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D1=83=20=D0=BF=D0=BE=20?= =?UTF-8?q?=D0=93=D0=B5=D0=BE=D0=BC=D0=B5=D1=82=D1=80=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ComputationalGeometry/10Ex/input.txt | 1 + ComputationalGeometry/10Ex/main.c | 40 +++++++ ComputationalGeometry/10Ex/makefile | 42 +++++++ ComputationalGeometry/10Ex/polygon.c | 122 +++++++++++++++++++++ ComputationalGeometry/10Ex/polygon.h | 25 +++++ ComputationalGeometry/10Ex/t/test1.txt | 3 + ComputationalGeometry/10Ex/t/test10.txt | 2 + ComputationalGeometry/10Ex/t/test11.txt | 5 + ComputationalGeometry/10Ex/t/test2.txt | 4 + ComputationalGeometry/10Ex/t/test3.txt | 3 + ComputationalGeometry/10Ex/t/test4.txt | 5 + ComputationalGeometry/10Ex/t/test5.txt | 4 + ComputationalGeometry/10Ex/t/test6.txt | 5 + ComputationalGeometry/10Ex/t/test7.txt | 5 + ComputationalGeometry/10Ex/t/test8.txt | 4 + ComputationalGeometry/10Ex/t/test9.txt | 3 + ComputationalGeometry/10Ex/t/tests_req.txt | 32 ++++++ ComputationalGeometry/10Ex/tools.c | 74 +++++++++++++ ComputationalGeometry/10Ex/tools.h | 13 +++ ComputationalGeometry/10Ex/types.h | 40 +++++++ 20 files changed, 432 insertions(+) create mode 100644 ComputationalGeometry/10Ex/input.txt create mode 100644 ComputationalGeometry/10Ex/main.c create mode 100644 ComputationalGeometry/10Ex/makefile create mode 100644 ComputationalGeometry/10Ex/polygon.c create mode 100644 ComputationalGeometry/10Ex/polygon.h create mode 100644 ComputationalGeometry/10Ex/t/test1.txt create mode 100644 ComputationalGeometry/10Ex/t/test10.txt create mode 100644 ComputationalGeometry/10Ex/t/test11.txt create mode 100644 ComputationalGeometry/10Ex/t/test2.txt create mode 100644 ComputationalGeometry/10Ex/t/test3.txt create mode 100644 ComputationalGeometry/10Ex/t/test4.txt create mode 100644 ComputationalGeometry/10Ex/t/test5.txt create mode 100644 ComputationalGeometry/10Ex/t/test6.txt create mode 100644 ComputationalGeometry/10Ex/t/test7.txt create mode 100644 ComputationalGeometry/10Ex/t/test8.txt create mode 100644 ComputationalGeometry/10Ex/t/test9.txt create mode 100644 ComputationalGeometry/10Ex/t/tests_req.txt create mode 100644 ComputationalGeometry/10Ex/tools.c create mode 100644 ComputationalGeometry/10Ex/tools.h create mode 100644 ComputationalGeometry/10Ex/types.h diff --git a/ComputationalGeometry/10Ex/input.txt b/ComputationalGeometry/10Ex/input.txt new file mode 100644 index 0000000..e29a0cd --- /dev/null +++ b/ComputationalGeometry/10Ex/input.txt @@ -0,0 +1 @@ +-1 1 1 1 1 -1 -1 -1 diff --git a/ComputationalGeometry/10Ex/main.c b/ComputationalGeometry/10Ex/main.c new file mode 100644 index 0000000..1834149 --- /dev/null +++ b/ComputationalGeometry/10Ex/main.c @@ -0,0 +1,40 @@ +#include "tools.h" +#include "polygon.h" + +int main(void) { + points ps; + double shift; + polygon plgn, new_polygon; + FILE * file = getFile(); + if (file == NULL) return -1; + + ps = getPoints(file); + if (ps.arr == NULL) return -2; + if (ps.len < 3) { + printf("Incorrect polygon!\n"); + return -4; + } + + shift = getShift(); + + if (-eps < shift && shift < eps) return -3; + + plgn.pts = ps; + repairPolygon(&plgn); + + if (plgn.pts.len <= 1) { + printf("Incorrect polygon!\n"); + return -4; + } + + printPolygon(plgn, "\nOriginal polygon:\n"); + + new_polygon = getPolygon(&plgn, shift); + + printPolygon(new_polygon, "\n\nNew polygon:\n"); + + free(ps.arr); + free(new_polygon.pts.arr); + + return 0; +} diff --git a/ComputationalGeometry/10Ex/makefile b/ComputationalGeometry/10Ex/makefile new file mode 100644 index 0000000..0837676 --- /dev/null +++ b/ComputationalGeometry/10Ex/makefile @@ -0,0 +1,42 @@ +CFLAGS = -mfpmath=sse \ + -fstack-protector-all \ + -W \ + -Wall \ + -Wextra \ + -Wunused \ + -Wcast-align \ + -Werror \ + -pedantic \ + -pedantic-errors \ + -Wfloat-equal \ + -Wpointer-arith \ + -Wformat-security \ + -Wmissing-format-attribute \ + -Wformat=1 \ + -Wwrite-strings \ + -Wcast-align \ + -Wno-long-long \ + -std=gnu99 \ + -Wstrict-prototypes \ + -Wmissing-prototypes \ + -Wmissing-declarations \ + -Wold-style-definition \ + -Wdeclaration-after-statement \ + -Wbad-function-cast \ + -Wnested-externs \ + -O3 \ + -D_DEBUG -g \ + -c + +all: main.o polygon.o tools.o + gcc main.o polygon.o tools.o -lssp && del *.o + a.exe + +main.o: main.c + gcc $(CFLAGS) main.c + +polygon.o: polygon.c + gcc $(CFLAGS) polygon.c + +tools.o: tools.c + gcc $(CFLAGS) tools.c diff --git a/ComputationalGeometry/10Ex/polygon.c b/ComputationalGeometry/10Ex/polygon.c new file mode 100644 index 0000000..8490e1e --- /dev/null +++ b/ComputationalGeometry/10Ex/polygon.c @@ -0,0 +1,122 @@ +#include "polygon.h" + +line getLine(point pt1, point pt2) { + return (line){.start=pt1, .direction=(point){pt2.x - pt1.x, pt2.y - pt1.y}}; +} + +lines getLines(points pts) { + line * lns = (line *)malloc(pts.len * sizeof(line)); + int len = pts.len; + + for (int i = 0; i < len; ++i) { + lns[i] = getLine(pts.arr[i], pts.arr[(i + 1) % len]); + } + + return (lines){lns, len}; +} + +points getVectors(points pts) { + point * vectors = (point *)malloc(pts.len * sizeof(point)); + int len = pts.len; + point vector; + double vlen; + + for (int i = 0; i < len; ++i) { + vector = normal(getLine(pts.arr[i], pts.arr[(i + 1) % len])); + vlen = vector_len(vector); + + vector.x /= vlen, vector.y /= vlen; + + vectors[i] = vector; + } + + return (points){vectors, len}; +} + +point normal(line ln) { + return (point){ln.direction.y, -ln.direction.x}; +} + +double vector_len(point vector) { + return sqrt(qpow(vector.x) + qpow(vector.y)); +} + +double qpow(double number) { + return number * number; +} + +void repairPolygon(polygon * plgn) { + lines lns = getLines(plgn -> pts); + int len = lns.len; + + for (int i = 0; i < len; ++i) { + point fdirect = lns.arr[i].direction; + point sdirect = lns.arr[(i + 1) % len].direction; + + if (isNull(fdirect)) { + polygonDelPoint(plgn, i), --len; + delLine(&lns, i--); + fdirect = sdirect, sdirect = lns.arr[(i + 1) % len].direction; + } + + if (isCollinear(fdirect, sdirect)) { + polygonDelPoint(plgn, i), --len; + delLine(&lns, i--); + } + } +} + +bool isNull(point vector) { + return (fabs(vector.x) < eps && fabs(vector.y) < eps); +} + +void polygonDelPoint(polygon * plgn, int index) { + delVector(&(plgn -> pts), index); +} + +bool isCollinear(point fvec, point svec) { + return fabs(fabs(fvec.x * svec.x + fvec.y * svec.y) - (vector_len(fvec) * vector_len(svec))) < eps; +} + +DELFUNC(Vector, points) + +DELFUNC(Line, lines) + +//void delVector(points * vectors, int index) { +// DEL(vectors -> arr, index, vectors -> len) +// vectors -> len--; +//} +// +//void delLine(lines * lns, int index) { +// for (int i = index + 1; i < lns -> len; ++i) { +// lns -> arr[i] = lns -> arr[i - 1]; +// } +// +// lns -> len--; +//} + +polygon getPolygon(polygon * plgn, double shift) { + points vectors = getVectors(plgn -> pts); + int secind, len = plgn -> pts.len; + point * pts = (point *)malloc(len * sizeof(point)); + + memcpy(pts, plgn -> pts.arr, len * sizeof(point)); + + for (int i = 0; i < len; ++i) { + vectors.arr[i].x *= shift; + vectors.arr[i].y *= shift; + + secind = ((i + 1) % len); + + pts[i].x += vectors.arr[i].x; + pts[secind].x += vectors.arr[i].x; + + pts[i].y += vectors.arr[i].y; + pts[secind].y += vectors.arr[i].y; + } + + free(vectors.arr); + + return (polygon){(points){pts, len}}; +} + diff --git a/ComputationalGeometry/10Ex/polygon.h b/ComputationalGeometry/10Ex/polygon.h new file mode 100644 index 0000000..0e494cc --- /dev/null +++ b/ComputationalGeometry/10Ex/polygon.h @@ -0,0 +1,25 @@ +#ifndef POLYGON +#define POLYGON + +#include +#include +#include +#include +#include +#include "types.h" + +line getLine(point pt1, point pt2); +lines getLines(points pts); +points getVectors(points pts); +point normal(line ln); +double vector_len(point vector); +double qpow(double number); +void repairPolygon(polygon * plgn); +bool isNull(point vector); +bool isCollinear(point fvec, point svec); +void polygonDelPoint(polygon * plgn, int index); +void delVector(points * vectors, int index); +void delLine(lines * lns, int index); +polygon getPolygon(polygon * plgn, double shift); + +#endif diff --git a/ComputationalGeometry/10Ex/t/test1.txt b/ComputationalGeometry/10Ex/t/test1.txt new file mode 100644 index 0000000..6860614 --- /dev/null +++ b/ComputationalGeometry/10Ex/t/test1.txt @@ -0,0 +1,3 @@ +0 0 +1 0 +0 1 diff --git a/ComputationalGeometry/10Ex/t/test10.txt b/ComputationalGeometry/10Ex/t/test10.txt new file mode 100644 index 0000000..4926dd4 --- /dev/null +++ b/ComputationalGeometry/10Ex/t/test10.txt @@ -0,0 +1,2 @@ +0 0 +0 0 diff --git a/ComputationalGeometry/10Ex/t/test11.txt b/ComputationalGeometry/10Ex/t/test11.txt new file mode 100644 index 0000000..9efa718 --- /dev/null +++ b/ComputationalGeometry/10Ex/t/test11.txt @@ -0,0 +1,5 @@ +0 0 +1 1 +2 2 +3 3 +4 4 diff --git a/ComputationalGeometry/10Ex/t/test2.txt b/ComputationalGeometry/10Ex/t/test2.txt new file mode 100644 index 0000000..64cd1bc --- /dev/null +++ b/ComputationalGeometry/10Ex/t/test2.txt @@ -0,0 +1,4 @@ +0 0 +2 0 +2 1 +0 1 diff --git a/ComputationalGeometry/10Ex/t/test3.txt b/ComputationalGeometry/10Ex/t/test3.txt new file mode 100644 index 0000000..2adab8c --- /dev/null +++ b/ComputationalGeometry/10Ex/t/test3.txt @@ -0,0 +1,3 @@ +0 0 +3 0 +1 2 diff --git a/ComputationalGeometry/10Ex/t/test4.txt b/ComputationalGeometry/10Ex/t/test4.txt new file mode 100644 index 0000000..7cec176 --- /dev/null +++ b/ComputationalGeometry/10Ex/t/test4.txt @@ -0,0 +1,5 @@ +0 0 +2 0 +2 2 +0 2 +0 0 diff --git a/ComputationalGeometry/10Ex/t/test5.txt b/ComputationalGeometry/10Ex/t/test5.txt new file mode 100644 index 0000000..b0ba122 --- /dev/null +++ b/ComputationalGeometry/10Ex/t/test5.txt @@ -0,0 +1,4 @@ +1000000000 1000000000 +2000000000 1000000000 +2000000000 2000000000 +1000000000 2000000000 diff --git a/ComputationalGeometry/10Ex/t/test6.txt b/ComputationalGeometry/10Ex/t/test6.txt new file mode 100644 index 0000000..1e5f9b8 --- /dev/null +++ b/ComputationalGeometry/10Ex/t/test6.txt @@ -0,0 +1,5 @@ +0 0 +1 0 +2 0 +3 0 +4 0 diff --git a/ComputationalGeometry/10Ex/t/test7.txt b/ComputationalGeometry/10Ex/t/test7.txt new file mode 100644 index 0000000..566393d --- /dev/null +++ b/ComputationalGeometry/10Ex/t/test7.txt @@ -0,0 +1,5 @@ +0 0 +4 0 +4 4 +2 2 +0 4 diff --git a/ComputationalGeometry/10Ex/t/test8.txt b/ComputationalGeometry/10Ex/t/test8.txt new file mode 100644 index 0000000..15da4e1 --- /dev/null +++ b/ComputationalGeometry/10Ex/t/test8.txt @@ -0,0 +1,4 @@ +0 0 +4 0 +0 4 +4 4 diff --git a/ComputationalGeometry/10Ex/t/test9.txt b/ComputationalGeometry/10Ex/t/test9.txt new file mode 100644 index 0000000..bacef92 --- /dev/null +++ b/ComputationalGeometry/10Ex/t/test9.txt @@ -0,0 +1,3 @@ +0 0 +1 1 +2 0 diff --git a/ComputationalGeometry/10Ex/t/tests_req.txt b/ComputationalGeometry/10Ex/t/tests_req.txt new file mode 100644 index 0000000..903d848 --- /dev/null +++ b/ComputationalGeometry/10Ex/t/tests_req.txt @@ -0,0 +1,32 @@ +t/test1.txt +1 + +t/test2.txt +2 + +t/test3.txt +0.5 + +t/test4.txt +1 + +t/test5.txt +100000 + +t/test6.txt +0.2 + +t/test7.txt +1.5 + +t/test8.txt +2 + +t/test9.txt +0.8 + +t/test10.txt +2 + +t/test11.txt +0.5 \ No newline at end of file diff --git a/ComputationalGeometry/10Ex/tools.c b/ComputationalGeometry/10Ex/tools.c new file mode 100644 index 0000000..89379e8 --- /dev/null +++ b/ComputationalGeometry/10Ex/tools.c @@ -0,0 +1,74 @@ +#include "tools.h" + +FILE * getFile(void) { + char filename[50]; + + printf("Enter file name: "); + if (scanf("%s", filename) == 1) { + FILE * file = fopen(filename, "r"); + if (file == NULL) { + printf("Error file!\n)"); + return NULL; + } else { + return file; + } + } else { + printf("Empty name!\n"); + return NULL; + } +} + +points getPoints(FILE * file) { + int i, size = 2; + point * array = NULL; + point p; + double current; + + if (fscanf(file, "%lf", ¤t) != 1) { + printf("File is empty!\n"); + return (points){.arr=NULL, 0}; + } + + array = (point *)malloc(size * sizeof(point)); + + i = 0, p.x = current; + while (fscanf(file, "%lf", ¤t) == 1) { + if (++i / 2 >= size) { + size *= 2; + array = (point *)realloc(array, size * sizeof(point)); + } + + if (i % 2 == 1) { + p.y = current; + array[i / 2] = p; + } else p.x = current; + } + + if (i == 0) { + printf("Array is empty!\n"); + return (points){.arr=NULL, 0}; + } + + return (points){array, (i + 1) / 2}; +} + +double getShift(void) { + double shift; + + printf("Enter the Shift: "); + + if (scanf("%lf", &shift) == 1) return shift; + else { + printf("\nThe Shift is zero!\n"); + return 0; + } +} + +void printPolygon(polygon plgn, const char * str) { + printf("%s", str); + + for (int i = 0; i < plgn.pts.len; ++i) { + printf("%c = (%.2lf, %.2lf)\n", i + 65, plgn.pts.arr[i].x, plgn.pts.arr[i].y); + } +} + diff --git a/ComputationalGeometry/10Ex/tools.h b/ComputationalGeometry/10Ex/tools.h new file mode 100644 index 0000000..692c22d --- /dev/null +++ b/ComputationalGeometry/10Ex/tools.h @@ -0,0 +1,13 @@ +#ifndef TOOLS +#define TOOLS + +#include +#include +#include "types.h" + +FILE * getFile(void); +points getPoints(FILE * file); +double getShift(void); +void printPolygon(polygon plgn, const char * str); + +#endif diff --git a/ComputationalGeometry/10Ex/types.h b/ComputationalGeometry/10Ex/types.h new file mode 100644 index 0000000..0a8eb57 --- /dev/null +++ b/ComputationalGeometry/10Ex/types.h @@ -0,0 +1,40 @@ +#ifndef TYPES +#define TYPES + +#define eps 1.e-6 + +#define ARR(TYPE, NAME) \ + typedef struct {\ + TYPE * arr;\ + int len;\ + } NAME + +#define DELFUNC(NAME, TYPE) \ + void del##NAME(TYPE * array, int index) { \ + DEL(array->arr, index, array->len) \ + array -> len--; \ + } + +#define DEL(DATA, INDEX, LEN) \ + for (int i = INDEX; i < (LEN) - 1; ++i) { \ + (DATA)[i] = (DATA)[i + 1]; \ + } + +typedef struct { + double x; + double y; +} point; + +typedef struct { + point start; + point direction; +} line; + +ARR(point, points); +ARR(line, lines); + +typedef struct { + points pts; +} polygon; + +#endif