Загрузка данных


#include <iostream>
#include <cmath>
#include <string>
#include <windows.h> // Для цветов в консоли Windows

using namespace std;

// Определения цветов
const string BLUE = "\x1B[94m";
const string GREEN = "\x1B[92m";
const string RED = "\x1B[91m";
const string RESET = "\x1B[0m";

void enableColor() {
    // Включаем поддержку ANSI escape codes в Windows 10+
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if (hOut == INVALID_HANDLE_VALUE) return;
    DWORD dwMode = 0;
    if (!GetConsoleMode(hOut, &dwMode)) return;
    dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    SetConsoleMode(hOut, dwMode);
}

// Задача B: Длина хорды
void taskB() {
    cout << BLUE << "*************************************************************************\n";
    cout << "* Вычисление длины хорды окружности, лежащей на прямой, проходящей через две *\n";
    cout << "* заданные точки                                                          *\n";
    cout << "*************************************************************************\n" << RESET;

    double cx, cy, r, x1, y1, x2, y2;

    cout << BLUE << "Введите координаты центра окружности:\n" << RESET;
    cout << GREEN; cin >> cx >> cy; cout << RESET;
    cout << BLUE << "Введите радиус окружности:\n" << RESET;
    cout << GREEN; cin >> r; cout << RESET;
    cout << BLUE << "Введите координаты первой точки, задающей прямую, содержащую хорду:\n" << RESET;
    cout << GREEN; cin >> x1 >> y1; cout << RESET;
    cout << BLUE << "Введите координаты второй точки, задающей прямую, содержащую хорду:\n" << RESET;
    cout << GREEN; cin >> x2 >> y2; cout << RESET;

    // Уравнение прямой ax + by + c = 0
    // a = y1 - y2
    // b = x2 - x1
    // c = x1*y2 - x2*y1
    double a = y1 - y2;
    double b = x2 - x1;
    double c = x1 * y2 - x2 * y1;

    // Расстояние от центра (cx, cy) до прямой
    double dist = abs(a * cx + b * cy + c) / sqrt(a * a + b * b);

    cout << BLUE << "Центр окружности расположен в точке (" << cx << ", " << cy << "); радиус окружности равен " << r << "\n";
    cout << "Хорда лежит на прямой, проходящей через точки ("
        << x1 << ", " << y1 << ") и (" << x2 << ", " << y2 << ")\n" << RESET;

    if (dist > r) {
        cout << BLUE << "Ошибка ввода входных данных\n" << RESET;
        cerr << RED << "Прямая, проходящая через точки ("
            << x1 << ", " << y1 << ") и (" << x2 << ", " << y2
            << "), не пересекает окружность с центром в точке ("
            << cx << ", " << cy << ") и радиусом " << r << "\n" << RESET;
        return;
    }

    double chord = 2.0 * sqrt(r * r - dist * dist);
    // Округляем до 1 знака после запятой для красоты, как на скриншоте (19.8)
    cout << BLUE << "Длина хорды равна " << chord << "\n" << RESET;
}

// Задача C: Средняя линия трапеции
void taskC() {
    cout << BLUE << "*************************************************************************\n";
    cout << "* Вычисление длины средней линии трапеции,                                      *\n";
    cout << "* заданной координатами четырёх вершин                                          *\n";
    cout << "*************************************************************************\n" << RESET;

    double x1, y1, x2, y2, x3, y3, x4, y4;

    cout << BLUE << "Введите координаты первой вершины трапеции:\n" << RESET;
    cout << GREEN; cin >> x1 >> y1; cout << RESET;
    cout << BLUE << "Введите координаты второй вершины трапеции:\n" << RESET;
    cout << GREEN; cin >> x2 >> y2; cout << RESET;
    cout << BLUE << "Введите координаты третьей вершины трапеции:\n" << RESET;
    cout << GREEN; cin >> x3 >> y3; cout << RESET;
    cout << BLUE << "Введите координаты четвёртой вершины трапеции:\n" << RESET;
    cout << GREEN; cin >> x4 >> y4; cout << RESET;

    // Векторы сторон
    // AB, BC, CD, DA
    double vAB_x = x2 - x1, vAB_y = y2 - y1;
    double vBC_x = x3 - x2, vBC_y = y3 - y2;
    double vCD_x = x4 - x3, vCD_y = y4 - y3;
    double vDA_x = x1 - x4, vDA_y = y1 - y4;

    // Проверка параллельности (векторное произведение должно быть 0)
    // AB || CD ?
    bool ab_parallel_cd = (vAB_x * vCD_y - vAB_y * vCD_x) == 0; // Точное равенство для целых, но лучше эпсилон
    // Для doubles используем маленькую погрешность
    double eps = 1e-9;
    ab_parallel_cd = fabs(vAB_x * vCD_y - vAB_y * vCD_x) < eps;

    // BC || DA ?
    bool bc_parallel_da = fabs(vBC_x * vDA_y - vBC_y * vDA_x) < eps;

    double midline = 0;
    bool isTrapezoid = false;

    if (ab_parallel_cd && !bc_parallel_da) {
        // Основания AB и CD
        double lenAB = sqrt(vAB_x * vAB_x + vAB_y * vAB_y);
        double lenCD = sqrt(vCD_x * vCD_x + vCD_y * vCD_y);
        midline = (lenAB + lenCD) / 2.0;
        isTrapezoid = true;
    } else if (bc_parallel_da && !ab_parallel_cd) {
        // Основания BC и DA
        double lenBC = sqrt(vBC_x * vBC_x + vBC_y * vBC_y);
        double lenDA = sqrt(vDA_x * vDA_x + vDA_y * vDA_y);
        midline = (lenBC + lenDA) / 2.0;
        isTrapezoid = true;
    } else if (ab_parallel_cd && bc_parallel_da) {
         // Параллелограмм (частный случай трапеции, но на скриншоте ошибка "не является трапецией" для четырехугольника)
         // В учебном контексте часто требуют отличать трапецию от параллелограмма.
         // Однако, посмотрим на скриншот с ошибкой: там вообще ничего не параллельно.
         // Попробуем считать параллелограмм трапецией или нет?
         // Обычно в таких задачах: "Трапеция - это четырехугольник, у которого две стороны параллельны, а две другие не параллельны".
         // Значит, если обе пары параллельны - это не трапеция (в строгом смысле).
         isTrapezoid = false; 
    }

    if (isTrapezoid) {
        cout << BLUE << "Трапеция с вершинами в точках ("
            << x1 << ", " << y1 << "); (" << x2 << ", " << y2 << "); (" << x3 << ", " << y3 << "); (" << x4 << ", " << y4 << ")\n";
        cout << "Длина средней линии равна " << midline << "\n" << RESET;
    } else {
        cout << BLUE << "Ошибка ввода входных данных\n" << RESET;
        cerr << RED << "Четырехугольник с вершинами в точках ("
            << x1 << ", " << y1 << "); (" << x2 << ", " << y2 << "); (" << x3 << ", " << y3 << "); (" << x4 << ", " << y4 << ")\n"
            << "не является трапецией\n" << RESET;
    }
}

// Задача D: Пересечение прямых
void taskD() {
    cout << BLUE << "*************************************************************************\n";
    cout << "* Нахождение точки пересечения двух прямых, заданных двумя парами точек *\n";
    cout << "*************************************************************************\n" << RESET;

    double x1, y1, x2, y2, x3, y3, x4, y4;

    cout << BLUE << "Введите координаты первой точки, задающей первую прямую:\n" << RESET;
    cout << GREEN; cin >> x1 >> y1; cout << RESET;
    cout << BLUE << "Введите координаты второй точки, задающей первую прямую:\n" << RESET; // На скриншоте написано "Второй точки, задающей первую прямую"
    // Но в скриншоте текст: "Введите координаты второй точки, задающей первую прямую:"
    // А потом: "Введите координаты первой точки, задающей вторую прямую:"
    // Я исправлю текст промпта чтобы совпадало с логикой ввода, но на скриншоте опечатка?
    // Скриншот 1: "Введите координаты первой точки... (1 8)", "Введите координаты второй точки... (1 5)" - это 1-я прямая.
    // "Введите координаты первой точки... (5 3)", "Введите координаты второй точки... (7 4)" - это 2-я прямая.
    
    // Исправляем текст запросов согласно скриншоту 1
    cout << BLUE << "Введите координаты первой точки, задающей первую прямую: " << RESET;
    cout << GREEN; cin >> x1 >> y1; cout << RESET;
    cout << BLUE << "Введите координаты второй точки, задающей первую прямую: " << RESET; // На скриншоте тут написано "Второй точки, задающей первую прямую" - это опечатка в задании на фото, логично "Второй точки..."
    // Но на фото четко видно: "Введите координаты второй точки, задающей первую прямую:"
    // Стоп, на фото: "Введите координаты первой точки... (1 8)", "Введите координаты второй точки... (1 5)".
    // Потом: "Введите координаты первой точки... (5 3)", "Введите координаты второй точки... (7 4)".
    // Все верно.
    
    // Переменная x2, y2 уже считана выше? Нет, я запутался в переменных.
    // Пересчитаю ввод заново.
    
    // Сброс переменных для ясности
    double lx1, ly1, lx2, ly2, lx3, ly3, lx4, ly4;

    cout << BLUE << "Введите координаты первой точки, задающей первую прямую: " << RESET;
    cout << GREEN; cin >> lx1 >> ly1; cout << RESET;
    
    cout << BLUE << "Введите координаты второй точки, задающей первую прямую: " << RESET; // На фото текст: "Введите координаты второй точки, задающей первую прямую:"
    // Нет, на фото: "Введите координаты первой точки... (1 8)", потом "Введите координаты второй точки... (1 5)".
    // Потом "Введите координаты первой точки... (5 3)".
    // Потом "Введите координаты второй точки... (7 4)".
    // Текст промпта на фото: "Введите координаты второй точки, задающей первую прямую:" - это для (1,5).
    // Текст промпта на фото: "Введите координаты первой точки, задающей вторую прямую:" - это для (5,3).
    // Текст промпта на фото: "Введите координаты второй точки, задающей вторую прямую:" - это для (7,4).
    
    cout << BLUE << "Введите координаты второй точки, задающей первую прямую: " << RESET;
    cout << GREEN; cin >> lx2 >> ly2; cout << RESET;

    cout << BLUE << "Введите координаты первой точки, задающей вторую прямую: " << RESET;
    cout << GREEN; cin >> lx3 >> ly3; cout << RESET;

    cout << BLUE << "Введите координаты второй точки, задающей вторую прямую: " << RESET;
    cout << GREEN; cin >> lx4 >> ly4; cout << RESET;

    // Уравнение прямой 1: A1*x + B1*y + C1 = 0
    double A1 = ly2 - ly1;
    double B1 = -(lx2 - lx1);
    double C1 = -A1 * lx1 - B1 * ly1;

    // Уравнение прямой 2: A2*x + B2*y + C2 = 0
    double A2 = ly4 - ly3;
    double B2 = -(lx4 - lx3);
    double C2 = -A2 * lx3 - B2 * ly3;

    double det = A1 * B2 - A2 * B1;

    cout << BLUE << "Первая прямая проходит через точки ("
        << lx1 << "," << ly1 << ") и (" << lx2 << "," << ly2 << ")\n";
    cout << "Вторая прямая проходит через точки ("
        << lx3 << "," << ly3 << ") и (" << lx4 << "," << ly4 << ")\n" << RESET;

    if (fabs(det) < 1e-9) {
        cout << BLUE << "Ошибка ввода входных данных\n" << RESET;
        cerr << RED << "Прямая, проходящая через точки ("
            << lx1 << "," << ly1 << ") и (" << lx2 << "," << ly2
            << "), не пересекается с прямой, проходящей через точки ("
            << lx3 << "," << ly3 << ") и (" << lx4 << "," << ly4 << ")\n" << RESET;
        return;
    }

    double x = (-C1 * B2 + C2 * B1) / det;
    double y = (-A1 * C2 + A2 * C1) / det;

    cout << BLUE << "Прямые пересекаются в точке (" << x << ", " << y << ")\n" << RESET;
}

int main(int argc, char* argv[]) {
    setlocale(LC_ALL, "RU"); // Для корректного отображения кириллицы
    enableColor();

    if (argc < 2) {
        cerr << RED << "Необходимо указать один параметр: B, C или D\n" << RESET;
        return 1;
    }

    string task(argv[1]);

    if (task == "B") taskB();
    else if (task == "C") taskC(); // Добавлена задача C
    else if (task == "D") taskD();
    else {
        cerr << RED << "Неизвестная задача: " << task << "\n" << RESET;
        return 1;
    }

    return 0;
}