Перейти к содержанию

Домашнее задание#

  1. Согласно вашему номеру по списку реализуйте графическое приложение со следующими функциями: (см. Методические указания по реализации кода)
  2. Приложение отрисовывает график и выводит его на экран
  3. Пользователь может поставить точку в любом месте окна
  4. В левом верхнем углу пользователь может увидеть координаты точки и номер "Зоны", в которую попала точка
    Полученное приложение скомпелируйте в exe файл.

  5. Отчет оформите в Word файле формата *.doc или *.docx

Стурктура отчета:
- Титульный лист, офрмленный согласно шаблону. Лабораторная работа №2 "Разработка графического приложения с использованием условных операторов"
- Номер задания. Добавляете рисунок по вашему варианту из таблицы ниже.
- Описываете функционал приложения. Даете ссылку на Гитхаб. Прикладываете скрин реализации (работающего интерфейса).
- Описываете логику разбиения на зоны. Добавляете рисунок блок-схема "Опредление зоны".
- Приведите таблицу тестирования (Входные данные Х, Y. Результат: )

Подготовьтесь к защите проекта.

Ход выполнения#

Методические указания по определению положения точки на плоскости, заданной двумя функциями#

  1. Введение

В данной работе рассматриваются две функции, например:
- y_1 = 0.5 \cdot x — прямая линия.
- y_2 = -x^2 + 5 — парабола

https://ratcatcher.ru/media/inf/pr/pr5/Рисунок_Г.png

Эти функции делят плоскость на пять областей. Цель задания — определить, в какую область попала случайно заданная точка, и вывести соответствующий результат.

  1. Определение областей

Области, образованные пересечением двух функций, могут быть охарактеризованы следующим образом:

  1. Область 1: Точки, находящиеся выше обеих функций.
  2. Область 2: Точки, находящиеся между двумя графиками (внутренняя область).
  3. Область 3: Точки, находящиеся ниже прямой y_1 и выше параболы y_2 , при x < 0 .
  4. Область 4: Точки, находящиеся ниже прямой y_1 и выше параболы y_2 , при x > 0 .
  5. Область 5: Точки, находящиеся ниже обеих функций.

Если точка попадает на одну из границ (линий y_1 или y_2 ), выводится сообщение «Граница».

  1. Условия для определения положения точки

3.1. Для функции y_1 = 0.5 \cdot x

  • Находится на прямой:

  • Находится ниже прямой:

  • Находится выше прямой:

3.2. Для функции y_2 = -x^2 + 5

  • Находится на кривой:

  • Находится во внутренней области:

  • Находится во внешней области:

  • Специфика областей 3 и 4

Условия для областей 3 и 4 совпадают по отношению к графикам, однако они различаются по знаку x :

  • Область 3:

  • Область 4:

  • Если условие неочевидно, то необходимо найти точки пересечения графиков

Для нахождения точек пересечения функций необходимо приравнять их:

Решая это уравнение, получаем корни:
- x_1 = -2.5
- x_2 = 1

Соответствующие точки на графиках:
- Точка (-2.5, -1.25)
- Точка (2, 1)

Итоговый алгоритм#

После нахождения точек пересечения выполните следующие шаги:

  1. Определите границы:
  2. Используйте найденные точки пересечения, чтобы обозначить границы областей на графике.

  3. Проверка введенной точки:

  4. После ввода пользователем координат точки (x, y):

    • Проверьте, попадает ли точка на границу:
    • Если y = 0.5 \cdot x или y = -x^2 + 5, выведите «Граница».
    • Если точка не на границе, проверьте её положение относительно функций.
  5. Определите конкретную область:

  6. В зависимости от положения точки:
    • Если точка выше обеих функций, выводите «Область 1».
    • Если между графиками, выводите «Область 2».
    • Если ниже прямой и выше параболы при x < -2.5, выводите «Область 3».
    • Если ниже прямой и выше параболы при x > 1, выводите «Область 4».
    • Если ниже обеих функций, выводите «Область 5».

Методические указания по реализации кода#

Для упрощения создания вашего первого графического приложения воспользуйтесь следюущим кодом для отрисовки графиков:

