ЭТАП 1 /////////////////////////////////////////////////////////// // Проект Task1_2 /////////////////////////////////////////////////////////// // Point.h #ifndef POINT_H #define POINT_H class Point { public: // Конструктор Point(double _x = 0, double _y = 0) : x(_x), y(_y) {} // Другие методы void Show() const; public: double x, y; }; #endif /* POINT_H */ /////////////////////////////////////////////////////////// // Point.cpp #include #include "Point.h" using namespace std; void Point::Show() const { cout << " (" << x << ", " << y << ")"; } /////////////////////////////////////////////////////////// // Triangle.h #ifndef TRIANGLE_H #define TRIANGLE_H #include "Point.h" class Triangle { public: Triangle(Point, Point, Point, const char*); // конструктор Triangle(const char*); // конструктор пустого (нулевого) треугольника ~Triangle(); // деструктор Point Get_v1() const { return v1; } // Получить значение v1 Point Get_v2() const { return v2; } // Получить значение v2 Point Get_v3() const { return v3; } // Получить значение v3 char* GetName() const { return name; } // Получить имя объекта void Show() const; // Показать объект void ShowSideAndArea() const; // Показать стороны и площадь объекта public: static int count; // количество созданных объектов private: char* objID; // идентификатор объекта char* name; // наименование треугольника Point v1, v2, v3; // вершины double a; // сторона, соединяющая v1 и v2 double b; // сторона, соединяющая v2 и v3 double c; // сторона, соединяющая v1 и v3 }; #endif /* TRIANGLE_H */ /////////////////////////////////////////////////////////// //Triangle.cpp // Реализация класса Triangle #include #include #include #include <сstring> //#include "CyrIOS.h" // for Visual C++ 6.0 #include "Triangle.h" using namespace std; // Конструктор Triangle::Triangle(Point _v1, Point _v2, Point _v3, const char* ident) : v1(_v1), v2(_v2), v3(_v3) { char buf[16]; objID = new char[strlen(ident) + 1]; strcpy(objID, ident); count++; sprintf(buf, "Треугольник %d", count); name = new char[strlen(buf) + 1]; strcpy(name, buf); a = sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y)); b = sqrt((v2.x - v3.x) * (v2.x - v3.x) + (v2.y - v3.y) * (v2.y - v3.y)); c = sqrt((v1.x - v3.x) * (v1.x - v3.x) + (v1.y - v3.y) * (v1.y - v3.y)); cout << "Constructor_1 for: " << objID << " (" << name << ")" << endl; // отладочный вывод } // Конструктор пустого (нулевого) треугольника Triangle::Triangle(const char* ident) { char buf[16]; objID = new char[strlen(ident) + 1]; strcpy(objID, ident); count++; sprintf(buf, "Треугольник %d", count); name = new char[strlen(buf) + 1]; strcpy(name, buf); a = b = c = 0; cout << "Constructor_2 for: " << objID << " (" << name << ")" << endl; // отладочный вывод } // Деструктор Triangle::~Triangle() { cout << "Destructor for: " << objID << endl; delete [] objID; delete [] name; } // Показать объект void Triangle::Show() const { cout << name << ":"; v1.Show(); v2.Show(); v3.Show(); cout << endl; } // Показать стороны и площадь объекта void Triangle::ShowSideAndArea() const { double p = (a + b + c) / 2; double s = sqrt(p * (p - a) * (p - b) * (p - c)); cout << "---------------------------------------------" << endl; cout << name << ":"; cout.precision(4); cout << " a= " << setw(5) << a; cout << ", b= " << setw(5) << b; cout << ", c= " << setw(5) << c; cout << ";\ts= " << s << endl; } /////////////////////////////////////////////////////////// // Main.cpp #include #include "Triangle.h" //#include "CyrIOS.h" // for Visual C++ 6.0 using namespace std; int Menu(); int GetNumber(int, int); void ExitBack(); void Show(Triangle* [], int); void Move(Triangle* [], int); void FindMax(Triangle* [], int); void IsIncluded(Triangle* [], int); // Инициализация глобальных переменных int Triangle::count = 0; // -------------------------------------- главная функция int main() { // Определения точек Point p1(0, 0); Point p2(0.5, 1); Point p3(1, 0); Point p4(0, 4.5); Point p5(2, 1); Point p6(2, 0); Point p7(2, 2); Point p8(3, 0); // Определения треугольников Triangle triaA(p1, p2, p3, "triaA"); Triangle triaB(p1, p4, p8, "triaB"); Triangle triaC(p1, p5, p6, "triaC"); Triangle triaD(p1, p7, p8, "triaD"); // Определение массива указателей на треугольники Triangle* pTria[] = { &triaA, &triaB, &triaC, &triaD }; int n = sizeof (pTria) / sizeof (pTria[0]); // Главный цикл bool done = false; while (!done) { switch (Menu()) { case 1: Show(pTria, n); break; case 2: Move(pTria, n); break; case 3: FindMax(pTria, n); break; case 4: IsIncluded(pTria, n); break; case 5: cout << "Конец работы." << endl; done = true; break; } } return 0; } // ------------------------------------------ вывод меню int Menu() { cout << "\n=============== Г л а в н о е м е н ю ===================" << endl; cout << "1 - вывести все объекты\t 3 - найти максимальный" << endl; cout << "2 - переместить\t\t 4 - определить отношение включения" << endl; cout << "\t\t 5 - выход" << endl; return GetNumber(1, 5); } // -------------- ввод целого числа в заданном диапазоне int GetNumber(int min, int max) { int number = min - 1; bool success = false; while (!success) { cin >> number; if ((number >= min) && (number <= max) && (cin.peek() == '\n')) break; else { cout << "Повторите ввод (ожидается число от " << min << " до " << max << "):" << endl; cin.clear(); while (cin.get() != '\n') {}; } } return number; } // ------------------- возврат в функцию с основным меню void ExitBack() { cout << "Нажмите Enter." << endl; cin.get(); cin.get(); } // ---------------------------- вывод всех треугольников void Show(Triangle* p_tria[], int k) { cout << "======= Перечень треугольников ========" << endl; for (int i = 0; i < k; ++i) p_tria[i]->Show(); for (i = 0; i < k; ++i) p_tria[i]->ShowSideAndArea(); ExitBack(); } // ----------------------------------------- перемещение void Move(Triangle* p_tria[], int k) { cout << "============= Перемещение =============" << endl; // здесь будет код функции... ExitBack(); } // -------------------- поиск максимального треугольника void FindMax(Triangle* p_tria[], int k) { cout << "=== Поиск максимального треугольника ==" << endl; // здесь будет код функции... ExitBack(); } // --------------------- определение отношения включения void IsIncluded(Triangle* p_tria[], int k) { cout << "======== Отношение включения ==========" << endl; // здесь будет код функции... ExitBack(); } //-------------- конец проекта Task1_2 ---------------- ////////////////////////////////////////////////////////// ЭТАП 2 1. Модуль Point.h: добавьте сразу после объявления метода Show() объявление операции-функции «+=»: void operator +=(Point&); 2. Модуль Point.cpp. Добавьте код реализации данной функции: void Point::operator +=(Point& p) { x += p.x; y += p.y; } 3. Модуль Triangle.h. - Удалите объявление метода ShowSideAndArea(); - Добавьте объявление метода: void Move(Point); 4. Модуль Triangle.cpp. Удалите метод ShowSideAndArea(); Добавьте код метода Move(): // Переместить объект на величину (dp.x, dp.y) void Triangle::Move(Point dp) { v1 += dp; v2 += dp; v3 += dp; } 5. Модуль Main.cpp. - В список прототипов функций в начале файла добавьте сигнатуру: double GetDouble(); - Добавьте в файл текст новой функции GetDouble()либо сразу после функции Show(), либо в конец файла. Эта функция предназначена для ввода вещественного числа и вызывается из функции Move(). В ней предусмотрена защита от ввода недопустимых (например, буквенных) символов аналогично тому, как это решено в функции GetNumber(): // ---------------------------- ввод вещественного числа double GetDouble() { double value; while (true) { cin >> value; if (cin.peek() == '\n') break; else { cout << "Повторите ввод (ожидается вещественное число):" << endl; cin.clear(); while (cin.get() != '\n') {}; } } return value; } - Замените заглушку функции Move() следующим кодом: // ----------------------------------------- перемещение void Move(Triangle* p_tria[], int k) { cout << "============= Перемещение =============" << endl; cout << "Введите номер треугольника (от 1 до " << k << "): "; int i = GetNumber(1, k) - 1; p_tria[i]->Show(); Point dp; cout << "Введите смещение по x: "; dp.x = GetDouble(); cout << "Введите смещение по y: "; dp.y = GetDouble(); p_tria[i]->Move(dp); cout << "Новое положение треугольника:" << endl; p_tria[i]->Show(); ExitBack(); } ЭТАП 3 6. Модуль Triangle.h: добавьте объявление функции-операции: bool operator >(const Triangle&) const; 7. Модуль Triangle.cpp: добавьте код реализации функции-операции: // Сравнить объект (по площади) с объектом tria bool Triangle::operator >(const Triangle& tria) const { double p = (a + b + c) / 2; double s = sqrt(p * (p - a) * (p - b) * (p - c)); double p1 = (tria.a + tria.b + tria.c) / 2; double s1 = sqrt(p1 * (p1 - tria.a) * (p1 - tria.b) * (p1 - tria.c)); if (s > s1) return true; else return false; } 8. Модуль Main.cpp: замените заглушку функции FindMax() следующим кодом: // -------------------- поиск максимального треугольника void FindMax(Triangle* p_tria[], int k) { cout << "=== Поиск максимального треугольника ==" << endl; // Создаем объект triaMax, который по завершению поиска будет идентичен максимальному объекту. // Инициализируем его значением 1-го объекта из массива объектов. Triangle triaMax("triaMax"); triaMax = *p_tria[0]; // Поиск for (int i = 1; i < 4; ++i) if (*p_tria[i] > triaMax) triaMax = *p_tria[i]; cout << "Максимальный треугольник: " << triaMax.GetName() << endl; ExitBack(); } ЭТАП 4 11. Модуль Point.h. - Добавьте перед объявлением класса Point объявление нового типа ORIENT, а также упреждающее объявление типа Triangle: enum ORIENT { LEFT, RIGHT, AHEAD, BEHIND, BETWEEN }; class Triangle; - Добавьте внутри класса Point объявления функций: Point operator +(Point&); Point operator -(Point&); double Length() const; // определяет длину вектора точки // в полярной системе координат ORIENT Classify(Point&, Point&) const; // определяет // положение точки относительно вектора, заданного двумя точками bool InTriangle(Triangle&) const; // определяет, // находится ли точка внутри треугольника 12. Модуль Point.cpp. - Добавьте после директивы #include директиву #include . - Добавьте после директивы #include «Point.h» директиву #include «Triangle.h». - Добавьте реализацию функций-операций: Point Point::operator +(Point& p) { return Point(x + p.x, y + p.y); } Point Point::operator -(Point& p) { return Point(x - p.x, y - p.y); } - Добавьте реализацию метода Length(): double Point::Length() const { return sqrt(x*x + y*y); } - Добавьте реализацию метода Classify(): ORIENT Point::Classify(Point& beg_p, Point& end_p) const { Point p0 = *this; Point a = end_p - beg_p; Point b = p0 - beg_p; double sa = a.x * b.y - b.x * a.y; if (sa > 0.0) return LEFT; if (sa < 0.0) return RIGHT; if ((a.x * b.x < 0.0) || (a.y * b.y < 0.0)) return BEHIND; if (a.Length() < b.Length()) return AHEAD; return BETWEEN; } - Добавьте реализацию метода InTriangle(): bool Point::InTriangle(Triangle& tria) const { ORIENT or1 = Classify(tria.Get_v1(), tria.Get_v2()); ORIENT or2 = Classify(tria.Get_v2(), tria.Get_v3()); ORIENT or3 = Classify(tria.Get_v3(), tria.Get_v1()); if ((or1 == RIGHT || or1 == BETWEEN) && (or2 == RIGHT || or2 == BETWEEN) && (or3 == RIGHT || or3 == BETWEEN)) return true; else return false; } 13. Модуль Triangle.h: добавьте в классе Triangle объявление дружественной функции: friend bool TriaInTria(Triangle, Triangle); // Определить, // входит ли один треугольник во второй 14. Модуль Triangle.cpp: добавьте в конец файла реализацию внешней дружественной функции: // Определить, входит ли треугольник tria1 в треугольник tria2 bool TriaInTria(Triangle tria1, Triangle tria2) { Point v1 = tria1.Get_v1(); Point v2 = tria1.Get_v2(); Point v3 = tria1.Get_v3(); return (v1.InTriangle(tria2) && v2.InTriangle(tria2) && v3.InTriangle(tria2)); return true; } 15. Модуль Main.cpp: замените заглушку функции IsIncluded() следующим кодом: // --------------------- определение отношения включения void IsIncluded(Triangle* p_tria[], int k) { cout << "======== Отношение включения ==========" << endl; cout << "Введите номер 1-го треугольника (от 1 до " << k << "): "; int i1 = GetNumber(1, k) - 1; cout << "Введите номер 2-го треугольника (от 1 до " << k << "): "; int i2 = GetNumber(1, k) - 1; if (TriaInTria(*p_tria[i1], *p_tria[i2])) cout << p_tria[i1]->GetName() << " - входит в - " << p_tria[i2]->GetName() << endl; else cout << p_tria[i1]->GetName() << " - не входит в - " << p_tria[i2]->GetName() << endl; ExitBack(); }