§ 16. Тип данных структура (struct)

16.2. Использование структур для описания геометрических объектов

Простейшим геометрическим объектом на плоскости является точка, которая задается своими координатами. Точка описана в примере 16.1. Пара точек на плоскости определяет отрезок, который описан в примере 16.5.

Еще одним важным геометрическим объектом на плоскости является прямая. В математике используют разные способы описать прямую с помощью уравнений. Уравнение прямой на плоскости в прямоугольной системе координат — это некоторое уравнение с двумя переменными x и y, которое обращается в тождество при подстановке в него координат любой точки этой прямой. Любая форма уравнения прямой имеет параметры. Используя параметры уравнения, можно описать соответствующую структуру (пример 16.7). Разные формы уравнения прямой (в большинстве случаев) могут быть приведены друг к другу, поскольку они описывают один и тот же объект. Использование той или иной формы уравнения прямой зависит от задачи. Уравнение прямой в общем виде является наиболее универсальным. Любая другая форма уравнения прямой всегда может быть приведена к общему уравнению прямой.

Пример 16.8. Известны координаты двух точек, через которые проходит прямая. Получить запись уравнения этой прямой в общем виде.

Этапы выполнения задания

I. Исходные данные: переменная p1 (структура, описывающая уравнение прямой, проходящей через две точки).

II. Результат: переменная p2 (структура, описывающая уравнение прямой в общем виде).

III. Алгоритм решения задачи.

1. Ввод исходных данных. Вводим координаты двух точек и создаем из них структуру p1.
2. 
Для того чтобы из одной структуры получить другую, создадим функцию tchk_to_pr.
3. 
Для получения соответствующих коэффициентов выполним следующие тождественные преобразования уравнения прямой, проходящей через две точки.

begin mathsize 18px style left parenthesis x space – space x subscript 1 right parenthesis left parenthesis y subscript 2 – space y subscript 1 right parenthesis space equals space left parenthesis y space – space y subscript 1 right parenthesis left parenthesis x subscript 2 space – space x subscript 1 right parenthesis space left right double arrow
left right double arrow left parenthesis y subscript 2 – space y subscript 1 right parenthesis x space minus left parenthesis y subscript 2 space minus space y subscript 1 right parenthesis space x subscript 1 space minus space left parenthesis x subscript 2 minus space x subscript 1 right parenthesis space y space plus space left parenthesis x subscript 2 minus space x subscript 1 right parenthesis space y subscript 1 equals 0 end style

begin mathsize 18px style A space equals space y subscript 2 space minus space y subscript 1 semicolon space space space B space equals space x subscript 1 space minus space x subscript 2 semicolon space space C space equals space space y subscript 1 x subscript 2 space minus space x subscript 1 y subscript 2 end style

4. Вывод результата.

IV. Описание переменных: p1, p2 – struct.

Пример 16.9. Известны координаты точки и коэффициенты уравнения прямой в общем виде. Определить, принадлежит ли точка прямой.

Этапы выполнения задания

I. Исходные данные: переменная АВ (структура, описывающая уравнение прямой в общем виде), А (структура, описывающая точку).

II. Результат: сообщение «да» или «нет».

III. Алгоритм решения задачи.

1. Ввод исходных данных.
2. 
Для того чтобы проверить, лежит ли точка на прямой, создадим функцию tchk_na_pr.
3. 
Точка лежит на прямой, если при подстановке ее координат в уравнение прямой получим верное равенство (для общего уравнения должны получить 0). Поскольку вычисления проходят в вещественных числах, то будем проверять, что полученное значение по модулю меньше, чем 10-6. Такой точности на практике обычно бывает достаточно.
4. 
Вывод результата.

IV. Описание переменных: A, AB – struct.

Пример 16.10. Известны координаты концов отрезка и коэффициенты уравнения прямой в общем виде. Определить, имеют ли прямая и отрезок общие точки.

Этапы выполнения задания

I. Исходные данные: переменная CD (структура, описывающая уравнение прямой в общем виде), АB (структура, описывающая отрезок).

II. Результат: сообщение «да» или «нет».

III. Алгоритм решения задачи.

1. Ввод исходных данных. Структуру AB создаем по введенным координатам двух точек.

2. Для того чтобы проверить, имеют ли прямая и отрезок общие точки, создадим функцию otr_na_pr.

3. Отрезок имеет с прямой общие точки, если выполняется одно из условий:

3.1. Один из концов отрезка лежит на прямой.
3.2. Оба конца отрезка лежат на прямой.
3.3. Прямая пересекает отрезок.

4. Если точка лежит на прямой, то при подстановке ее координат в уравнение, в левой части общего уравнения прямой получаем 0. Если точка не принадлежит прямой, то получаем одно из двух неравенств: begin mathsize 16px style A x space plus space B y space plus space C space less than space 0 end style  или   A x space plus space B y space plus space C space greater than space 0. Каждое из неравенств определяет полуплоскость относительно заданной прямой. Прямая пересекает отрезок, если его концы находятся в разных полуплоскостях относительно заданной прямой.

5. Поскольку вычисления проходят в вещественных числах, то будем проверять, что полученное значение по модулю меньше, чем 10-6. Такой точности на практике обычно бывает достаточно.

6. Вывод результата.

IV. Описание переменных: CD, AB – struct.

Пример 16.11. Многоугольник задан списком своих вершин в порядке обхода. Для каждой вершины известны ее координаты на плоскости. Найти периметр многоугольника.

Этапы выполнения задания

I. Исходные данные: n — количество точек, a — массив точек.

II. Результат: периметр многоугольника.

III. Алгоритм решения задачи.

