Система классов для описания плоских геометрических фигур

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    93,4 Кб
  • Опубликовано:
    2015-04-23
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Система классов для описания плоских геометрических фигур

Факультет: Высшего профессионального образования

Специальность: 230100.62 Вычислительные машины, комплексы, системы и сети









КУРСОВАЯ РАБОТА

по дисциплине: «Программирование»













Лысьва, 2013 г.

Содержание

Введение

Основные теоретические сведения        

Постановка задачи

Теоретический материал по задаче

Реализованные алгоритмы

Тестирование

Заключение

Список использованных источников

Приложение А. Полный листинг программы

Введение

класс программа геометрический алгоритм

Разработка алгоритмов с использованием объектно-ориентированного подхода является важнейшей частью обучения программированию, поскольку именно этот подход является наиболее приоритетным при создании приложений любого типа на сегодняшний день. Целью данной курсовой работы является изучение основных принципов объектно-ориентированного программирования и решение поставленной задачи.

Основные теоретические сведения

Объе́ктно-ориенти́рованное, или объектное, программи́рование (в дальнейшем ООП) - парадигма программирования, в которой основными концепциями являются понятия объектов и классов.

ООП возникло в результате развития идеологии процедурного программирования, где данные и подпрограммы (процедуры, функции) их обработки формально не связаны. Для дальнейшего развития объектно-ориентированного программирования часто большое значение имеют понятия события (так называемое событийно-ориентированное программирование) и компонента (компонентное программирование, КОП).

В настоящее время количество прикладных языков программирования (список языков), реализующих объектно-ориентированную парадигму, является наибольшим по отношению к другим парадигмам. В области системного программирования до сих пор применяется парадигма процедурного программирования, и общепринятым языком программирования является язык C. Хотя при взаимодействии системного и прикладного уровней операционных систем заметное влияние стали оказывать языки объектно-ориентированного программирования. Например, одной из наиболее распространенных библиотек мультиплатформенного программирования является объектно-ориентированная библиотека Qt, написанная на языке C++.

В центре ООП находится понятие объекта. Объект - это сущность, которой можно посылать сообщения, и которая может на них реагировать, используя свои данные. Объект - это экземпляр класса. Данные объекта скрыты от остальной программы. Сокрытие данных называется инкапсуляцией.

Наличие инкапсуляции достаточно для объектности языка программирования, но ещё не означает его объектной ориентированности - для этого требуется наличие наследования.

Но даже наличие инкапсуляции и наследования не делает язык программирования в полной мере объектным с точки зрения ООП. Основные преимущества ООП проявляются только в том случае, когда в языке программирования реализован полиморфизм; то есть возможность объектов с одинаковой спецификацией иметь различную реализацию.

Как уже говорилось выше, в современных объектно-ориентированных языках программирования каждый объект является значением, относящимся к определённому классу. Класс представляет собой объявленный программистом составной тип данных, имеющий в составе:

Поля данных

Параметры объекта (конечно, не все, а только необходимые в программе), задающие его состояние (свойства объекта предметной области). Иногда поля данных объекта называют свойствами объекта, из-за чего возможна путаница. Физически поля представляют собой значения (переменные, константы), объявленные как принадлежащие классу.

Методы

Процедуры и функции, связанные с классом. Они определяют действия, которые можно выполнять над объектом такого типа, и которые сам объект может выполнять.

Классы могут наследоваться друг от друга. Класс-потомок получает все поля и методы класса-родителя, но может дополнять их собственными либо переопределять уже имеющиеся. Большинство языков программирования поддерживает только единичное наследование (класс может иметь только один класс-родитель), лишь в некоторых допускается множественное наследование - порождение класса от двух или более классов-родителей.

Взаимодействие объектов в абсолютном большинстве случаев обеспечивается вызовом ими методов друг друга.

Инкапсуляция обеспечивается следующими средствами

Контроль доступа

Поскольку методы класса могут быть как чисто внутренними, обеспечивающими логику функционирования объекта, так и внешними, с помощью которых взаимодействуют объекты, необходимо обеспечить скрытость первых при доступности извне вторых. Для этого в языки вводятся специальные синтаксические конструкции, явно задающие область видимости каждого члена класса. Традиционно это модификаторы public, protected и private, обозначающие, соответственно, открытые члены класса, члены класса, доступные только из классов-потомков и скрытые, доступные только внутри класса. Конкретная номенклатура модификаторов и их точный смысл различаются в разных языках.

Методы доступа

