Scientific journal
Modern high technologies
ISSN 1812-7320
"Перечень" ВАК
ИФ РИНЦ = 0,940

C++ FOR STUDENTS OF CARTOGRAPHERS AND SURVEYORS: EDUCATIONAL PROGRAM «DIRECT GEODESIC PROBLEM AND ONE (TWO)-DIMENSIONAL ARRAYS»

Zablotskiy V.R. 1, 2 Lugovskoy A.E. 2
1 Bauman Moscow State Technical University
2 Moscow State University of Geodesy and Cartography
The some features of the organization of the C ++ programming course at the Moscow University of Geodesy and Cartography was considered. The course of C++ programming is characterized by using computer programs with geodesic contents, learning C++ and general geodesy in parallel mode, developing highly specialized programs for educational purposes. The code of training program for cartographers and surveyors studying the basics of programming in C++ is discussed. The program calculates the flat rectangular coordinates of the three points specified on a sheet of topographic map. A direct geodesic task is used for calculating X and Y coordinates. The calculated coordinate values are compared with the measured coordinates and the errors of the X and Y coordinates are calculated. The program demonstrates the use of two-dimensional and one-dimensional arrays to store the original and calculated values. The use of the trigonometric functions of cosine and sine at the loop and their mutual transformation based on the loop counter is shown. The program displays the calculated coordinates of points and errors in determining the coordinates. The developed program illustrates the solution of a direct geodesic problem for calculating flat rectangular coordinates of a set of specified points based on the use of procedural programming technology.
teaching C ++ programming
training geodetic program
direct geodesic task
calculation of flat rectangular coordinates of points

Отметим некоторые особенности организации учебного курса по программированию на С++ в Московском университете геодезии и картографии (МИИГАиК). Обучение студентов программированию с геодезическим уклоном проводится на младших курсах параллельно с курсом общей геодезии. Поэтому желательно, чтобы компьютерные программы, используемые на занятиях по программированию, соответствовали той последовательности, в которой учебный материал излагается в курсе общей геодезии. Использование программ с решениями геодезических задач, не изученных студентами в базовом курсе геодезии, является малоэффективным. Кроме того, в процессе обучении программированию изучаемые конструкции языка должны рассматриваться в определенной последовательности. Это неизбежно приводит к тому, что преподаватель ограничен узким набором языковых конструкций, особенно на начальном этапе курса. Как результат, некоторые учебные программы содержат решения, реализованные не самым эффективным способом. Если понятие «оператор цикла» в курсе программирования изучается раньше понятия «функция», то в программах, иллюстрирующих циклы, нежелательно использовать функции, например тригонометрические функции или функции округления. Что не очень удобно и желательно учитывать при разработке учебных программ.

Целью данной работы является разработка типовых учебных компьютерных программ и заданий с геодезическим содержанием для обучения студентов – картографов и геодезистов основам программирования на языке С++.

Заметим, что обучение студентов программированию на С++ часто проводится по классическому учебнику С. Прата [1], учебникам Г.С. Ивановой и др. [2, 3], подготовленным в МГТУ им. Н.Э. Баумана, самоучителям Дж. Либерти и С. Дэвиса [4, 5]. Однако в настоящее время отсутствуют учебники по программированию, ориентированные на подготовку картографов и геодезистов. Нашей основной задачей [6] является разработка учебных программ. Эти программы не следует рассматривать как универсальные, предназначенные для обработки исходных геодезических данных в широком наборе комбинаций и при разных условиях. Программы для обучения студентов должны лишь иллюстрировать различные конструкции языка С++ на примере решения конкретных геодезических задач, может, даже и частных задач. Приведем пример, поясняющий сказанное. Известно, что прямая угловая засечка реализуется в геодезической практике, как правило, с дополнительным контрольным пунктом или в виде двукратной прямой засечки с уравниванием полученных данных. Однако если реализовать такую универсальную программу, то её код будет существенно превышать 50 строк и, как следствие, программа станет малопонятной и трудноусваиваемой для первоначального изучения. Поэтому учебные программы должны быть в основном небольшими (объемом до 50 строк), в тоже время охватывающими все разделы современного языка С++.

Материалы и методы исследования

Работа выполнена на персональном компьютере под управлением ОС Microsoft Windows 8.1. Для разработки программы использовалась среда программирования с открытым кодом Code:Blocks и компилятор GCC C++. Созданная программа запускается в командной строке, и результат выводит в командную строку.

В данной работе представлена учебная программа для студентов картографов и геодезистов, демонстрирующая использование прямой геодезической задачи при вычислении плоских прямоугольных координат трех точек, заданных на топографической карте. Рассмотрим геодезическую постановку задачи. Пусть даны три точки на топографической карте А(XА,YА), В(XB,YB) и С(XC,YC). Требуется определить их координаты по карте и вычислить эти же координаты на основе решения прямой геодезической задачи. Также необходимо сравнить вычисленные и измеренные координаты точек. Графическая часть задачи состоит в непосредственных измерениях на карте с помощью геодезического транспортира трех дирекционных углов направлений αA, αB, αC и трех расстояний d1, d2, d3 между точками с помощью линейки. Вычислительная часть задачи заключается в использовании формул для решения прямой геодезической задачи и вычислении по формулам координат точек. Прямоугольные X и Y координаты некоторой точки P вычисляются по формулам zabl01.wmf и zabl02.wmf, где ΔX и ΔY – значения приращения X и Y координат опорной точки, вычисляемые по формулам: zabl03.wmf, zabl04.wmf и α – дирекционный угол направления. В таблице представлены данные вспомогательных измерений для вычисления координат искомых точек, а также результаты измерения этих же координат по карте. Координаты опорной точки выделены в таблице полужирным шрифтом.

