Раздел «Язык Си».ClassMass:

Классы со сложными атрибутами

Массивы в классе

REFACTOR Задача

Вершины треугольника заданы координат точек на плоскости.

Необходимо:

  1. создавать треугольник;
  2. задавать координаты вершин;
  3. печатать треугольник;
  4. сравнивать два треугольника;
  5. поворачивать треугольник на 90o налево;
  6. поворачивать треугольник на 90o направо;

Опишем класс Triangle

// Начало мантры
#include <iostream>
#include <cstdlib>
using namespace std;
// Конец мантры

// Известный уже класс Point
// Вершины треугольника - точки на плоскости
class Point{
  int x,y;
public:
    Point();
    Point(int x1, int y2);
// Получить значения с клавиатуры
    void getVal();
// Переместить точку вдоль X на x1, вдоль Y на y1
    void moveOn(int x1, int y1);
// Вычислить на расстояние до а по X
    int diffX(Point a);
// Вычислить на расстояние до а по y
    int diffY(Point a);
// печать
    void print();
};

// Класс Triangle.
// У треугольника три точки, поэтому поместим 
// их в массив Point apex[3];
// А размеры ребер  - в массив int edge2[3];
// Все, кто будет использовать наш треугольник не должны знать
// что точки и ребра - массивы

class Triangle{
   Point apex[3];// массив точек
   int edge2[3]; // массив размеров ребер (в квдрате)
public:
// Вначале наш треугольник "сжимается" до одной точки в (0,0)
    Triangle();
// Получим  координаты точек
// Имя массива точек - это указатель. Поэтому мы пишем 
// параметр - указатель
// Point * a - указатель на первую точку из 
// трех в массиве точек.
    void setApex(Point *a);
// Печать   
    void print();

// Сравнение треугольников.  
// Triangle& a - ссылка на другой треугольник. 
// Ссылка позволяет не создавать
// лишнюю копию и сохранить место в памяти. 
// Но, чтобы нечаянно не изменить "настоящий" треугольник, 
// напишем const
// Тогда, если мы попытаемся изменить атрибуты треугольника a, 
// компилятор напишет сообщение об ошибке
// Если треугольники равны, возвращает 1, нет - 0
    int operator==(const Triangle& a);
}; 
//________Реализция Point_________________________
Point::Point(){
  x=y=0;
};
Point::Point(int x1, int y1){
  x=x1;
  y=y1;
};
void Point::getVal(){
    cin>>x>>y;
};
void Point::moveOn(int x1, int y1){
     x+=x1;
     y+=y1;
};
int Point::diffX(Point a){
    return a.x-x;
};
int Point::diffY(Point a){
   return a.y-y;
};
void Point::print(){
    cout<<'('<<x<<','<<y<<')';
};
//_____________________________________________________

//____Реализация Triangle______________________________

