#include <iostream>
#include <vector>
#include <stdlib.h>
#include <cmath>
using namespace std;
struct Point{//Точка
double x,y;
};
//Базовый класс
class Shape {
public:
Point *arc;
char ID;
/* Поля и методы */
virtual double GetArea(){return 0;}//Вычисление площади фигуры
virtual void CreateShape(){}
virtual void move(){}
virtual void rotate(){}
virtual Point GetCenter()=0;//Вычисление координат центра фигуры
virtual int GetRadOutcircle()=0;//Вычисление радиуса вписанной окружности
virtual int GetRadIncircle()=0;//Вычисление радиуса вписанной окружности
virtual ~Shape(){}
};
class Rectangle : public Shape {
//Класс прямоугольник
public:
Rectangle ()
{
ID='R';
arc = new Point [4];
}
//Определение координат фигуры
void CreateShape()
{
cout<<"Input 2 Rectangle coordinate points"<<endl;
cin>>arc[0].x; /*вводим все координаты*/
cin>>arc[0].y;
cin>>arc[3].x;
cin>>arc[3].y;
arc[1].x = arc[3].x;
arc[1].y = arc[0].y;
arc[2].x = arc[0].x;
arc[2].y = arc[3].y;
}
//Перемещение фигуры в данную точку
void move(double step, double angle)
{
for(int i=0; i<4; i++)
{
arc[i].x+=step*cos(angle);
arc[i].y+=step*sin(angle);
}
}
//Поворот фигуры на определенный угол
void rotate(Point point, double angle)
{
double *ort = new double[3];
double *fi = new double[3];
for(int i=0; i<4; i++)
{
double newX = arc[i].x-point.x;
double newY = arc[i].y-point.y;
ort[i] = sqrt(newX*newX+newY*newY);
if(newX>0 && newY>=0) fi[i] = atan(newY/newX);
if(newX>0 && newY<0) fi[i] = atan(newY/newX)+2*M_PI;
if(newX<0) fi[i] = atan(newY/newX)+M_PI;
if(newX==0 && newY>0) fi[i] = M_PI/2;
if(newX==0 && newY<0) fi[i] = 3*M_PI/2;
if(newX==0 && newY==0) fi[i] = 0;
fi[i]+=angle;
arc[i].x = point.x+ort[i]*cos(fi[i]);
arc[i].y = point.y+ort[i]*sin(fi[i]);
}
}
Point GetCenter()
{
Point result;
result.x = (arc[0].x + arc[2].x) / 2;
result.y = (arc[0].y + arc[2].y) / 2;
return result;
}
//радиус описанной(это для пересечения, включения)
int GetRadIncircle()
{
int a = arc[2].x - arc[0].x;
int b = arc[2].y - arc[0].y;
if (abs(a) == abs(b))
{
return a / 2;
}
return 0;
}
//радиус описанной окружности
int GetRadOutcircle()
{
Point cog = GetCenter();
return sqrt(pow(cog.x - arc[0].x, 2) + pow(cog.y - arc[0].y, 2));
}
double GetArea()
{
/*вычисление конкретной площади*/return abs((arc[0].x-arc[3].x)*(arc[0].y-arc[3].y));
}
~Rectangle(){}
};
//Класс треугольник
class Triangle : public Shape {
public:
Triangle ()
{
arc = new Point[3];
ID='T';
}
//Определения координат
void CreateShape()
{
cout<<"Input Triangle coordinate points"<<endl;
for(int i=0; i<3; i++)
{
cin>>arc[i].x; /*вводим все координаты*/
cin>>arc[i].y;
}
}
//Поворот
void rotate(Point point, double angle)
{
double *ort = new double[3];
double *fi = new double[3];
for(int i=0; i<3; i++)
{
double newX = arc[i].x-point.x;
double newY = arc[i].y-point.y;
ort[i] = sqrt(newX*newX+newY*newY);
if(newX>0 && newY>=0) fi[i] = atan(newY/newX);
if(newX>0 && newY<0) fi[i] = atan(newY/newX)+2*M_PI;
if(newX<0) fi[i] = atan(newY/newX)+M_PI;
if(newX==0 && newY>0) fi[i] = M_PI/2;
if(newX==0 && newY<0) fi[i] = 3*M_PI/2;
if(newX==0 && newY==0) fi[i] = 0;
fi[i]+=angle;
arc[i].x = point.x+ort[i]*cos(fi[i]);
arc[i].y = point.y+ort[i]*sin(fi[i]);
}
}
//Перемещение
void move(double step, double angle)
{
for(int i=0; i<3; i++)
{
arc[i].x+=step*cos(angle);
arc[i].y+=step*sin(angle);
}
}
//Находим центр треугольника
Point GetCenter()
{
Point result;
result.x = (arc[0].x + arc[1].x + arc[2].x) / 3;
result.y = (arc[0].y + arc[2].y + arc[2].y) / 3;
return result;
}
//радиус вписанной
int GetRadIncircle()
{
double a = sqrt((arc[1].x - arc[0].x) * (arc[1].x - arc[0].x) + (arc[1].y -
arc[0].y) * (arc[1].y - arc[0].y));
double b = sqrt((arc[2].x - arc[0].x) * (arc[2].x - arc[0].x) + (arc[2].y -
arc[0].y) * (arc[2].y - arc[0].y));
double c = sqrt((arc[1].x - arc[2].x) * (arc[1].x - arc[2].x) + (arc[1].y -
arc[2].y) * (arc[1].y - arc[2].y));
double p = (a + b + c) / 2;
return sqrt(((p - a) * (p - b) * (p - c)) / p);
}
//радиус описанной(это для пересечения, включения)
int GetRadOutcircle()
{
double a = sqrt((arc[1].x - arc[0].x) * (arc[1].x - arc[0].x) + (arc[1].y -
arc[0].y) * (arc[1].y - arc[0].y));
double b = sqrt((arc[2].x - arc[0].x) * (arc[2].x - arc[0].x) + (arc[2].y -
arc[0].y) * (arc[2].y - arc[0].y));
double c = sqrt((arc[1].x - arc[2].x) * (arc[1].x - arc[2].x) + (arc[1].y -
arc[2].y) * (arc[1].y - arc[2].y));
double p = (a + b + c) / 2;
return a * b * c / (4 * sqrt(p * ((p - a) * (p - b) * (p - c))));
}
double GetArea()
{
/*вычисление конкретной площади*/
return abs(arc[0].x*(arc[1].y-arc[2].y)+arc[1].x*(arc[2].y-arc[0].y)+arc[2].x*(arc[0].y-arc[1].y))/2;
}
~Triangle(){}
};
//Класс восьмиугольник
class Octagon : public Shape {
public:
Octagon(){arc = new Point[8]; ID='O';}
void CreateShape(){/*...*/}
/* .....*/
double GetArea(){/*вычисление конкретной площади*/return 8;}
void move(){}
void rotate(){}
Point GetCenter()
{
Point result;
result.x = 0;
result.y = 0;
return result;
}
int GetRadOutcircle(){return 0;}
int GetRadIncircle(){return 0;}
~Octagon(){}
};
//Класс квадрат
class Square : public Shape {
public:
Square(){arc = new Point[4]; ID='S';}
void CreateShape(){/*...*/}
/* .....*/
double GetArea(){/*вычисление конкретной площади*/return 8;}
void move(){}
void rotate(){}
Point GetCenter()
{
Point result;
result.x = 0;
result.y = 0;
return result;
}
int GetRadOutcircle(){return 0;}
int GetRadIncircle(){return 0;}
~Square(){}
};
//Класс параллелограмм
class Parallelogram : public Shape {
public:
Parallelogram(){arc = new Point[4]; ID='P';}
void CreateShape(){/*...*/}
/* .....*/
double GetArea(){/*вычисление конкретной площади*/return 8;}
void move(){}
void rotate(){}
Point GetCenter()
{
Point result;
result.x = 0;
result.y = 0;
return result;
}
int GetRadOutcircle(){return 0;}
int GetRadIncircle(){return 0;}
~Parallelogram(){}
};
//Класс трапеция
class trapeze : public Shape {
public:
trapeze(){arc = new Point[4]; ID='t';}
void CreateShape(){/*...*/}
/* .....*/
double GetArea(){/*вычисление конкретной площади*/return 8;}
void move(){}
void rotate(){}
Point GetCenter()
{
Point result;
result.x = 0;
result.y = 0;
return result;
}
int GetRadOutcircle(){return 0;}
int GetRadIncircle(){return 0;}
~trapeze(){}
};
//Класс шестиугольник
class hexagon : public Shape {
public:
hexagon(){arc = new Point[6]; ID='h';}
void CreateShape(){/*...*/}
/* .....*/
double GetArea(){/*вычисление конкретной площади*/return 8;}
void move(){}
void rotate(){}
Point GetCenter()
{
Point result;
result.x = 0;
result.y = 0;
return result;
}
int GetRadOutcircle(){return 0;}
int GetRadIncircle(){return 0;}
~hexagon(){}
};
//Фасадный класс для выполнений операций с фигурами
class Operation
{ //Класс, инкапсулирующий методы обработки всех объектов иерархии
public:
//Сравнение площадей
void Compare(Shape* s1, Shape* s2)
{// Проверка правильности подбора типов фигур
if ((s1->ID=='T' && s2->ID=='R')||(s2->ID=='T' && s1->ID=='R'))
cout<<"Correct choice"<<endl;
else {cout<<"Not such operation"<<endl; return;}
//Вычисления
if (s1->GetArea()> s2->GetArea()) cout<<"Area "<<s1->ID<<" > "<<s2->ID<<endl;
if (s1->GetArea()==s2->GetArea()) cout<<"Area "<<s1->ID<<" = "<<s2->ID<<endl;
if (s1->GetArea()< s2->GetArea()) cout<<"Area "<<s1->ID<<" < "<<s2->ID<<endl;
}
//Прверка на включение
void IsInclude(Shape* s1, Shape* s2)
{
if ((s1->ID=='T' && s2->ID=='R')||(s2->ID=='T' && s1->ID=='R'))
{
bool b=false;
Point Center1=(*s1).GetCenter();
Point Center2=(*s2).GetCenter();
int R1 = (*s1).GetRadOutcircle();
int R2 = (*s2).GetRadOutcircle();
Point lc1, lc2, rc1, rc2;
lc1.x=Center1.x - R1; lc2.x=Center2.x - R2;
lc1.y=Center1.y - R1; lc2.y=Center2.y - R2;
rc1.x=Center1.x + R1; rc2.x=Center2.x + R2;
rc1.y=Center1.y + R1; rc2.y=Center2.y + R2;
if (((lc1.x>=lc2.x) && (rc1.x<=rc2.x)) && ((lc1.y>=lc2.y) &&
(rc1.y<=rc2.y)))
{
cout << "Shape " << s1->ID << " in " << s2->ID << endl;
b=true;
}
if (((lc1.x<=lc2.x) && (rc1.x>=rc2.x)) && ((lc1.y<=lc2.y) &&
(rc1.y>=rc2.y)))
{
cout << "Shape " << s2->ID << " in " << s1->ID << endl;
b=true;
}
if (b==true)
cout <<"Includes" << endl;
else
cout << "Dont includes" << endl;
}
else
{
cout << "Not such operation" << endl;
return;
}
}
//Проверка на пересечение
void IsIntersect(Shape* s1, Shape* s2)
{
if ((s1->ID=='T' && s2->ID=='R')||(s2->ID=='T' && s1->ID=='R'))
{
bool b = false;
Point Center1=(*s1).GetCenter();
Point Center2=(*s2).GetCenter();
int R1 = (*s1).GetRadOutcircle();
int R2 = (*s2).GetRadOutcircle();
Point lc1, lc2, rc1, rc2;
lc1.x=Center1.x - R1; lc2.x=Center2.x - R2;
lc1.y=Center1.y - R1; lc2.y=Center2.y - R2;
rc1.x=Center1.x + R1; rc2.x=Center2.x + R2;
rc1.y=Center1.y + R1; rc2.y=Center2.y + R2;
if ((lc2.x<lc1.x<rc2.x || lc2.x<rc1.x<rc2.x) && (lc2.y<lc1.y<rc2.y ||
lc2.y<rc1.y<rc2.y))
b = true;
else
b = false;
if (b)
cout << "Intersects" << endl;
else
cout << "Dont intersects" << endl;
}
else
{
cout << "Not such operation" << endl;
return;
}
}
};
// Класс–фабрика объектов, производных от Shape
class FactoryShape{
public:
Shape* generator()
{ switch(rand() % 3) {
case 0:
return new Triangle;
case 1:
return new Rectangle;
case 2:
return new Octagon;
}
}
};
int main()
{
//Создаем 2 указателя на базовый класс
Shape *p1=0,*p2=0;
//Создаем заданные объекты
FactoryShape f;
cout<<"Input 1-t shape"<<endl;
char cond='y';
while (cond=='y')
{
if (p1) delete p1;
p1=f.generator();
cout<<p1->ID<<endl;
cout<<"Continue choice?(y/…)"<<endl;
cin>>cond;
}
p1->CreateShape();
cout<<"Input 2-d shape"<<endl;
cond='y';
while (cond=='y')
{if (p2) delete p2;
p2=f.generator();
cout<<p2->ID<<endl;
cout<<"Continue choice? (y/…)"<<endl;
cin>>cond;
}
p2->CreateShape();
Operation op;
op.Compare(p1,p2); //Сравниваем площади
op.IsIntersect(p1,p2);//Определяем пересекаются фигуры или нет
op.IsInclude(p1,p2);//Определяем включение фигур
if(p1) delete p1;
if(p2) delete p2;
return 0;
}