Точка

α

S

Xизм, м

Yизм, м

А

337 °33′

738

6066785

4311832

B

63 °54′

818

6067471

4311549

C

203 °30′

1131

6067824

4312274

Результаты исследования и их обсуждение

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

01: #include <iostream>

02: #include <iomanip>

03: #define Pi 3.141592653589793L

04:

05: using namespace std;

06: int main (void)

07: {

08: double measuredXYcoordinates[2][3] = {6066785,6067471,6067824,

08: 4311832, 4311549, 4312274};

09: double calculatedXYcoordinates[2][3] = { 0, 0, 0,

09: 0, 0, 0};

10: double errorXYcoordinates[2][3] = { 0, 0, 0,

10: 0, 0, 0 };

11: double gridAzimuth[2][3] = { 337, 63, 203, // градусы

11: 33, 54, 30 }; // минуты

12: double distance[3] = {738, 818, 1131}; // метры

13: double radian[3] = { 0, 0, 0};

14:

15: for(int j = 0; j < 3; j++) {

16: gridAzimuth[0][j] = gridAzimuth[0][j] + gridAzimuth[1][j]/60;

17: radian[j] = gridAzimuth[0][j] * Pi/180;

18: }

19: calculatedXYcoordinates[0][0] = measuredXYcoordinates[0][0];

20: calculatedXYcoordinates[1][0] = measuredXYcoordinates[1][0];

21: for(int i = 0; i < 2; i++)

22: for(int j = 1; j <= 3; j++)

23: calculatedXYcoordinates[i][j%3]=calculatedXYcoordinates[i][j-1]+

23: distance[j-1]*cos(i*Pi/2 - radian[j-1]);

24: for(int i = 0; i < 2; i++)

25: for(int j = 0; j < 3; j++)

26: errorXYcoordinates[i][j] = measuredXYcoordinates[i][j] -

26: calculatedXYcoordinates[i][j];

27: cout << fixed << setprecision(0);

28: char c; int j;

29: for( j = 0, c ='A'; j < 3; j++, c++){

30: cout << endl <<"Point "<< c << "\t\tX\t\t\tY" << endl;

31: for(int i = 0; i < 2; i++){

32: cout <<"Calculated: "<< calculatedXYcoordinates[i][j] << "\t";

33: }

34: cout << endl;

35: for(int i = 0; i < 2; i++){

36: cout <<"Measured: "<< measuredXYcoordinates[i][j] << "\t";

37: }

38: cout << endl;

39: for(int i = 0; i < 2; i++){

40: cout <<"Error:\t\t "<< showpos << errorXYcoordinates[i][j]

40: <<"\t" << noshowpos;

41: }cout << endl;

42: }

43: return 0;

44: }

Рассмотрим код программы. Инициализация массивов значениями координат Х и Y трех точек выполняется в строках 08-09. Причем массив измеренных координат Х и Y инициализируется значениями, считанными с топографической карты, массив вычисленных координат – нулевыми значениями. Эти два массива удобно представить в виде матриц размерности 2*3, в которых первая строка содержит Х-координаты, а вторая строка – Y-координаты точек. Здесь уместно напомнить, что в языках программирования С и С++ нумерация элементов массива начинается с нулевого индекса. Далее в строке 10 массив погрешностей errorXYcoordinates, вычисляемых как разность значений измеренных и вычисленных координат, инициализируется также нулевыми значениями. Массив gridAzimuth[2, 3] инициализируется значениями дирекционных углов, полученных по результатам угловых измерений на карте с помощью геодезического транспортира (строка 11). Данный массив имеет размерность 2*3 и содержит в первой строке матрицы значения градусов, во второй – значения минут дирекционных углов. В строке 12 одномерный массив distance [3] инициализируется значениями расстояний между отмеченными на карте точками, причем эти расстояния уже переведены в метры. В строке 13 одномерный массив radian[3] для дирекционных углов направлений в радианах, инициализируется нулевыми значениями.

Таким образом, пользователь, работая с программой, не вводит никаких данных, все необходимые исходные данные встроены в код программы. Это сделано в учебно-методических целях, поскольку программа предназначена для анализа листинга с кодом и обучения студентов. Так легче проследить в коде программы изменения величин в ходе работы программы и тем самым ознакомиться с особенностями обработки данных, представленных в массивах.

