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

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

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 04.05.2014
Размер файла 129,3 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

Размещено на http://www.allbest.ru

Размещено на http://www.allbest.ru

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

Специальность: 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.

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

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

x = 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 использует функции, описанные в теоретической части для поворота координат углов прямоугольника.

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

Функции 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>

using namespace std;

class Shape //общий класс фигур

{

public:

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

int type; //тип фигуры

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

virtual void Move(float X, float Y) =0;

virtual void Resize(float X, float Y) =0;

virtual void Rotate(float Kangle) =0;

virtual void FindSquare() =0;

virtual void FindPerimeter() =0;

};

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

{

public:

float LTX, LTY, LDX, LDY, RDX, RDY, RTX, RTY; //координаты углов

Rectangle(){};

Rectangle(float KLTX, float KLTY, float KRDX, float KRDY) //конструктор

{

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

LTX=KLTX; //копируем координаты

LTY=KLTY;

RDX=KRDX;

RDY=KRDY;

LDX=LTX;

LDY=RDY;

RTX=RDX;

RTY=LTY;

CenterX=(RDX-LDX)/2.0+LDX; //находим координаты центра

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

}

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

{

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

LTX+=X;

LTY+=Y;

LDX+=X;

LDY+=Y;

RDX+=X;

RDY+=Y;

RTX+=X;

RTY+=Y;

CenterX+=X;

CenterY+=Y;

}

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

{

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

float YP=sin(Angle)*Y*1.0;

LTX-=(XP/2.0); //и свдигаем

LDX-=(XP/2.0);

RTX+=(XP/2.0);

RDX+=(XP/2.0);

LTY+=(YP/2.0);

RTY-=(YP/2.0);

LDY+=(YP/2.0);

RDY-=(YP/2.0);

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

float YQ=cos(Angle)*X*1.0;

LTX+=(XQ/2.0); //и свдигаем

LDX-=(XQ/2.0);

RTX+=(XQ/2.0);

RDX-=(XQ/2.0);

LTY+=(YQ/2.0);

RTY+=(YQ/2.0);

LDY-=(YQ/2.0);

RDY-=(YQ/2.0);

}

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

{

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

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

float KLTX=LTX;

float KLTY=LTY;

float KLDX=LDX;

float KLDY=LDY;

float KRTX=RTX;

float KRTY=RTY;

float KRDX=RDX;

float KRDY=RDY;

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

LTY = CenterY+ (KLTX-CenterX) * sin(angle) + (KLTY-CenterY) * cos(angle);

RTX = CenterX+ (KRTX-CenterX) * cos(angle) - (KRTY-CenterY) * sin(angle);

RTY = CenterY+ (KRTX-CenterX) * sin(angle) + (KRTY-CenterY) * cos(angle);

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

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

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

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

Angle-=angle;

}

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

{

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

}

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

{

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

}

};

class Quadrate: public Rectangle //квадрат

{

public:

float side; //сторона

Quadrate(float KLTX, float KLTY, float Side) //конструктор

{

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

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

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

LTX=KLTX;

LTY=KLTY;

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

RDY=KLTY-Side;

LDX=LTX;

LDY=RDY;

RTX=RDX;

RTY=LTY;

CenterX=(RDX-LDX)/2.0+LDX; //вычисляем центр

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

}

void Resize(float X)

{

float XP=cos(Angle)*X*1.0;

float YP=sin(Angle)*X*1.0;

LTX-=(XP/2.0);

LDX-=(XP/2.0);

RTX+=(XP/2.0);

RDX+=(XP/2.0);

LTY+=(YP/2.0);

RTY-=(YP/2.0);

LDY+=(YP/2.0);

RDY-=(YP/2.0);

float XQ=sin(Angle)*X*1.0;

float YQ=cos(Angle)*X*1.0;

LTX+=(XQ/2.0);

LDX-=(XQ/2.0);

RTX+=(XQ/2.0);

RDX-=(XQ/2.0);

LTY+=(YQ/2.0);

RTY+=(YQ/2.0);

LDY-=(YQ/2.0);

RDY-=(YQ/2.0);

side+=X;

}

void Rotate(float Kangle)

{

float angle=-Kangle*3.14/180;

float KLTX=LTX;

float KLTY=LTY;

float KLDX=LDX;

float KLDY=LDY;

float KRTX=RTX;

float KRTY=RTY;

float KRDX=RDX;

float KRDY=RDY;

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

LTY = CenterY+ (KLTX-CenterX) * sin(angle) + (KLTY-CenterY) * cos(angle);

RTX = CenterX+ (KRTX-CenterX) * cos(angle) - (KRTY-CenterY) * sin(angle);

RTY = CenterY+ (KRTX-CenterX) * sin(angle) + (KRTY-CenterY) * cos(angle);

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

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

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

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

Angle-=angle;

}

void FindSquare()

{

Square=side*side;

}

void FindPerimeter()

{

Perimeter=side*4;

}

};

class Circle: public Shape //круг

{

public:

float Radius; //радиус

Circle(float KRadius, float KCenterX, float KCenterY) //конструктор

{

type=1; //задаём тип

Radius=KRadius; //копируем параметры

CenterX=KCenterX;

CenterY=KCenterY;

}

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

{

CenterX+=X;

CenterY+=Y;

}

void Rotate(float Kangle) {}; //вращение круга не влияет на параметры

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

{

Radius+=X;

}

void FindSquare()

{

Square=M_PI*Radius*Radius;

}

void FindPerimeter()

{

Perimeter=M_PI*Radius*2;

}

};

int main()

{

system("chcp 1251");

vector < Shape* > Shapes; //массив фигур

while(1) //выполнять меню до выхода из программы

{

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

int task;

cin>>task;

if (task==4)

{

break;

}

else if (task==1)

{

if (Shapes.size()>0)

{

while (1)

{

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

{

cout<<(i+1)<<". ";

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

{

Circle *Temp=dynamic_cast<Circle*>(Shapes[i]); //приведение к типу круга

cout<<"Круг - Радиус="<<Temp->Radius<<" Центр "<<Temp->CenterX<<"; "<<Temp->CenterY<<"; "<<endl;

}

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

{

Rectangle *Temp=dynamic_cast<Rectangle*>(Shapes[i]); //приведение к типу прямоугольника

cout<<"Прямоугольник - Левый Верхний Угол "<<Temp->LTX<<"; "<<Temp->LTY<<"; Правый нижний угол "<<Temp->RDX<<"; "<<Temp->RDY<<";"<<endl;

}

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

{

Quadrate *Temp=dynamic_cast<Quadrate*>(Shapes[i]); //приведение к типу квадрата

cout<<"Квадрат - Левый Верхний Угол "<<Temp->LTX<<"; "<<Temp->LTY<<"; Сторона "<<Temp->side<<";"<<endl;

}

}

cout<<(Shapes.size()+1)<<". В главное меню"<<endl;

cout<<"Введите номер фигуры"<<endl;

int fnum;

cin>>fnum; fnum--;

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

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

{

Circle *Temp=dynamic_cast<Circle*>(Shapes[fnum]);

Temp->FindSquare();

Temp->FindPerimeter();

cout<<"Круг:Информация"<<endl<<"Радиус="<<Temp->Radius<<";"<<endl<<"Центр: "<<Temp->CenterX<<"; "<<Temp->CenterY<<"; "<<endl<<"Площадь="<<Temp->Square<<";"<<endl<<"Периметр="<<Temp->Perimeter<<";"<<endl;

}

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

{

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

Temp->FindSquare();

Temp->FindPerimeter();

cout<<"Прямоугольник:Информация"<<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;

}

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

{

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

Temp->FindSquare();

Temp->FindPerimeter();

//float sd=sqrt(pow(Temp->LTX-Temp->RTX,2)+pow(Temp->LTY-Temp->RTY,2));

cout<<"Квадрат:Информация"<<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;

cin>>item2;

if (item2==1)

{

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

{

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

float r;

cin>>r;

Circle *Temp=dynamic_cast<Circle*>(Shapes[fnum]);

Temp->Resize(r,0);

}

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

{

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

float x,y;

cin>>x>>y;

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

Temp->Resize(x,y);

}

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

{

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

float x;

cin>>x;

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

Temp->Resize(x);

}

}

else if (item2==2)

{

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

float x,y;

cin>>x>>y;

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

{

Circle *Temp=dynamic_cast<Circle*>(Shapes[fnum]);

Temp->Move(x,y);

}

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

{

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

Temp->Move(x,y);

}

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

{

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

Temp->Move(x,y);

}

}

else if (item2==3)

{

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

{

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

}

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

{

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

float ang;

cin>>ang;

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

Temp->Rotate(ang);

}

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

{

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

float ang;

cin>>ang;

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

Temp->Rotate(ang);

}

}

else {break;}

}

}

else

{

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

}

}

else if (task==2)

{

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

int item1;

cin>>item1;

if (item1==1)

{

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

float r,cx,cy;

cin>>r>>cx>>cy;

Shapes.push_back(new Circle(r,cx,cy));

}

if (item1==2)

{

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

float lx,ly,rx,ry;

cin>>lx>>ly>>rx>>ry;

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

}

if (item1==3)

{

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

float lx,ly,sd;

cin>>lx>>ly>>sd;

Shapes.push_back(new Quadrate(lx,ly,sd));

Shapes[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) //для прямоугольника и квадрата

{

Rectangle *Main=dynamic_cast<Rectangle*>(Shapes[i]);

for (int j=0; j<Shapes.size(); j++) //сравним со всеми фигурами

{

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

{

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

float dist=sqrt(pow(Main->LTX-Temp->CenterX,2)+pow(Main->LTY-Temp->CenterY,2))+Temp->Radius; //поиск расстояния

if (dist>r) //если больше текущего радиуса, то берём его

{

//вычисляем центр

r=dist;

float vectx=((Main->LTX-Temp->CenterX));

float vecty=((Main->LTY-Temp->CenterY));

float vecl=sqrt(vectx*vectx+vecty*vecty);

float prx=vectx*Temp->Radius/vecl;

float pry=vecty*Temp->Radius/vecl;

cx=Temp->CenterX-prx+((vectx+prx)/2.0);

cy=Temp->CenterY-pry+((vecty+pry)/2.0);

}

//аналогично для остальных углов прямоугольника

dist=sqrt(pow(Main->LDX-Temp->CenterX,2)+pow(Main->LDY-Temp->CenterY,2))+Temp->Radius;

if (dist>r)

{

r=dist;

float vectx=((Main->LDX-Temp->CenterX));

float vecty=((Main->LDY-Temp->CenterY));

float vecl=sqrt(vectx*vectx+vecty*vecty);

float prx=vectx*Temp->Radius/vecl;

float pry=vecty*Temp->Radius/vecl;

cx=Temp->CenterX-prx+((vectx+prx)/2.0);

cy=Temp->CenterY-pry+((vecty+pry)/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->RDX-Temp->CenterX));

float vecty=((Main->RDY-Temp->CenterY));

float vecl=sqrt(vectx*vectx+vecty*vecty);

float prx=vectx*Temp->Radius/vecl;

float pry=vecty*Temp->Radius/vecl;

cx=Temp->CenterX-prx+((vectx+prx)/2.0);

cy=Temp->CenterY-pry+((vecty+pry)/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->RTX-Temp->CenterX));

float vecty=((Main->RTY-Temp->CenterY));

float vecl=sqrt(vectx*vectx+vecty*vecty);

float prx=vectx*Temp->Radius/vecl;

float pry=vecty*Temp->Radius/vecl;

cx=Temp->CenterX-prx+((vectx+prx)/2.0);

cy=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));

if (dist>r)

{

r=dist;

float vectx=((Main->LTX-Temp->LTX));

float vecty=((Main->LTY-Temp->LTY));

cx=Temp->LTX+(vectx/2.0);

cy=Temp->LTY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->LTX-Temp->LDX));

float vecty=((Main->LTY-Temp->LDY));

cx=Temp->LDX+(vectx/2.0);

cy=Temp->LDY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->LTX-Temp->RTX));

float vecty=((Main->LTY-Temp->RTY));

cx=Temp->RTX+(vectx/2.0);

cy=Temp->RTY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->LTX-Temp->RDX));

float vecty=((Main->LTY-Temp->RDY));

cx=Temp->RDX+(vectx/2.0);

cy=Temp->RDY+(vecty/2.0);

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

}

//-------

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

if (dist>r)

{

r=dist;

float vectx=((Main->LDX-Temp->LTX));

float vecty=((Main->LDY-Temp->LTY));

cx=Temp->LTX+(vectx/2.0);

cy=Temp->LTY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->LDX-Temp->LDX));

float vecty=((Main->LDY-Temp->LDY));

cx=Temp->LDX+(vectx/2.0);

cy=Temp->LDY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->LDX-Temp->RTX));

float vecty=((Main->LDY-Temp->RTY));

cx=Temp->RTX+(vectx/2.0);

cy=Temp->RTY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->LDX-Temp->RDX));

float vecty=((Main->LDY-Temp->RDY));

cx=Temp->RDX+(vectx/2.0);

cy=Temp->RDY+(vecty/2.0);

}

//-------

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

if (dist>r)

{

r=dist;

float vectx=((Main->RDX-Temp->LTX));

float vecty=((Main->RDY-Temp->LTY));

cx=Temp->LTX+(vectx/2.0);

cy=Temp->LTY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->RDX-Temp->LDX));

float vecty=((Main->RDY-Temp->LDY));

cx=Temp->LDX+(vectx/2.0);

cy=Temp->LDY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->RDX-Temp->RTX));

float vecty=((Main->RDY-Temp->RTY));

cx=Temp->RTX+(vectx/2.0);

cy=Temp->RTY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->RDX-Temp->RDX));

float vecty=((Main->RDY-Temp->RDY));

cx=Temp->RDX+(vectx/2.0);

cy=Temp->RDY+(vecty/2.0);

}

//-------

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

if (dist>r)

