#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#include <conio.h>
const int M = 10;
struct ball // тип вводимых данных о шаре: координаты его центра и радиус
{
float x;
float y;
float z;
float rad;
};
// расстояние между двумя центрами
float r0(ball a1, ball a2)
{
float r;
r = sqrt(fabs((a1.x - a2.x)*(a1.x - a2.x) + (a1.y - a2.y)*(a1.y - a2.y) + (a1.z - a2.z)*(a1.z - a2.z)));
return (r);
}
// построение направляющего вектора прямой, содержащей 2 заданные точки
ball vect(ball A1, ball A2)
{
ball v0;
float R;
R = r0(A1, A2); // нормировка вектора
R = r0(A1, A2);
v0.rad = 0;
v0.x = A2.x - A1.x; v0.x = v0.x / R;
v0.y = A2.y - A1.y; v0.y = v0.y / R;
v0.z = A2.z - A1.z; v0.z = v0.z / R;
return v0;
}
//построение шара, охватывающего два данных
ball res_ball(ball a, ball b)
{
ball A1, A2, v0, v1, v2, res;
A1 = a; A2 = b;
v0 = vect(A1, A2);
float R = r0(a, b);
//радиус-вектор первого шара
v1.x = A1.x + v0.x*A1.rad; v1.y = A1.y + v0.y*A1.rad; v1.z = A1.z + v0.z*A1.rad;
if (r0(v1, A2) < R) //поворот вектора в другую сторону, если он направлен к центру
{
v1.x = A1.x - v0.x*A1.rad; v1.y = A1.y - v0.y*A1.rad; v1.z = A1.z - v0.z*A1.rad;
};
//радиус-вектор второго шара
v2.x = A2.x + v0.x*A2.rad; v2.y = A2.y + v0.y*A2.rad; v2.z = A2.z + v0.z*A2.rad;
if (r0(v2, A1) < R) //поворот вектора в другую сторону, если он направлен к центру
{
v2.x = A2.x - v0.x*A2.rad; v2.y = A2.y - v0.y*A2.rad; v2.z = A2.z - v0.z*A2.rad;
};
res.rad = r0(v1, v2) / 2;
res.x = v1.x + (v2.x - v1.x) / 2;
res.y = v1.y + (v2.y - v1.y) / 2;
res.z = v1.z + (v2.z - v1.z) / 2;
return res;
}
// проверка, лежит ли шар 2 внутри шара 1
bool inner(ball R, ball cand)
{
if (r0(R, cand) + cand.rad < R.rad) return true;
else return false;
}
void main()
{
int n, i, j, k, l;
ball BALLS[M], A1, A2, v0, res;
ball v1, v2;
float R, max, max2;
printf("n = ");
scanf("%i", &n);
printf("\n");
max = -1;
for (i = 0; i < n; i++) scanf_s("%f%f%f%f", &BALLS[i].x, &BALLS[i].y, &BALLS[i].z, &BALLS[i].rad);
//если занесен 1 шар
if (n == 1) printf("RESULT: %.3f %.3f %.3f %.3f\n", BALLS[0].x, BALLS[0].y, BALLS[0].z, BALLS[0].rad);
//если занесено 2 шара
if (n == 2)
{
A1 = BALLS[0]; A2 = BALLS[1];
v0 = vect(A1, A2);
//радиус-вектор первого шара
v1.x = A1.x + v0.x*A1.rad; v1.y = A1.y + v0.y*A1.rad; v1.z = A1.z + v0.z*A1.rad;
if (r0(v1, A2) < R) //поворот вектора в другую сторону, если он направлен к центру
{
v1.x = A1.x - v0.x*A1.rad; v1.y = A1.y - v0.y*A1.rad; v1.z = A1.z - v0.z*A1.rad;
};
//радиус-вектор второго шара
v2.x = A2.x + v0.x*A2.rad; v2.y = A2.y + v0.y*A2.rad; v2.z = A2.z + v0.z*A2.rad;
if (r0(v2, A1) < R) //поворот вектора в другую сторону, если он направлен к центру
{
v2.x = A2.x - v0.x*A2.rad; v2.y = A2.y - v0.y*A2.rad; v2.z = A2.z - v0.z*A2.rad;
};
res.rad = r0(v1, v2) / 2;
res.x = v1.x + (v2.x - v1.x) / 2;
res.y = v1.y + (v2.y - v1.y) / 2;
res.z = v1.z + (v2.z - v1.z) / 2;
printf("RESULT: %.3f %.3f %.3f %.3f\n", res.x, res.y, res.z, res.rad);
}
//ищем перебором два самый отдаленных шара и на них строим итоговый
if (n>1)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (r0(BALLS[i], BALLS[j]) + BALLS[i].rad + BALLS[j].rad > max)
{
max = r0(BALLS[i], BALLS[j]) + BALLS[i].rad + BALLS[j].rad;
res = res_ball(BALLS[i], BALLS[j]);
for (k = 0; k < n; k++) //если нашелся шар, который не попадает в уже построенный
if(!inner(res,BALLS[k]))
for (l = 0; l < n; l++)
if (r0(BALLS[k], BALLS[l]) + BALLS[k].rad + BALLS[l].rad > max)
{
max = r0(BALLS[k], BALLS[l]) + BALLS[k].rad + BALLS[l].rad;
res = res_ball(BALLS[k], BALLS[l]);
}
}
printf("RESULT: %.3f %.3f %.3f %.3f\n", res.x, res.y, res.z, res.rad);
getch();
}
Be the first to comment
You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.