Написал 6е задание на вычислительную геометрию, задача наименьшего круга по алгоритму Велзля
This commit is contained in:
parent
6e9934a2d8
commit
b36187b77d
18 changed files with 264 additions and 1 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
*.un~
|
*.un~
|
||||||
*.exe
|
*.exe
|
||||||
*~
|
*~
|
||||||
*.out
|
*.out
|
||||||
|
.*.sw*
|
81
ComputationalGeometry/6Ex/SCP.c
Normal file
81
ComputationalGeometry/6Ex/SCP.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
21
ComputationalGeometry/6Ex/SCP.h
Normal file
21
ComputationalGeometry/6Ex/SCP.h
Normal 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
|
1
ComputationalGeometry/6Ex/input.txt
Normal file
1
ComputationalGeometry/6Ex/input.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
1 0 -1 0
|
23
ComputationalGeometry/6Ex/main.c
Normal file
23
ComputationalGeometry/6Ex/main.c
Normal 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;
|
||||||
|
}
|
42
ComputationalGeometry/6Ex/makefile
Normal file
42
ComputationalGeometry/6Ex/makefile
Normal 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
|
2
ComputationalGeometry/6Ex/t/e
Normal file
2
ComputationalGeometry/6Ex/t/e
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
1 1 1 1 1 1 1 1
|
1
ComputationalGeometry/6Ex/t/foi
Normal file
1
ComputationalGeometry/6Ex/t/foi
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0 0 0 2 2 0 1 1
|
1
ComputationalGeometry/6Ex/t/i
Normal file
1
ComputationalGeometry/6Ex/t/i
Normal file
|
@ -0,0 +1 @@
|
||||||
|
1 0 -1 0
|
1
ComputationalGeometry/6Ex/t/n
Normal file
1
ComputationalGeometry/6Ex/t/n
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0
|
1
ComputationalGeometry/6Ex/t/o
Normal file
1
ComputationalGeometry/6Ex/t/o
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0 0
|
1
ComputationalGeometry/6Ex/t/r
Normal file
1
ComputationalGeometry/6Ex/t/r
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0 0 2 0
|
1
ComputationalGeometry/6Ex/t/t
Normal file
1
ComputationalGeometry/6Ex/t/t
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0 0 0 2 2 0
|
1
ComputationalGeometry/6Ex/t/tr
Normal file
1
ComputationalGeometry/6Ex/t/tr
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0 0 1 0 2 0
|
1
ComputationalGeometry/6Ex/t/v
Normal file
1
ComputationalGeometry/6Ex/t/v
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0 0 0 1 0 2
|
54
ComputationalGeometry/6Ex/tools.c
Normal file
54
ComputationalGeometry/6Ex/tools.c
Normal 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", ¤t) != 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", ¤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){.array=NULL, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
return (points){array, (i + 1) / 2};
|
||||||
|
}
|
||||||
|
|
11
ComputationalGeometry/6Ex/tools.h
Normal file
11
ComputationalGeometry/6Ex/tools.h
Normal 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
|
19
ComputationalGeometry/6Ex/types.h
Normal file
19
ComputationalGeometry/6Ex/types.h
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue