Написал 6е задание на вычислительную геометрию, задача наименьшего круга по алгоритму Велзля

This commit is contained in:
AZEN-SGG 2024-12-08 22:18:24 +03:00
parent 6e9934a2d8
commit b36187b77d
18 changed files with 264 additions and 1 deletions

View file

@ -0,0 +1,81 @@
#include "SCP.h"
circle MEC(point * I, int ilen, point * N, int nlen) {
if (ilen != 0 && nlen < 3) {
point rnd = I[ilen - 1];
circle crcl = MEC(I, ilen - 1, N, nlen);
if (belongs(crcl, rnd)) return crcl;
else {
N[nlen++] = rnd;
return MEC(I, ilen - 1, N, nlen);
}
} else return primitive(N, nlen);
}
bool belongs(circle crcl, point p) {
if (powd(p.x - crcl.center.x) + powd(p.y - crcl.center.y) - powd(crcl.radius) <= exp) return true;
return false;
}
double powd(double number) {
return number * number;
}
circle primitive(point * N, int nlen) {
if (nlen == 3) {
point temp;
circle crcl;
for (int i = 0; i < nlen; ++i) {
temp = N[2];
N[2] = N[i];
N[i] = temp;
crcl = centermass(N[0], N[1]);
if (belongs(crcl, N[2])) return crcl;
N[i] = N[2];
N[2] = temp;
}
return byThreePoints(N);
} else if (nlen == 2) {
return centermass(N[0], N[1]);
} else if (nlen == 1) {
return (circle){N[0], 0};
} else {
return (circle){(point){0, 0}, 0};
}
}
circle centermass(point p1, point p2) {
return (circle){(point){(p1.x + p2.x) / 2, (p1.y + p2.y) / 2}, distance(p1, p2) / 2};
}
circle byThreePoints(point * warp) {
point center;
double radius, x, y;
double ang_a = straightAngle(warp[1], warp[0]);
double ang_b = straightAngle(warp[2], warp[1]);
x = (ang_a * ang_b * (warp[0].y - warp[2].y) + ang_b * (warp[0].x + warp[1].x) - ang_a * (warp[1].x + warp[2].x)) / (2 * (ang_b - ang_a));
y = (-(1/ang_b) * (x - (warp[1].x + warp[2].x) / 2) + (warp[1].y + warp[2].y) / 2);
center = (point){x, y};
radius = distance(center, warp[0]);
return (circle){center, radius};
}
double straightAngle(point p1, point p2) {
return (p1.y - p2.y) / (p1.x - p2.x);
}
double distance(point p1, point p2) {
return sqrt(powd(p1.x - p2.x) + powd(p1.y - p2.y));
}
void printCircle(circle crcl) {
printf("Center of circle at point (%.2lf, %.2lf)\nRadius is %.2lf\n", crcl.center.x, crcl.center.y, crcl.radius);
}

View file

@ -0,0 +1,21 @@
#ifndef SCP
#define SCP
#include <stdbool.h>
#include <stdio.h>
#include <math.h>
#include "types.h"
#define exp 1.e-6
circle MEC(point * I, int ilen, point * N, int nlen);
bool belongs(circle crcl, point p);
double powd(double number);
circle primitive(point * N, int nlen);
circle centermass(point p1, point p2);
circle byThreePoints(point * warp);
double straightAngle(point p1, point p2);
double distance(point p1, point p2);
void printCircle(circle crcl);
#endif

View file

@ -0,0 +1 @@
1 0 -1 0

View file

@ -0,0 +1,23 @@
#include "tools.h"
#include "SCP.h"
int main(void) {
points ps;
point N[3];
circle crcl;
FILE * file = getFile();
if (file == NULL) return -1;
ps = getPoints(file);
if (ps.array == NULL) return -2;
for (int i = 0; i < ps.length; ++i) printf("(%.2lf, %.2lf) ", ps.array[i].x, ps.array[i].y);
printf("\n");
crcl = MEC(ps.array, ps.length, N, 0);
printCircle(crcl);
free(ps.array);
return 0;
}

View file

@ -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 SCP.o tools.o
gcc main.o SCP.o tools.o -lssp && del *.o
a.exe
main.o: main.c
gcc $(CFLAGS) main.c
SCP.o: SCP.c
gcc $(CFLAGS) SCP.c
tools.o: tools.c
gcc $(CFLAGS) tools.c

View file

@ -0,0 +1,2 @@
1 1 1 1 1 1 1 1

View file

@ -0,0 +1 @@
0 0 0 2 2 0 1 1

View file

@ -0,0 +1 @@
1 0 -1 0

View file

@ -0,0 +1 @@
0

View file

@ -0,0 +1 @@
0 0

View file

@ -0,0 +1 @@
0 0 2 0

View file

@ -0,0 +1 @@
0 0 0 2 2 0

View file

@ -0,0 +1 @@
0 0 1 0 2 0

View file

@ -0,0 +1 @@
0 0 0 1 0 2

View file

@ -0,0 +1,54 @@
#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", &current) != 1) {
printf("File is empty!\n");
return (points){.array=NULL, 0};
}
array = (point *)malloc(size * sizeof(point));
i = 0, p.x = current;
while (fscanf(file, "%lf", &current) == 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){.array=NULL, 0};
}
return (points){array, (i + 1) / 2};
}

View file

@ -0,0 +1,11 @@
#ifndef TOOLS
#define TOOLS
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
FILE * getFile(void);
points getPoints(FILE * file);
#endif

View file

@ -0,0 +1,19 @@
#ifndef TYPES
#define TYPES
typedef struct {
double x;
double y;
} point;
typedef struct {
point * array;
int length;
} points;
typedef struct {
point center;
double radius;
} circle;
#endif