Поля класса, в общем случае, не должны быть доступны извне, поскольку такой доступ позволил бы произвольным образом менять внутреннее состояние объектов. Поэтому поля обычно объявляются скрытыми (либо язык в принципе не позволяет обращаться к полям класса извне), а для доступа к находящимся в полях данным используются специальные методы, называемые методами доступа. Такие методы либо возвращают значение того или иного поля, либо производят запись в это поле нового значения. При записи метод доступа может проконтролировать допустимость записываемого значения и, при необходимости, произвести другие манипуляции с данными объекта, чтобы они остались корректными (внутренне согласованными). Методы доступа называют ещё аксессорами (от англ. access - доступ), а по отдельности - геттерами (англ. get - чтение) и сеттерами (англ. set - запись).

Полиморфизм реализуется путём введения в язык правил, согласно которым переменной типа «класс» может быть присвоен объект любого класса-потомка её класса.

Постановка задачи

Построить систему классов для описания плоских геометрических фигур: круг, квадрат, прямоугольник. Предусмотреть методы для создания объектов, перемещения на плоскости, изменения размеров и вращения на заданный угол; вычисления площади и периметра фигур. Определить метод, который отыскивает круг наименьшего радиуса, содержащий все заданные фигуры.

Теоретический материал по задаче

Система объектов.

Для описания системы объектов нам понадобится понятие абстрактного класса.

Абстрактный класс в объектно-ориентированном программировании - базовый класс, который не предполагает создания экземпляров. Абстрактные классы реализуют на практике один из принципов ООП - полиморфизм. Абстрактный класс может содержать (и не содержать) абстрактные методы и свойства. Абстрактный метод не реализуется для класса, в котором объявлен, однако должен быть реализован для его неабстрактных потомков. Абстрактные классы представляют собой наиболее общие абстракции, то есть имеющие наибольший объём и наименьшее содержание.

На языке программирования C++ абстрактный класс объявляется включением хотя бы одной чистой виртуальной функции, типа virtual _сигнатура_функции_ =0;, которая, как и другие, может быть заменена.

Контейнер vector

Для наиболее удобного и безопасного хранения объектов можно использовать контейнер vector.

Шаблон vector расположен в заголовочном файле <vector>. Как и все стандартные компоненты, он расположен в пространстве имён std. Данный интерфейс эмулирует работу стандартного массива C (например, быстрый произвольный доступ к элементам), а также некоторые дополнительные возможности, вроде автоматического изменения размера вектора при вставке или удалении элементов.

Все элементы вектора должны принадлежать одному типу. Например, нельзя совместно хранить данные типов char и int в одном экземпляре вектора. Класс vector обладает стандартным набором методов для доступа к элементам, добавления и удаления элементов, а также получения количества хранимых элементов.

Инициализация:

vector<int> myVector;

Доступ к элементам осуществляется так же, как и для обычного массива: myVector[i]=4;

Количество элементов возвращает функция size(), а очистка осуществляется функцией clear().

Площади и периметры геометрических фигур.

Площадь квадрата: S=a2. Периметр: P=a*4.

Площадь прямоугольника: S=a*b. Периметр: P=(a+b)*2.

Площадь круга: S=r2. Периметр: P=2r.

Поворот вектора на угол относительно точки.

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

= x0 + (x1-x0)*cos(alpha) - (y1-y0)*sin(alpha)  y = y0 + (x1-x0)*sin(alpha) + (y1-y0)*cos(alpha)

Реализованные алгоритмы

Система классов

Для реализации системы классов создадим абстрактный класс Shape (форма), наполнив его виртуальными функциями Move, Resize, Rotate, FindSquare, FindPerimeter.

Унаследуем от Shape классы Circle и Rectangle - круг и прямоугольник. В этих классах реализуем все виртуальные функции в соответствии с особенностями каждой геометрической фигуры. Затем унаследуем от Rectangle класс Quadrate - квадрат и переопределим в нём все функции в соответствии с его геометрическими особенностями. Удобством данной системы будет являться возможность обращаться к большинству полей классов Quadrate и Rectangle, приводя их к общему типу Rectangle.

Хранение фигур

Для хранение фигур создаётся контейнер vector с типом Shape. При обращении к объекту, анализируется значение его переменной type (тип), и объект приводится к конкретному потомку класса Shape.

Реализация функций классов

Рассмотрим реализацию функций для класса Rectangle.

Функция Move прибавляет переданные ей параметры к координатам углов прямоугольника.

Функция Rotate использует функции, описанные в теоретической части для поворота координат углов прямоугольника.

Функции FindSquare и FindPerimeter находит площадь и периметр соответственно по формулам, представленным в теор. части.

Отличием в реализации функций квадрата является обновление поля side - сторона, а также одинаковым увеличением размеров по обоим направлениям.

Рассмотрим реализацию функций для класса Circle.