// Функция для отрисовки графика
void drawGraph(sf::RenderWindow& window, std::function<float(float)> func, float xMin, float xMax, float scaleX, float scaleY, sf::Color color) {
    sf::VertexArray graph(sf::LinesStrip);

    for (float x = xMin; x <= xMax; x += 0.1f) {
        float y = func(x); // Вычисление значения функции

        // Преобразование координат в экранные
        float screenX = 400 + x * scaleX;
        float screenY = 300 - y * scaleY;

        // Добавление точки в массив вершин
        graph.append(sf::Vertex(sf::Vector2f(screenX, screenY), color));
    }

    window.draw(graph);
}

Параметры:

sf::RenderWindow& window: ссылка на окно, в котором будет отрисован график.
std::function<float(float)> func: функция, которую необходимо отобразить на графике.
float xMin: минимальное значение по оси X.
float xMax: максимальное значение по оси X.
float scaleX: масштаб по оси X для преобразования координат.
float scaleY: масштаб по оси Y для преобразования координат.
sf::Color color: цвет графика.

Используйте нижеописанный код для составления программы. Обратите внимание, на комментарии.
Участки с номерами 1-5 требуют модификации программы или простого написания команд.

  1. Загрузка шрифта: Добавьте код для загрузки шрифта, который будет использоваться для отображения текста координат пользовательской точки.
  2. Отображение текста: Создайте текст для отображения координат точки. Установите размер текста равным 20, положение текста - (10,10), цвет - белый. Храните текст в переменной coordinatesText.
  3. Логика проверки точки: Реализуйте логику проверки пользовательской точки по переменным mathX и mathY.
  4. Очистка экрана: Добавьте код для очистки экрана перед отрисовкой новых кадров.
  5. Изменение функции для отрисовки графика
#include <SFML/Graphics.hpp>
#include <functional> 
#include <cmath> 

// Функция для отрисовки графика
void drawGraph(sf::RenderWindow& window, std::function<float(float)> func, float xMin, float xMax, float scaleX, float scaleY, sf::Color color) {
    sf::VertexArray graph(sf::LinesStrip);

    for (float x = xMin; x <= xMax; x += 0.1f) {
        float y = func(x); // Вычисление значения функции

        // Преобразование координат в экранные
        float screenX = 400 + x * scaleX;
        float screenY = 300 - y * scaleY;

        // Добавление точки в массив вершин
        graph.append(sf::Vertex(sf::Vector2f(screenX, screenY), color));
    }

    window.draw(graph);
} 