Обработка данных начинается в строке 15, в которой используется цикл for для перебора всех значений массива дирекционных углов. В цикле выполняется сложение значений градусов с минутами, представленными как дробная часть градусов. В результате в первой строке массива gridAzimuth[0][j] (индекс 0) сохраяются дирекционные углы в градусах с дробной частью. Далее полученные значения преобразуются в радианы. Здесь используется именованная константа Pi (определенная ранее в строке 3) и равная π = 3,141592653589793L. Суффикс L в конце записи числа π используется, чтобы сохранить в константе 16 значащих цифр числа «пи». Такая запись означает, что данная числовая константа имеет тип данных long double в отличие от констант типа double, устанавливаемых по умолчанию.

В обработке двумерных массивов используются вложенные циклы – особые управляющие конструкции, например в строках 21–22 вложенные циклы for используются для вычисления Х и Y координат точек. Конструкция, представленная далее, позволяет перебрать все элементы двумерного массива при вычислении Х и Y координат трех точек.

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

for(int j = 1; j <= 3; j++)

calculatedXYcoordinates[i][j%3] =

calculatedXYcoordinates[i][j-1]+distance[j-1]*cos(i*Pi/2-radian[j-1]);

Обращаем внимание читателя на две особенности рассматриваемой конструкции. Первая заключается в том, что счетчик вложенного цикла начинается со значения j = 1 и заканчивается j = 3. Такой выбор начального и конечного значения позволяет при вычислении выражения j %3 получить следующие значения индекса массива: 1, 2 и 0 (остаток от деления 3 %3 = 0). В результате таких манипуляций с индексом нет необходимости выполнять циклический сдвиг элементов массива, чтобы разместить элементы массива в правильной последовательности. Вторая особенность заключается в выражение cos(i*Pi/2-radian[j]), которое используется в инструкции цикла и позволяет вычислять как косинус, так и синус некоторого угла. В этом выражении счетчик цикла i включен в тело внутреннего цикла for и реализует либо функцию косинуса, либо функцию синуса с помощью одной математической формулы. Действительно, при i = 0, данная запись эквивалентна выражению cos(radian[j]), а при i=1, – выражению sin(radian[j]).

Без манипуляции индексами (вида j %3) массива, (если использовать одинаковые начальные индексы для внешнего и внутреннего циклов), потребуется циклическая перестановка элементов массива.

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

for(int j = 0; j < 3; j++)

calculatedXYcoordinates[i][j] =

calculatedXYcoordinates[i][j]+distance[j]*cos(i*Pi/2-radian[j]);

Циклическую перестановку можно осуществить с помощью следующих инструкций:

double temp;

for(int i = 0; i < 2; i++){

temp = calculatedXYcoordinates[i][2];

for(int j = 2; j > 0; j--)

calculatedXYcoordinates[i][j]=calculatedXYcoordinates[i][j-1];

calculatedXYcoordinates[i][0] = temp; }

В данном фрагменте кода вычисленные значения координат записываются в массив с последовательным перебором индексов, Х и Y координаты точки В – в первый столбец двумерного массива с индексом 0, координаты точки С – во второй столбец с индексом 1 и координаты точки А – в третий столбец с индексом 2. Для расчета разностей измеренных и вычисленных координат в цикле for возможно использовать одинаковые индексы в обозначении измеренных и вычисленных координат, принадлежащих одной точке. В этом случае для осуществления циклического сдвига значений координат в массиве используется временная переменная temp. Далее в строках 24-26 выполняется вычисление разностей координат: из измеренных координат вычитаются вычисленные координаты точек, результаты помещаются в двумерный массив errorXYcoordinates[i][j]. Оставшаяся часть кода (строки 27–42) предназначена для форматированного вывода результатов на экран. Поскольку результаты вычислений координат имеют погрешности более 1 м, Х и Y координаты точек выводятся на экран в виде целых чисел, дробная часть не высвечивается. Для этого в строке 27 поток вывода информации переводится в режим fixed и устанавливается точность вывода чисел до целых метров с помощью объекта setprecision (0). Здесь 0 означает вывод с точностью до целых чисел.

В результате работы программа напечатает следующее:

Point A

X

 

Y

Calculated:

6066790

Calculated:

4311834

Measured:

6066785

Measured:

4311832

Error:

–5

Error:

–2

       

Point B

X

 

Y

Calculated:

6067467

Calculated:

4311550

Measured:

6067471

Measured:

4311549

Error:

+4

Error:

–2

       

Point C

X

 

Y

Calculated:

6067827

Calculated:

4312285

Measured:

6067824

Measured:

4312274

Error:

–3

Error:

–11

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

Выводы

Разработана учебная программа для студентов картографов и геодезистов, изучающих основы программирования на языке С++. Программа демонстрирует вычисление плоских прямоугольных координат трех точек, заданных на топографической карте. Вычисления координат точек проводятся на основе решения прямой геодезической задачи. Подробно описывается код программы и поясняется назначение использованных инструкций. В программе используются двумерные и одномерные массивы, позволяющие хранить значения координат, дирекционных углов и расстояний. На экран координаты точек и погрешности определения координат выводятся с точностью до целых метров. Разработанная программа иллюстрирует использование массивов для решения прямой геодезической задачи и вычисление плоских прямоугольных координат на основе применения технологии процедурного программирования.