Функция Move прибавляет переданные ей параметры к координате центра круга.

Функция Rotate пуста. Вращение круга никак не отразится на наших параметрах.

Функция Resize увеличивает радиус на переданное ей значение.

Функции FindSquare и FindPerimeter находит площадь и периметр соответственно по формулам, представленным в теор. части.

Функция Main

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

Поиск наименьшего круга, описывающего все фигуры

Чтобы описать такой круг, необходимо найти максимальное расстояние между двумя точками фигур на плоскости. Для этого каждую фигуру нужно сравнить с каждой попарно.

Прямоугольник-прямоугольник. В этом случае нужно вычислить расстояние от каждой точки первого прямоугольника до каждой точки второго прямоугольника и выбрать наибольшее из них.

Прямоугольник-круг. В этом случае вычисляется расстояние от каждой точки прямоугольника до наиболее удалённой точки круга (для данной точки прямоугольника). Для этого к расстоянию от точки прямоугольника до центра круга прибавляется радиус круга (очевидно, что наиболее удалённая точка лежит на прямой, проходящей через центр). Из полученных четырёх расстояний выбирается наибольшее.

Круг-круг. Наиболее удалённые точки окружностей лежат по разные стороны прямой, проходящей через центры этих окружностей. Вычисляем расстояние между центрами кругов и прибавляем по одному радиусу каждого круга.

Обратим внимание, что, благодаря наследованию класса Quadrate от класса Rectangle, нет необходимости рассматривать квадрат как отдельную фигуру. Квадрат рассматривается в качестве прямоугольника, так как имеет аналогичную структуру (4 угла).

Каждый раз, получая максимальное расстояние для двух фигур, сравниваем его с сохранённым в переменной и, в случае превосходства первого, записываем его в эту переменную. В итоге получим максимальное расстояние между двумя точками всех фигур на плоскости, что будет являться диаметром искомого круга. Центром его будет являться середина отрезка, соединяющего две эти максимально удалённые точки.

Тестирование

Тест 1.

Создадим два круга: r=30, c=(-25; 30) и r=20, c=(20; 70).

Выполним для них поиск минимального описывающего круга.

Результат:

Рисунок 1. Скриншот первого теста

Тест 2.

Квадрат (-80, -10), сторона=20

Прямоугольник (-35, -10), (0, -25)

Круг r=20, c=(30, 50)

Рисунок 2. Скриншот второго теста

Тест 3.

Квадрат (-15, -40), сторона 10

Квадрат (15, 15), сторона 5

Прямоугольник (-20, -5), (10, -15)

Рисунок 3. Скриншот третьего теста

Тест 4.

Круг r=40, c=(-15, 5).

Результат:

Рисунок 4. Скриншот четвёртого теста

Тест 5.

Круг r=25, c=(15, 20).

Прямоугольник (5,40), (25, 15)

Квадрат (15, 20), сторона 15.

Тест 6.

Создадим прямоугольник (15, 75), (25, 25) и найдём описывающий круг.

Рисунок 6.1. Скриншот шестого теста до поворота

Повернём прямоугольник на угол 30 градусов.

Рисунок 6.2. Прямоугольник повернули на 30 градусов

Снова найдём описывающий круг.

Рисунок 6. Скриншот шестого теста

Заключение

Проделав курсовую работу, я приобрёл навыки объектно-ориентированного программирования, а именно: наследования классов, использования абстрактных классов, виртуальных функций. В ходе работы были решены несколько геометрических задач как с использованием готовых формул, так и с разработкой алгоритма собственными силами. Приобретённые умения безусловно будут полезны мне, как студенту направления информатики.

Список использованных источников

Википедия - http://ru.wikipedia.org/

Форум программистов и сисадминов - http://www.cyberforum.ru/

Приложение А. Полный листинг программы

#include <iostream>

#include <cmath>

#include <vector>namespace std;Shape //общий класс фигур

{

public:Perimeter, Square, CenterX, CenterY, Angle; //общие параметры для всех фигур type; //тип фигуры

//виртуальные функции:

virtual void Move(float X, float Y) =0; void Resize(float X, float Y) =0;void Rotate(float Kangle) =0;void FindSquare() =0;void FindPerimeter() =0;

}; Rectangle: public Shape //прямоугольник

{:LTX, LTY, LDX, LDY, RDX, RDY, RTX, RTY; //координаты углов(){};(float KLTX, float KLTY, float KRDX, float KRDY) //конструктор

{=2; //задаём тип фигуры

CenterY=(LTY-LDY)/2.0+LDY;

} Move(float X, float Y) //переместить на X, Y

{

//просто сдвинем все координаты

LTX+=X;

LTY+=Y;+=X;+=Y;+=X;+=Y;+=X;+=Y;+=X;+=Y;

} Resize(float X, float Y) //изменить размер

{XP=cos(Angle)*Y*1.0; //находим вектор-сдвиг точки для шириныYP=sin(Angle)*Y*1.0;-=(XP/2.0); //и свдигаем

LDX-=(XP/2.0);

RTX+=(XP/2.0);+=(XP/2.0);+=(YP/2.0);=(YP/2.0);+=(YP/2.0);=(YP/2.0); XQ=sin(Angle)*X*1.0; //находим вектор-сдвиг точки для длины

float YQ=cos(Angle)*X*1.0;+=(XQ/2.0); //и свдигаем

LDX-=(XQ/2.0);

RTX+=(XQ/2.0);

RDX-=(XQ/2.0);

LTY+=(YQ/2.0);

RTY+=(YQ/2.0);=(YQ/2.0);=(YQ/2.0);

}Rotate(float Kangle) //поворот

{ angle=-Kangle*3.14/180; //перевод из градусов в радианы

//запоминаем первоначальные значения, т.к. они будут меняться в ходе вычислений, а для каждого следующего вычисления нужны первоначальные данные

float KLTX=LTX;KLTY=LTY;KLDX=LDX;KLDY=LDY;KRTX=RTX;KRTY=RTY;KRDX=RDX;KRDY=RDY;

LTX = CenterX+ (KLTX-CenterX) * cos(angle) - (KLTY-CenterY) * sin(angle);= CenterY+ (KLTX-CenterX) * sin(angle) + (KLTY-CenterY) * cos(angle); = CenterX+ (KRTX-CenterX) * cos(angle) - (KRTY-CenterY) * sin(angle);= CenterY+ (KRTX-CenterX) * sin(angle) + (KRTY-CenterY) * cos(angle); = CenterX+ (KLDX-CenterX) * cos(angle) - (KLDY-CenterY) * sin(angle);= CenterY+ (KLDX-CenterX) * sin(angle) + (KLDY-CenterY) * cos(angle); = CenterX+ (KRDX-CenterX) * cos(angle) - (KRDY-CenterY) * sin(angle);= CenterY+ (KRDX-CenterX) * sin(angle) + (KRDY-CenterY) * cos(angle); =angle;

}FindSquare() //находим площадь

{=sqrt(pow((RTX-LTX),2)+pow((RTY-LTY),2))*sqrt(pow((LDX-LTX),2)+pow((LDY-LTY),2));

} FindPerimeter() //и периметр

{=(sqrt(pow((RTX-LTX),2)+pow((RTY-LTY),2))+sqrt(pow((LDX-LTX),2)+pow((LDY-LTY),2)))*2;

}

}; Quadrate: public Rectangle //квадрат

{:side; //сторона(float KLTX, float KLTY, float Side) //конструктор

{

Rectangle();//вызываем конструктор супер-класса

type=3; //указываем тип

side=Side; //копируем параметры

LTX=KLTX;

LTY=KLTY;

RDX=KLTX+Side; //и вычисляем недостающие

RDY=KLTY-Side;=LTX;=RDY;=RDX;=LTY;=(RDX-LDX)/2.0+LDX; //вычисляем центр=(LTY-LDY)/2.0+LDY;

} Resize(float X)

{XP=cos(Angle)*X*1.0;YP=sin(Angle)*X*1.0;=(XP/2.0);=(XP/2.0);+=(XP/2.0);+=(XP/2.0);+=(YP/2.0);=(YP/2.0);+=(YP/2.0);=(YP/2.0);XQ=sin(Angle)*X*1.0;YQ=cos(Angle)*X*1.0;+=(XQ/2.0);=(XQ/2.0);+=(XQ/2.0);=(XQ/2.0);+=(YQ/2.0);+=(YQ/2.0);=(YQ/2.0);=(YQ/2.0);+=X;

}Rotate(float Kangle)

{angle=-Kangle*3.14/180; KLTX=LTX;KLTY=LTY;KLDX=LDX;KLDY=LDY;KRTX=RTX;KRTY=RTY;KRDX=RDX;KRDY=RDY;

LTX = CenterX+ (KLTX-CenterX) * cos(angle) - (KLTY-CenterY) * sin(angle);= CenterY+ (KLTX-CenterX) * sin(angle) + (KLTY-CenterY) * cos(angle); = CenterX+ (KRTX-CenterX) * cos(angle) - (KRTY-CenterY) * sin(angle);= CenterY+ (KRTX-CenterX) * sin(angle) + (KRTY-CenterY) * cos(angle);

= CenterX+ (KLDX-CenterX) * cos(angle) - (KLDY-CenterY) * sin(angle);= CenterY+ (KLDX-CenterX) * sin(angle) + (KLDY-CenterY) * cos(angle); = CenterX+ (KRDX-CenterX) * cos(angle) - (KRDY-CenterY) * sin(angle);= CenterY+ (KRDX-CenterX) * sin(angle) + (KRDY-CenterY) * cos(angle); =angle;

} FindSquare()

{=side*side;

} FindPerimeter()

{=side*4;

}

};Circle: public Shape //круг

{:Radius; //радиус(float KRadius, float KCenterX, float KCenterY) //конструктор

{=1; //задаём тип=KRadius; //копируем параметры=KCenterX; =KCenterY;

}Move(float X, float Y) //сдвинуть круг = сдвинуть центр

{+=X; +=Y;

} Rotate(float Kangle) {}; //вращение круга не влияет на параметры Resize(float X, float Y) //увеличить радиус; второй параметр записан в виртуальной функции - значит он должен быть и здесь, т.к. это не перегрузка функции

{+=X;

} FindSquare()

{=M_PI*Radius*Radius;

} FindPerimeter()

{=M_PI*Radius*2;

}

}; main()

{("chcp 1251"); < Shape* > Shapes; //массив фигур(1) //выполнять меню до выхода из программы

{

cout<<"Введите номер команды и нажмите Enter." << endl << "1. Выбрать фигуру" << endl << "2. Создать фигуру" << endl << "3. Найти минимальный круг, описывающий все имеющиеся фигуры" << endl << "4. Выход" << endl;

int task;>>task;(task==4)

{;

}if (task==1)

{(Shapes.size()>0)

{(1)

{ (int i=0; i<Shapes.size(); i++)

{<<(i+1)<<". ";(Shapes[i]->type==1)

} if (Shapes[i]->type==2)

{*Temp=dynamic_cast<Rectangle*>(Shapes[i]); //приведение к типу прямоугольника<<"Прямоугольник - Левый Верхний Угол "<<Temp->LTX<<"; "<<Temp->LTY<<"; Правый нижний угол "<<Temp->RDX<<"; "<<Temp->RDY<<";"<<endl;

} if (Shapes[i]->type==3)

{*Temp=dynamic_cast<Quadrate*>(Shapes[i]); //приведение к типу квадрата<<"Квадрат - Левый Верхний Угол "<<Temp->LTX<<"; "<<Temp->LTY<<"; Сторона "<<Temp->side<<";"<<endl;

}

}<<(Shapes.size()+1)<<". В главное меню"<<endl;<<"Введите номер фигуры"<<endl;

int fnum;>>fnum; fnum--;(fnum>Shapes.size()-1) break;

if (Shapes[fnum]->type==1)

{*Temp=dynamic_cast<Circle*>(Shapes[fnum]);>FindSquare();>FindPerimeter();<<"Круг:Информация"<<endl<<"Радиус="<<Temp->Radius<<";"<<endl<<"Центр: "<<Temp->CenterX<<"; "<<Temp->CenterY<<"; "<<endl<<"Площадь="<<Temp->Square<<";"<<endl<<"Периметр="<<Temp->Perimeter<<";"<<endl;

} if (Shapes[fnum]->type==2)

{*Temp=dynamic_cast<Rectangle*>(Shapes[fnum]);>FindSquare();>FindPerimeter();<<"Прямоугольник:Информация"<<endl<<"Левый Верхний Угол:"<<Temp->LTX<<"; "<<Temp->LTY<<";"<<endl<<"Правый верхний угол "<<Temp->RTX<<"; "<<Temp->RTY<<";"<<endl<<"Левый нижний Угол:"<<Temp->LDX<<"; "<<Temp->LDY<<";"<<endl<<"Правый нижний угол "<<Temp->RDX<<"; "<<Temp->RDY<<";"<<endl<<"Площадь="<<Temp->Square<<";"<<endl<<"Периметр="<<Temp->Perimeter<<";"<<endl;

} if (Shapes[fnum]->type==3)

{*Temp=dynamic_cast<Quadrate*>(Shapes[fnum]);>FindSquare();>FindPerimeter();

//float sd=sqrt(pow(Temp->LTX-Temp->RTX,2)+pow(Temp->LTY-Temp->RTY,2));<<"Квадрат:Информация"<<endl<<"Сторона="<<Temp->side<<";"<<endl<<"Левый Верхний Угол:"<<Temp->LTX<<"; "<<Temp->LTY<<";"<<endl<<"Правый верхний угол "<<Temp->RTX<<"; "<<Temp->RTY<<";"<<endl<<"Левый нижний Угол:"<<Temp->LDX<<"; "<<Temp->LDY<<";"<<endl<<"Правый нижний угол "<<Temp->RDX<<"; "<<Temp->RDY<<";"<<endl<<"Площадь="<<Temp->Square<<";"<<endl<<"Периметр="<<Temp->Perimeter<<";"<<endl;

}

cout<<"Введите номер команды и нажмите Enter"<<endl;

cout<<"1. Изменить размер"<<endl<<"2. Сдвинуть"<<endl<<"3. Повернуть на угол"<<endl<<"4. Выйти в меню"<<endl;

int item2;>>item2;(item2==1)

{

if (Shapes[fnum]->type==1)

{

cout<<"Введите число, на которое нужно увеличить радиус"<<endl;

float r;>>r;*Temp=dynamic_cast<Circle*>(Shapes[fnum]);>Resize(r,0);

}(Shapes[fnum]->type==2)

{

cout<<"Введите через пробел увеличение длины и ширины прямоугольника"<<endl;

float x,y;>>x>>y;*Temp=dynamic_cast<Rectangle*>(Shapes[fnum]);>Resize(x,y);

} (Shapes[fnum]->type==3)

{

cout<<"Введите увеличение стороны квадрата"<<endl;

float x;>>x;*Temp=dynamic_cast<Quadrate*>(Shapes[fnum]);>Resize(x);

}

} if (item2==2)

{

cout<<"Введите через пробел сдвиг по оси X, по оси Y"<<endl;

float x,y;>>x>>y; (Shapes[fnum]->type==1)

{*Temp=dynamic_cast<Circle*>(Shapes[fnum]);>Move(x,y);

} if (Shapes[fnum]->type==2)

{*Temp=dynamic_cast<Rectangle*>(Shapes[fnum]);>Move(x,y);

} if (Shapes[fnum]->type==3)

{*Temp=dynamic_cast<Quadrate*>(Shapes[fnum]);>Move(x,y);

}

} if (item2==3)

{(Shapes[fnum]->type==1)

{<<"Круг вращается, вращается..."<<endl;

}if (Shapes[fnum]->type==2)

{

cout<<"Введите угол поворота по часовой стрелке (в градусах)"<<endl;

float ang;>>ang; *Temp=dynamic_cast<Rectangle*>(Shapes[fnum]);>Rotate(ang);

} if (Shapes[fnum]->type==3)

{

cout<<"Введите угол поворота по часовой стрелке (в градусах)"<<endl;

float ang;>>ang; *Temp=dynamic_cast<Quadrate*>(Shapes[fnum]);>Rotate(ang);

}

} {break;}

}

}

else

{

cout<<"На плоскости пока нет ни одной фигуры."<<endl;

}

}

else if (task==2)

{

cout<<"Введите 1, чтобы создать круг; 2, чтобы создать прямоугольник; 3, чтобы создать квадрат"<<endl;

int item1;>>item1;(item1==1)

{

cout<<"Введите через пробел радиус и две координаты центра"<<endl;

float r,cx,cy;>>r>>cx>>cy; .push_back(new Circle(r,cx,cy));

}

{

cout<<"Введите через пробел две координаты левого верхнего угла, затем две координаты правого нижнего угла"<<endl;

float lx,ly,rx,ry;>>lx>>ly>>rx>>ry; .push_back(new Rectangle(lx,ly,rx,ry));

}

if (item1==3)

{

cout<<"Введите через пробел две координаты левого верхнего угла, затем сторону квадрата"<<endl;

float lx,ly,sd;>>lx>>ly>>sd; .push_back(new Quadrate(lx,ly,sd));[Shapes.size()-1]->type=3;

}

}

else if (task==3) //поиск минимального круга, описывающего все фигуры

{

float cx, cy, r=-1; //здесь будем хранить наибольший найденный круг (центр и радиус)

for (int i=0; i<Shapes.size(); i++) //цикл по всем фигурам

{

if (Shapes[i]->type>1) //для прямоугольника и квадрата

{*Main=dynamic_cast<Rectangle*>(Shapes[i]); (int j=0; j<Shapes.size(); j++) //сравним со всеми фигурами

{

if (Shapes[j]->type==1) //сравниваем с кругом

{*Temp=dynamic_cast<Circle*>(Shapes[j]);dist=sqrt(pow(Main->LTX-Temp->CenterX,2)+pow(Main->LTY-Temp->CenterY,2))+Temp->Radius; //поиск расстояния (dist>r) //если больше текущего радиуса, то берём его

{

//вычисляем центр=dist; vectx=((Main->LTX-Temp->CenterX));vecty=((Main->LTY-Temp->CenterY));vecl=sqrt(vectx*vectx+vecty*vecty);prx=vectx*Temp->Radius/vecl;pry=vecty*Temp->Radius/vecl;=Temp->CenterX-prx+((vectx+prx)/2.0); =Temp->CenterY-pry+((vecty+pry)/2.0);

}

//аналогично для остальных углов прямоугольника=sqrt(pow(Main->LDX-Temp->CenterX,2)+pow(Main->LDY-Temp->CenterY,2))+Temp->Radius;(dist>r)

{=dist; vectx=((Main->LDX-Temp->CenterX));vecty=((Main->LDY-Temp->CenterY));vecl=sqrt(vectx*vectx+vecty*vecty);prx=vectx*Temp->Radius/vecl;pry=vecty*Temp->Radius/vecl;=Temp->CenterX-prx+((vectx+prx)/2.0); =Temp->CenterY-pry+((vecty+pry)/2.0);

} =sqrt(pow(Main->RDX-Temp->CenterX,2)+pow(Main->RDY-Temp->CenterY,2))+Temp->Radius;(dist>r)

{=dist; vectx=((Main->RDX-Temp->CenterX));vecty=((Main->RDY-Temp->CenterY));vecl=sqrt(vectx*vectx+vecty*vecty);prx=vectx*Temp->Radius/vecl;pry=vecty*Temp->Radius/vecl;=Temp->CenterX-prx+((vectx+prx)/2.0); =Temp->CenterY-pry+((vecty+pry)/2.0);

} =sqrt(pow(Main->RTX-Temp->CenterX,2)+pow(Main->RTY-Temp->CenterY,2))+Temp->Radius;(dist>r)

{=dist; vectx=((Main->RTX-Temp->CenterX));vecty=((Main->RTY-Temp->CenterY));vecl=sqrt(vectx*vectx+vecty*vecty);prx=vectx*Temp->Radius/vecl;pry=vecty*Temp->Radius/vecl;=Temp->CenterX-prx+((vectx+prx)/2.0); =Temp->CenterY-pry+((vecty+pry)/2.0);

}

}

else //если сравниваем с прямоугольником/квадратом

{

if (i<=j) //избежать повторов

{

Rectangle *Temp=dynamic_cast<Rectangle*>(Shapes[j]);

//ищем расстояния от каждой точки к каждой точке

float dist=sqrt(pow(Main->LTX-Temp->LTX,2)+pow(Main->LTY-Temp->LTY,2));(dist>r)

{=dist; vectx=((Main->LTX-Temp->LTX));vecty=((Main->LTY-Temp->LTY));=Temp->LTX+(vectx/2.0); =Temp->LTY+(vecty/2.0);

} =sqrt(pow(Main->LTX-Temp->LDX,2)+pow(Main->LTY-Temp->LDY,2));(dist>r)

{=dist; vectx=((Main->LTX-Temp->LDX));vecty=((Main->LTY-Temp->LDY));=Temp->LDX+(vectx/2.0); =Temp->LDY+(vecty/2.0);

}=sqrt(pow(Main->LTX-Temp->RTX,2)+pow(Main->LTY-Temp->RTY,2));(dist>r)

{=dist; vectx=((Main->LTX-Temp->RTX));vecty=((Main->LTY-Temp->RTY));=Temp->RTX+(vectx/2.0); =Temp->RTY+(vecty/2.0);

}=sqrt(pow(Main->LTX-Temp->RDX,2)+pow(Main->LTY-Temp->RDY,2));(dist>r)

{=dist; vectx=((Main->LTX-Temp->RDX));vecty=((Main->LTY-Temp->RDY));=Temp->RDX+(vectx/2.0); =Temp->RDY+(vecty/2.0);

//cout<<cx<<" "<<cy<<endl;

}

//-------=sqrt(pow(Main->LDX-Temp->LTX,2)+pow(Main->LDY-Temp->LTY,2));(dist>r)

{=dist; vectx=((Main->LDX-Temp->LTX));vecty=((Main->LDY-Temp->LTY));=Temp->LTX+(vectx/2.0); =Temp->LTY+(vecty/2.0);

} =sqrt(pow(Main->LDX-Temp->LDX,2)+pow(Main->LDY-Temp->LDY,2));(dist>r)

{=dist; vectx=((Main->LDX-Temp->LDX));vecty=((Main->LDY-Temp->LDY));=Temp->LDX+(vectx/2.0); =Temp->LDY+(vecty/2.0);

}=sqrt(pow(Main->LDX-Temp->RTX,2)+pow(Main->LDY-Temp->RTY,2));(dist>r)

{=dist; vectx=((Main->LDX-Temp->RTX));vecty=((Main->LDY-Temp->RTY));=Temp->RTX+(vectx/2.0); =Temp->RTY+(vecty/2.0);

}=sqrt(pow(Main->LDX-Temp->RDX,2)+pow(Main->LDY-Temp->RDY,2));(dist>r)

{=dist; vectx=((Main->LDX-Temp->RDX));vecty=((Main->LDY-Temp->RDY));=Temp->RDX+(vectx/2.0); =Temp->RDY+(vecty/2.0);

}

//-------=sqrt(pow(Main->RDX-Temp->LTX,2)+pow(Main->RDY-Temp->LTY,2));(dist>r)

{=dist; vectx=((Main->RDX-Temp->LTX));vecty=((Main->RDY-Temp->LTY));=Temp->LTX+(vectx/2.0); =Temp->LTY+(vecty/2.0);

} =sqrt(pow(Main->RDX-Temp->LDX,2)+pow(Main->RDY-Temp->LDY,2));(dist>r)

{=dist; vectx=((Main->RDX-Temp->LDX));vecty=((Main->RDY-Temp->LDY));=Temp->LDX+(vectx/2.0); =Temp->LDY+(vecty/2.0);

}=sqrt(pow(Main->RDX-Temp->RTX,2)+pow(Main->RDY-Temp->RTY,2));(dist>r)

{=dist; vectx=((Main->RDX-Temp->RTX));vecty=((Main->RDY-Temp->RTY));=Temp->RTX+(vectx/2.0); =Temp->RTY+(vecty/2.0);

}=sqrt(pow(Main->RDX-Temp->RDX,2)+pow(Main->RDY-Temp->RDY,2));(dist>r)

{=dist; vectx=((Main->RDX-Temp->RDX));vecty=((Main->RDY-Temp->RDY));=Temp->RDX+(vectx/2.0); =Temp->RDY+(vecty/2.0);

}

//-------=sqrt(pow(Main->RTX-Temp->LTX,2)+pow(Main->RTY-Temp->LTY,2));(dist>r)

{=dist; vectx=((Main->RTX-Temp->LTX));vecty=((Main->RTY-Temp->LTY));=Temp->LTX+(vectx/2.0); =Temp->LTY+(vecty/2.0);

} =sqrt(pow(Main->RTX-Temp->LDX,2)+pow(Main->RTY-Temp->LDY,2));(dist>r)

{=dist; vectx=((Main->RTX-Temp->LDX));vecty=((Main->RTY-Temp->LDY));=Temp->LDX+(vectx/2.0); =Temp->LDY+(vecty/2.0);

}=sqrt(pow(Main->RTX-Temp->RTX,2)+pow(Main->RTY-Temp->RTY,2));(dist>r)

}=sqrt(pow(Main->RTX-Temp->RDX,2)+pow(Main->RTY-Temp->RDY,2));(dist>r)

{=dist; vectx=((Main->RTX-Temp->RDX));vecty=((Main->RTY-Temp->RDY));=Temp->RDX+(vectx/2.0); =Temp->RDY+(vecty/2.0);

}

}

}

}

}

else //если работаем с кругом

{

Circle *Main=dynamic_cast<Circle*>(Shapes[i]);(int j=0; j<Shapes.size(); j++) //цикл по всем фигурам

{

if ((Shapes[j]->type==1) && (i<=j)) //избежать повторов; сравнивать только с кругами

{

if (i==j) //отдельно для сравнения с самим собой

{dist=Main->Radius*2; //диаметр круга(dist>r)

{=dist;=Main->CenterX; //центр копируем=Main->CenterY; //центр копируем; //на новую итерацию

}

} *Temp=dynamic_cast<Circle*>(Shapes[j]);dist=(sqrt(pow(Main->CenterX-Temp->CenterX,2)+pow(Main->CenterY-Temp->CenterY,2))+Temp->Radius+Main->Radius);(dist>r)

{=dist; vectx=((Main->CenterX-Temp->CenterX));vecty=((Main->CenterY-Temp->CenterY));vecl=sqrt(vectx*vectx+vecty*vecty);prx=vectx*(Main->Radius)/vecl;pry=vecty*(Main->Radius)/vecl;=Main->CenterX+((prx)); =Main->CenterY+((pry)); =((dist*vectx/vecl)/2.0);=((dist*vecty/vecl)/2.0);

}

}

}

}

}

r/=2.0; //был диаметр, стал радиус.

cout<<"Радиус="<<r<<" Центр: "<<cx<<" ;"<<cy<<" ;"<<endl;

}

}

system("PAUSE");

Shapes.clear();

}

Похожие работы на - Система классов для описания плоских геометрических фигур

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!