int main() {
    // Создание окна
    sf::RenderWindow window(sf::VideoMode(800, 600), "Приложение для вывода графиков");

    // Переменная для хранения пользовательской точки
    sf::CircleShape userPoint(5); // Радиус 5 пикселей
    userPoint.setFillColor(sf::Color::Red);
    bool userPointExists = false; // Переменная для проверки существования пользовательской точки

    // 1 _ Загрузка шрифта (допишите код)
    // ...
    // ...
    // 

    // 2 _ Текст для отображения координат точки (допишите код)
    // Размер текста 20, положение текста (10,10), цвет белый. Текст храните в переменной coordinatesText
    // ...
    // ...
    //  

    // Оси X и Y
    sf::VertexArray xAxis(sf::Lines, 2);
    xAxis[0].position = sf::Vector2f(50, 300); // Начало оси X
    xAxis[0].color = sf::Color::White; // Цвет оси
    xAxis[1].position = sf::Vector2f(750, 300); // Конец оси X
    xAxis[1].color = sf::Color::White;

    sf::VertexArray yAxis(sf::Lines, 2);
    yAxis[0].position = sf::Vector2f(400, 50); // Начало оси Y
    yAxis[0].color = sf::Color::White; // Цвет оси
    yAxis[1].position = sf::Vector2f(400, 550); // Конец оси Y
    yAxis[1].color = sf::Color::White;

    while (window.isOpen()) {
    sf::Event event;
    while (window.pollEvent(event)) {
        if (event.type == sf::Event::Closed)
            window.close();

        // Проверка клика мышью
        if (event.type == sf::Event::MouseButtonPressed) {
            if (event.mouseButton.button == sf::Mouse::Left) {
                // Получение позиции клика
                sf::Vector2i mousePos = sf::Mouse::getPosition(window);

                // Преобразование экранных координат в "математические"
                float mathX = (mousePos.x - 400) / 30.0f; // Масштаб 30 по X
                float mathY = -(mousePos.y - 300) / 100.0f; // Масштаб 100 по Y

                // Установка новой пользовательской точки
                userPoint.setPosition(mousePos.x - userPoint.getRadius(), mousePos.y - userPoint.getRadius());
                userPointExists = true; // Помечаем, что точка существует

                // 3 _ Допишите логику проверки точки по переменным mathX и mathY !
                // ...
                // ...
                //  

                // Обновление текста с координатами точки 
                coordinatesText.setString("Coordinates: (" + std::to_string(mathX) + ", " + std::to_string(mathY) + ")");
            }
        }
    }


        // 4 _ Очистка экрана (допишите код)
        // ...
        // 


        // Отрисовка осей
        window.draw(xAxis);
        window.draw(yAxis);



        // 5 _  Отрисовка графика y1 = 0.5*x (Замените на ваш график)
        drawGraph(window, [](float x) { return 0.5*x; }, -10, 10, 30, 100, sf::Color::Blue);

        // 5 _   Отрисовка графика y2 = x * x - 5 (Замените на ваш график)
        drawGraph(window, [](float x) { return - x * x + 5 / 10.0f; }, -10, 10, 30, 10, sf::Color::Red);

        // Отрисовка пользовательской точки, если она существует
        if (userPointExists) {
            window.draw(userPoint);
            window.draw(coordinatesText);
        }

        // Отображение нового кадра
        window.display();
    }

    return 0;
}

Варианты#

Вариант Графики
1 https://ratcatcher.ru/media/inf/pr/pr5/График_1.png
2 https://ratcatcher.ru/media/inf/pr/pr5/График_2.png
3 https://ratcatcher.ru/media/inf/pr/pr5/График_3.png
4 https://ratcatcher.ru/media/inf/pr/pr5/График_4.png
5 https://ratcatcher.ru/media/inf/pr/pr5/График_5.png
6 Гhttps://ratcatcher.ru/media/inf/pr/pr5/рафик_6.png
7 https://ratcatcher.ru/media/inf/pr/pr5/График_7.png
8 https://ratcatcher.ru/media/inf/pr/pr5/График_8.png
9 https://ratcatcher.ru/media/inf/pr/pr5/График_9.png
10 https://ratcatcher.ru/media/inf/pr/pr5/График_10.png
11 https://ratcatcher.ru/media/inf/pr/pr5/График_11.png
12 https://ratcatcher.ru/media/inf/pr/pr5/График_12.png
13 https://ratcatcher.ru/media/inf/pr/pr5/График_13.png
14 https://ratcatcher.ru/media/inf/pr/pr5/График_14.png
15 https://ratcatcher.ru/media/inf/pr/pr5/График_15.png
16 https://ratcatcher.ru/media/inf/pr/pr5/График_16.png
17 https://ratcatcher.ru/media/inf/pr/pr5/График_17.png
18 https://ratcatcher.ru/media/inf/pr/pr5/График_18.png
19 https://ratcatcher.ru/media/inf/pr/pr5/График_19.png
20 https://ratcatcher.ru/media/inf/pr/pr5/График_20.png
21 https://ratcatcher.ru/media/inf/pr/pr5/График_21.png
22 https://ratcatcher.ru/media/inf/pr/pr5/График_22.png
23 https://ratcatcher.ru/media/inf/pr/pr5/График_23.png
24 https://ratcatcher.ru/media/inf/pr/pr5/График_24.png
25 https://ratcatcher.ru/media/inf/pr/pr5/График_25.png
26 https://ratcatcher.ru/media/inf/pr/pr5/График_26.png
27 https://ratcatcher.ru/media/inf/pr/pr5/График_27.png
28 https://ratcatcher.ru/media/inf/pr/pr5/График_28.png
29 https://ratcatcher.ru/media/inf/pr/pr5/График_29.png
30 https://ratcatcher.ru/media/inf/pr/pr5/График_30.png