Advertisement
Nexeon

Untitled

Mar 22nd, 2018
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.98 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <stdio.h>
  5.  
  6. // Расстояние от точки до окружности
  7. double distance(double r, double center_x, double center_y, double x, double y) {
  8.     return sqrt(pow(x - center_x, 2) + pow(y - center_y, 2)) - r;
  9. }
  10.  
  11. // Сумма квадратов расстояний
  12. double sum(double points[2][36], double r, double center_x, double center_y) {
  13.     double sum = 0;
  14.  
  15.     for (int i = 0; i < 36; i++) {
  16.         sum += pow(distance(r, center_x, center_y, points[0][i], points[1][i]), 2);
  17.     }
  18.  
  19.     return sum;
  20. }
  21.  
  22. int main()
  23. {
  24.     setlocale(LC_ALL, "RUS");
  25.  
  26.     FILE *file = nullptr;
  27.  
  28.     fopen_s(&file, "file.txt", "r"); // <- Считываем файл
  29.  
  30.     if (!file) {
  31.         printf("Не удалось открыть файл\n");
  32.         return -1;
  33.     }
  34.  
  35.     char buff[100]; // <- Буфер
  36.  
  37.     double points[2][36]; // <- Входные данные
  38.  
  39.     double x, y;
  40.  
  41.     int i = 0;
  42.  
  43.     // 1. Считываем входные данные
  44.  
  45.     while (fgets(buff, 100, file)) {
  46.         if (std::string(buff).empty()) break;
  47.  
  48.         sscanf_s(buff, "%lf %lf", &x, &y);
  49.  
  50.         points[0][i] = x;
  51.         points[1][i] = y;
  52.  
  53.         i++;
  54.     }
  55.  
  56.     fclose(file);
  57.  
  58.     // 2. Начальное приближение
  59.  
  60.     double minX = points[0][0]
  61.          , maxX = points[0][0]
  62.          , minY = points[1][0]
  63.          , maxY = points[1][0];
  64.  
  65.     // Поиск минимальной и максимальной координаты по Оси X и Y
  66.  
  67.     for (i = 0; i < 36; i++) {
  68.         minX = std::min(minX, points[0][i]);
  69.         maxX = std::max(maxX, points[0][i]);
  70.         minY = std::min(minY, points[1][i]);
  71.         maxY = std::max(maxY, points[1][i]);
  72.     }
  73.  
  74.     double centerX = (minX + maxX) / 2.0 // <- Центр окружности (x, y)
  75.          , centerY = (minY + maxY) / 2.0;
  76.  
  77.     double radius = ((abs(maxX - minX) / 2.0) + (abs(maxY - minY) / 2.0)) / 2.0; // <- Радиус окружности
  78.  
  79.     // 3. Метод Дихтемии
  80.  
  81.     double eps = 1e-2; // <- Точность
  82.  
  83.     printf("Введите погрешность (eps): \n");
  84.     std::cin >> eps;
  85.  
  86.     double oldCenterX = centerX, newCenterX = oldCenterX
  87.         , oldCenterY = centerY, newCenterY = oldCenterY
  88.         , oldRadius = radius, newRadius = oldRadius;
  89.  
  90.     double a, b, c;
  91.  
  92.     int j = 0; // <- Количество итераций
  93.  
  94.     do {
  95.         // Обновляем данные
  96.  
  97.         oldRadius = newRadius;
  98.         oldCenterX = newCenterX;
  99.         oldCenterY = newCenterY;
  100.  
  101.         // Смещаем окружность по оси X
  102.  
  103.         a = minX;
  104.         b = maxX;
  105.  
  106.         while (abs(b - a) > eps) {
  107.             c = (b + a) / 2.0;
  108.  
  109.             if (sum(points, oldRadius, c - eps, oldCenterY) > sum(points, oldRadius, c + eps, oldCenterY))
  110.                 a = c;
  111.             else
  112.                 b = c;
  113.         }
  114.  
  115.         newCenterX = c;
  116.  
  117.         // Смещаем окружность по оси Y
  118.  
  119.         a = minY;
  120.         b = maxY;
  121.  
  122.         while (abs(b - a) > eps) {
  123.             c = (b + a) / 2.0;
  124.  
  125.             if (sum(points, oldRadius, oldCenterX, c - eps) > sum(points, oldRadius, oldCenterX, c + eps))
  126.                 a = c;
  127.             else
  128.                 b = c;
  129.         }
  130.  
  131.         newCenterY = c;
  132.  
  133.         // Подгоняем радиус окружности
  134.  
  135.         a = std::min(abs(maxX - minX) / 2.0, abs(maxY - minY) / 2.0);
  136.         b = std::max(abs(maxX - minX) / 2.0, abs(maxY - minY) / 2.0);
  137.  
  138.         while (abs(b - a) > eps) {
  139.             c = (b + a) / 2.0;
  140.  
  141.             if (sum(points, c - eps, oldCenterX, oldCenterY) > sum(points, c + eps, oldCenterX, oldCenterY))
  142.                 a = c;
  143.             else
  144.                 b = c;
  145.         }
  146.  
  147.         newRadius = c;
  148.  
  149.         j++;
  150.  
  151.     } while (abs(newCenterX - oldCenterX) > eps && abs(newCenterY - oldCenterY) > eps && abs(newRadius - oldRadius) > eps);
  152.  
  153.     // 4. Выводим результат программы
  154.  
  155.     printf("\nНачальное приближение: Окружность с центром (%lf, %lf) и радиусом %lf", centerX, centerY, radius);
  156.     printf("\nРезультат: Окружность с центром (%lf, %lf) и радиусом %lf", newCenterX, newCenterY, newRadius);
  157.     printf("\nПотребовалось итераций: %i\n\n", j);
  158.  
  159.     system("pause");
  160.  
  161.     return 0;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement