Загрузка данных
#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;
}