Загрузка данных
#define NOMINMAX // Обязательно ДО windows.h, чтобы убрать конфликт с max()
#include <iostream>
#include <cmath>
#include <windows.h>
using namespace std;
// Базовый класс
class Figure {
public:
virtual void Show() const = 0; // Вывод в консоль
virtual void Draw(HDC hdc) const = 0; // Отрисовка через GDI
virtual ~Figure() {}
};
// Производный класс: Касающиеся окружности
class TouchingCircles : public Figure {
private:
int x1, y1, r1;
int x2, y2, r2;
// Смещение для рисования в окне (чтобы фигура была по центру)
const int offsetX = 300;
const int offsetY = 300;
public:
TouchingCircles(int x1, int y1, int r1, int x2, int y2, int r2)
: x1(x1), y1(y1), r1(r1), x2(x2), y2(y2), r2(r2) {}
// Реализация вывода в консоль
void Show() const override {
cout << "Окружность 1: центр (" << x1 << ", " << y1 << "), радиус " << r1 << endl;
cout << "Окружность 2: центр (" << x2 << ", " << y2 << "), радиус " << r2 << endl;
double dist = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
if (abs(dist - (r1 + r2)) < 1e-6 || abs(dist - abs(r1 - r2)) < 1e-6) {
cout << "Окружности касаются." << endl;
} else {
cout << "Окружности не касаются." << endl;
}
}
// Реализация отрисовки через GDI
void Draw(HDC hdc) const override {
// Создаем кисти и перья
HPEN hPen1 = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); // Красный для 1-й
HPEN hPen2 = CreatePen(PS_SOLID, 3, RGB(0, 0, 255)); // Синий для 2-й
HBRUSH hBrush = (HBRUSH)GetStockObject(NULL_BRUSH); // Прозрачная заливка
// Сохраняем старые объекты
HGDIOBJ oldPen = SelectObject(hdc, hPen1);
HGDIOBJ oldBrush = SelectObject(hdc, hBrush);
// Рисуем первую окружность
Ellipse(hdc, x1 + offsetX - r1, y1 + offsetY - r1, x1 + offsetX + r1, y1 + offsetY + r1);
// Меняем перо и рисуем вторую
SelectObject(hdc, hPen2);
Ellipse(hdc, x2 + offsetX - r2, y2 + offsetY - r2, x2 + offsetX + r2, y2 + offsetY + r2);
// Восстанавливаем объекты и удаляем созданные
SelectObject(hdc, oldPen);
SelectObject(hdc, oldBrush);
DeleteObject(hPen1);
DeleteObject(hPen2);
}
};
// Оконная процедура для обработки сообщений
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
static Figure* figure = nullptr;
switch (uMsg) {
case WM_CREATE:
// Создаем фигуру при создании окна
figure = new TouchingCircles(0, 0, 100, 200, 0, 100); // Внешнее касание
break;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
if (figure) {
figure->Draw(hdc); // Вызов GDI отрисовки
}
EndPaint(hwnd, &ps);
break;
}
case WM_DESTROY:
delete figure;
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
int main() {
setlocale(LC_ALL, "Russian");
// 1. Вывод в консоль (полиморфный вызов)
Figure* figure = new TouchingCircles(0, 0, 100, 200, 0, 100);
figure->Show();
cout << "\nНажмите Enter, чтобы открыть графическое окно..." << endl;
cin.get();
// 2. Создание окна для GDI
HINSTANCE hInstance = GetModuleHandle(NULL);
const wchar_t CLASS_NAME[] = L"GDI_Figure_Window";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // Белый фон
RegisterClass(&wc);
// Размеры окна (клиентская область 600x600)
RECT rect = { 0, 0, 600, 600 };
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
HWND hwnd = CreateWindowEx(
0, CLASS_NAME, L"GDI: Касающиеся окружности",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
rect.right - rect.left, rect.bottom - rect.top,
NULL, NULL, hInstance, NULL
);
if (hwnd == NULL) {
cout << "Ошибка создания окна!" << endl;
delete figure;
return 1;
}
ShowWindow(hwnd, SW_SHOW);
// 3. Цикл сообщений
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
delete figure;
return 0;
}