// Конструктор "по-умолчанию". Все размеры сторон  - 0
// Для массива Point a[3] работают конструкторы по-умолчанию
// для точек. Значит все точки в (0,0)
Triangle::Triangle(){
// Необходимо все стороны сделать 0
  for(int i = 0; i < 3; i++)
     edge2[i] = 0;
};
// Получаем указатель на первую точку в массиве a 
void Triangle::setApex(Point *a){
// присваиваем значения из массива точек (Point) a в apex
   for(int i = 0; i < 3; i++)
     apex[i] = a[i]; // точка копируетяв точку

// вычисляем расстояния между сторонами:
// i=0: 0 и  (0 + 1) % 3 = 1 (0 и 1)
// i=1: 1 и  (1 + 1) % 3 = 2 (1 и 2)
// i=2: 2 и  (2 + 1) % 3 = 0 (2 и 0)
   for(int i = 0; i < 3; i++){
     int dx; //  разница по х
     int dy; //  разница по y 
// diffX - для точки вычисляет разницу по x (x1-x2)
// diffY - для точки вычисляет разницу по y (y1-y2)
     dx = apex[i].diffX(apex[(i + 1) % 3]);
     dy = apex[i].diffY(apex[(i + 1) % 3]);
//
     edge2[i] = dx*dx + dy*dy;
   }
};
// печать
void Triangle::print(){
  for(int i = 0; i < 3; i++)
     apex[i].print();
   cout<<endl;
};
//__________________________________________________________
// Если три стороны одного треугольника соответственно равны
// трем сторонам другого треугольника, то такие треугольники
// равны
// Если треугольники равны, возвращается 1, нет - 0
//____________________________________________________________
int Triangle::operator==(const Triangle& a){
       int right = 0;// количество равных сторон вправо
       int left = 0; //  количество равных сторон влево
       int i, k = 0, nom = 0;
// ищем номер стороны нашего треугольника, которая
// равна стороне с номером 0 треугольника a
       for( i = 0; i < 3 ; i++){
            if (edge2[i] == a.edge2[0])
                  break;
       }
// Если не нашлось ни одной стороны 
// (все 3 проверили, и ни одна не равна),
// тогда треугольники точно не равны
       if (i == 3) return 0;

// номер стороны "нашего" треугольника, которая равна
// стороне с номером 0 треугольника a
          nom = i; 
//        cout<<"nom="<<nom<<endl;

// Стороны с номерами 0 и nom  проверять уже не нужно
// Будем проверять следующие
       k = nom + 1;
// Пусть nom = 1. Тогда будем проверять стороны: 
// i = 1; k = 2: (3 + 2) % 3 = 5 % 3 = 2
// i = 2; k = 3: (3 + 3) % 3 = 6 % 3 = 0
       for( i = 1; i < 3 ; i++,k++){
//cout<<"["<<(k + 3) % 3<<"]="<<edge2[(k + 3) % 3];
//cout<<" ["<<i<<"]="<<a.edge2[i];
          if (edge2[ (k + 3) % 3] == a.edge2[i])
             left++;
//        cout<<" "<<left<<endl;
       }
      if(left==2) return 1; // все строны совпали, равны

// Если left !=3, нужно проверить стороны по-другому.      
// Стороны могут быть пронумерованы 
// в обратном порядке 0->1->2: 0->2->1
// Например(квадраты сторон) : 36->52->16 
// или треугольник зеркально отобажен 36->16->52.
// Тогда, сравниваем стороны с номерами: 0:0, 1:2, 2:1
// То есть i увеличивается, а номер стороны второго треугольника
// вычисляется по формуле (3 + k)%3: 
// i=0 -> k=0  n = (3 + 0) % 3 = 0 |0:0
// i=1 -> k=-1 n = (3 - 1) % 3 = 2 |1:2
// i=2 -> k=-2 n = (3 - 2) % 3 = 2 |2:1

// Стороны с номерами 0 и nom  проверять уже не нужно.
// Будем проверять следующие:
       k = nom - 1;
//      cout<<"k="<<k<<endl;
       for( i = 1; i < 3 ; i++,k--){
// cout<<"["<<(3 + k) % 3<<"]="<<edge2[(3 + k) % 3];
// cout<<" ["<<i<<"]="<<a.edge2[i];
          if (edge2[ (3 + k) % 3] == a.edge2[i])
             right++;
//         cout<<" "<<right<<endl;
       }
             
       if(right == 2) // все строны совпали, равны
        return 1;
       return 0;
 };
};

//______________________________________________
int main(){
// Массив точек для двух треугольников
   Point pt[6]; 
// получить координаты всех точек с клавиатуры
   for (int i = 0; i < 6; i++)
      pt[i].getVal();
// Создать два треугольника в (0,0) 
 Triangle tr1, tr2;

// установить координаты вершин для первого треугольника
// имя массива pt - начало первой точки. Всего их три
// pt[0] (адрес pt), pt[1] (адрес pt + 1), 
// pt[2] (адрес pt + 2)
     tr1.setApex(pt);

// установить координаты вершин для второго треугольника
// имя массива pt - начало первой точки. pt + 3 - адрес 
// четвертой точки
// pt[3] (адрес (pt + 3)), pt[4] (адрес (pt + 3) + 1), 
// pt[5] (адрес (pt + 3) + 2)
     tr2.setApex(pt + 3);
     tr1.print();
     tr2.print(); 
// Сравнить треугольники после реализации оператора ==
    if(tr1 == tr2)
     cout<<"ok!\n";
    else
     cout<<"no\n";
}

REFACTOR Задача 1

Начертить 10 разных треугольников, 4 из которых расположены по-разному, но равны. Проверить функцию сравнения.

REFACTOR Задача 2

Добавить функции void Right90() и void Left90(), которые поворачивают треугольник на 90o относительно первой точки apex[0]. Проверить работу функций.

REFACTOR Задача 3

Даны точки для 10 треугольников (30).
  1. Создать массив треугольников Triangle mass[10].
  2. Задать координаты вершин.
  3. Повернуть все треугольники с четными номерами направо, а с нечетными налево.
  4. Напечать все треугольники после поворота.

REFACTOR Задача 4

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

REFACTOR Задача 5

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

-- TatyanaOvsyannikova2011 - 14 Nov 2015