{

r=dist;

float vectx=((Main->RTX-Temp->LTX));

float vecty=((Main->RTY-Temp->LTY));

cx=Temp->LTX+(vectx/2.0);

cy=Temp->LTY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->RTX-Temp->LDX));

float vecty=((Main->RTY-Temp->LDY));

cx=Temp->LDX+(vectx/2.0);

cy=Temp->LDY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->RTX-Temp->RTX));

float vecty=((Main->RTY-Temp->RTY));

cx=Temp->RTX+(vectx/2.0);

cy=Temp->RTY+(vecty/2.0);

}

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

if (dist>r)

{

r=dist;

float vectx=((Main->RTX-Temp->RDX));

float vecty=((Main->RTY-Temp->RDY));

cx=Temp->RDX+(vectx/2.0);

cy=Temp->RDY+(vecty/2.0);

}

}

}

}

}

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

{

Circle *Main=dynamic_cast<Circle*>(Shapes[i]);

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

{

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

{

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

{

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

if (dist>r)

{

r=dist;

cx=Main->CenterX; //центр копируем

cy=Main->CenterY; //центр копируем

continue; //на новую итерацию

}

}

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

float dist=(sqrt(pow(Main->CenterX-Temp->CenterX,2)+pow(Main->CenterY-Temp->CenterY,2))+Temp->Radius+Main->Radius);

if (dist>r)

{

r=dist;

float vectx=((Main->CenterX-Temp->CenterX));

float vecty=((Main->CenterY-Temp->CenterY));

float vecl=sqrt(vectx*vectx+vecty*vecty);

float prx=vectx*(Main->Radius)/vecl;

float pry=vecty*(Main->Radius)/vecl;

cx=Main->CenterX+((prx));

cy=Main->CenterY+((pry));

cx-=((dist*vectx/vecl)/2.0);

cy-=((dist*vecty/vecl)/2.0);

}

}

}

}

}

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

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

}

}

system("PAUSE");

Shapes.clear();

}

Размещено на Allbest.ru


Подобные документы

  • Изучение базовых понятий объектно-ориентированного программирования. Исследование принципов работы с классами и объектами. Построение системы классов для описания плоских геометрических фигур. Анализ методов создания объектов, перемещения на плоскости.

    лабораторная работа [212,0 K], добавлен 10.03.2013

  • Объектно-ориентированные возможности языка C++. Моделирование системы геометрических фигур, методика проектирования программных комплексов. Анализ предметной области, технология создания объектной модели. Упрощение классов при использовании наследования.

    курсовая работа [668,8 K], добавлен 22.09.2011

  • Математическое описание операций преобразования плоских фигур. Выбор и обоснование языка программирования и среды разработки. Задание базовой фигуры. Разработка алгоритма работы программы. Проверка корректности работы программы в различных режимах.

    курсовая работа [567,6 K], добавлен 13.10.2014

  • Рисование линий. Выбор объектов. Создание фигур. Редактирование фигур. Вращение, искажение и другие преобразования объектов. Копирование и наложение объектов. Установка позиции и размеров объекта. Сохранение проекта.

    реферат [55,3 K], добавлен 21.12.2003

  • Понятие растра и растровой графики. Аффинные преобразования на плоскости и в пространстве. Цветовые модели RGB, MCYK. Алгоритмы вывода линий и фигур, устранения ступенчатости, удаления невидимых линий, закраски фигур. Графические эффекты, анимация.

    лекция [281,0 K], добавлен 26.07.2013

  • Понятия шаблонов функции и класса, правила описания на языке С++. Разработка и отлаживание в среде программирования программ, содержащих шаблоны функций и классов. Шаблон функции square, возвращающей квадрат переменной. Создание шаблона класса массива.

    лабораторная работа [162,6 K], добавлен 25.05.2013

  • Вычисление площади геометрических фигур с помощью интегрального исчисления. Основные свойства площади как функции. Разработка алгоритма работы программы на языке Object-Pascal в среде Delphi. Текст программы, порядок ее запуска и полученный результат.

    курсовая работа [281,0 K], добавлен 06.06.2013

  • Понятие и свойства алгоритма. Основные типы учебных алгоритмических задач. Обучение программированию в среде Лого. Архитектура, режим работы и система команд исполнителя черепашка. Примеры создания геометрических фигур, организации циклов со счетчиком.

    презентация [327,0 K], добавлен 19.10.2014

  • Назначение и цели создания системы. Разработка логической модели данных, выбор хранилища. Диаграмма классов для диспетчера и контент-менеджера, схема взаимодействия объектов системы. Описание программных модулей. Тестирование веб-базированной системы.

    курсовая работа [5,4 M], добавлен 17.09.2013

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

    курсовая работа [588,7 K], добавлен 17.07.2012

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.