1. Ввод исходных данных. Создаем массив из точек и вводим координаты.
2. 
Каждая сторона многоугольника — это отрезок, соединяющий вершины с соседними номерами. Для того, чтобы не обрабатывать отдельно сторону, соединяющую последнюю вершину с начальной, добавим координаты начальной вершины в конец вектора.
3. 
Для вычисления периметра создадим функцию, которая будет вычислять длину отрезка.
4. 
В цикле переберем пары соседних вершин и вычислим их длины. Сумма длин — искомый периметр.
5. 
Вывод результата.

IV. Описание переменных: n – int, a – vector<tchk>.

Пример 16.7. Формы записи уравнения прямой и соответствующие им описания структур.

Уравнение прямой с угловым коэффициентом: y = kx + l. Уравнение не позволяет описать прямую, параллельную оси OY.

struct pr_ugl_kf

{

  double k, l;

};

Уравнение прямой в отрезках: begin mathsize 16px style x over a space plus space y over b space equals space 1. end style Параметры а и b — величины отрезков, отсекаемых прямой на осях координат. Уравнение не позволяет описать прямую, проходящую через начало координат.

struct pr_v_otr

{

  double a, b;

};

Уравнение прямой, проходящей через две точки begin mathsize 16px style A left parenthesis x subscript 1 comma space space y subscript 1 right parenthesis end style) и  B left parenthesis x subscript 2 comma space space y subscript 2 right parenthesis:

begin mathsize 16px style left parenthesis x space minus space x subscript 1 right parenthesis left parenthesis y subscript 2 space minus space y subscript 1 right parenthesis space equals space left parenthesis y space minus space y subscript 1 right parenthesis left parenthesis x subscript 2 space minus space x subscript 1 right parenthesis end style

struct pr_2_tchk

{

  tchk A, B; 

};

Общее уравнение прямой:

struct pr

{

  double A, B, C;

};

Пример 16.8.

V. Программа:

#include <iostream>

 

using namespace std;

 

struct tchk

{

  double x, y;

};

 

struct pr_2_tchk

{

    tchk A, B;

};

 

struct pr

{

    double A, B, C;

};

 

pr tchk_to_pr(pr_2_tchk t)

{

  pr t1;

  t1.= t.B.- t.A.y;

  t1.= t.A.- t.B.x;

  t1.= t.A.* t.B.- t.A.* t.B.y;

  return t1;

}

 

int main()

{

  tchk A, B;

  cout << "x1, y1" << endl;

  cin >> A.>> A.y;

  cout << "x2, y2" << endl;

  cin >> B.>> B.y;

  pr_2_tchk p1 = {A, B};

  pr p2 = tchk_to_pr (p1);

  cout << "obschee uravnenie: ";

  cout << p2.<< "x + ";

  cout << p2.<< "y + " << p2.C;

  cout << " = 0" << endl;

  return 0;

}

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

Пример 16.9.

V. Программа:

#include <iostream>

#include <cmath>

 

using namespace std;

 

struct tchk

{

  double x, y;

};

 

struct pr

{

  double A, B, C;

};

 

bool tchk_na_pr(pr p, tchk t)

{

  double z = p.* t.+ p.* t.+ p.C;

  return (abs(z) <= 0.000001);

}

 

int main()

{

  tchk A;

  cout << "koord x, y" << endl;

  cin >> A.>> A.y;

  pr AB;

  cout << "koef A, B, C" << endl;

  cin >> AB.>> AB.>> AB.C;

  if (tchk_na_pr(AB, A))

    cout << "da" << endl;

  else

    cout << "net" << endl;

  return 0;

}

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

Пример 16.10.

V. Программа:

#include <iostream>

#include <cmath>

 

using namespace std;

 

struct tchk

{

  double x, y;

};

 

struct otrezok

{

  tchk beg, en;

};

 

struct pr

{

  double A, B, C;

};

 

bool otr_na_pr(pr p, otrezok t)

{

  double z1, z2;

  z1 = p.* t.beg.+ p.* t.beg.+ p.C;

  z2 = p.* t.en.+ p.* t.en.+ p.C;

  return (z1 * z2 < 0 ||

        abs(z1 * z2) <= 0.000001);

}

 

int main()

{

  tchk A, B;

  cout << "koord x1, y1" << endl;

  cin >> A.>> A.y;

  cout << "koord x2, y2" << endl;

  cin >> B.>> B.y;

  otrezok AB = {A, B};

  pr CD;

  cout << "koef A, B, C" << endl;

  cin >> CD.>> CD.>> CD.C;

  if (otr_na_pr(CD, AB))

    cout << "da" << endl;

  else

    cout << "net" << endl;

  return 0;

}

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

Отрезок целиком лежит на прямой.

Один конец отрезка лежит на прямой.

Прямая пересекает отрезок.

Нет общих точек.

Пример 16.11.

V. Программа:

#include <iostream>

#include <vector>

#include <cmath>

 

using namespace std;

 

struct tchk

{

  double x, y;

};

 

double dlina (tchk A, tchk B)

{

  double dl;

  dl = sqrt((A.- B.x) * (A.- B.x) +

            (A.- B.y) * (A.- B.y));

  return dl;

}

 

int main()

{

  int n;

  cout << "n = ";

  cin >> n;

  vector <tchk> a(n);

  for (int i = 0; i < n; i++)

    cin >> a[i].>> a[i].y;

  a.push_back(a[0]);

  double p = 0;

  for (int i = 0; i < n; i++)

    p += dlina(a[i], a[+ 1]);

  cout << "p = " << p << endl;

  return 0;

}

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