С.И.Хашин
В начале реализован совсем простой класс "точка на плоскости":
class pnt { public: int x, y; pnt(int x_ = 0, int y_ = 0) { x = x_; y = y_; }; bool operator==(pnt& rhs) { return x == rhs.x && y == rhs.y; }; };
Затем описываем массив точек:
class pvector{ // вектор точек vectorv; pvector(int n); // конструктор void setSize(int n); // задать размер ... };
Помимо естественных основных методов имеются нахождение максимумов и минимумов каждой из координат, а также:
int getX(int i); // x-координата i-й точки int getY(int i); // y-координата i-й точки void add(pnt &p); // добавить точку в вектор void add(int x, int y);// добавить точку в вектор void add(pvector &w); int maxX(); // максимальное значение x-координаты int maxY(); // максимальное значение y-координаты int minX(); // минимальное значение x-координаты int minY(); // минимальное значение y-координаты void del(int k0, int k1);// delete points [k0..k1] exactly int indexOf(pnt p); // поиск точки p в массиве, -1 - не найдено
Сохранение в файл и чтение из файла:
void save(char *filename, char *msg, int k = 1, char *frm = " (%4d,%4d)"); // сохранить в файл по k штук в строку по формату frm void load(char *filename); // прочитать из файла
При сохранении вектора точек в файле, обычно вектор сохраняется по одной точке в строке:
list.save("t:\\list.txt", "source " );
Результат (121 – количество элементов вектора):
1) source , #121 0) ( 30, 10) 1) ( 31, 10) 2) ( 32, 10) 3) ( 33, 10) …
Можно сохранить по нескольку точек в строке (например, 3):
list.save("t:\\list2.txt", "source (square)", 3 );
Результат:
3) source (square), #121 0( 0): ( 30, 10) ( 31, 10) ( 32, 10) 3( 1): ( 33, 10) ( 34, 10) ( 35, 10) 6( 2): ( 36, 10) ( 37, 10) ( 38, 10) …
Можно, кроме того, задать формат вывода каждой пары координат:
hull.save("t:\\list3.txt", "save-load-save", 3, " (x=%2d, y=%2d)" );
Результат:
3) save-load-save, #121 0( 0): (x=30, y=10) (x=31, y=10) (x=32, y=10) 3( 1): (x=33, y=10) (x=34, y=10) (x=35, y=10) 6( 2): (x=36, y=10) (x=37, y=10) (x=38, y=10) 9( 3): (x=39, y=10) (x=40, y=10) (x=30, y=11) …
Можно создать список, содержащий все точки круга или прямоугольника:
void createCircle( int x0, int y0, double rad, int mx=0, int my=0); // построить круг. Если mx,my>0, то точки не должны заходить за эти пределы void createBox ( int x0, int y0, int dx, int dy); // построить прямоугольник
А теперь то же самое, но только точки, обе координаты которых делятся на k:
void createCircleK(int x0, int y0, double rad, int K, int mx = 0, int my = 0); void createBoxK(int x0, int y0, int dx, int dy, int K);
сортировка
void sortByX (); // отсортировать список по убыванию X void sortByX_(); // отсортировать список по возрастанию X void sortByY (); // отсортировать список по убыванию Y void sortByY_(); // отсортировать список по возрастанию Y
средние и далекие точки
double middPoint_(pnt &m); // m - среднее значение векторов p[i], возвращает // среднеквадратичное расстояние до центра double middPoint(double &x1, double &y1); // (x1,y1) среднее значение векторов p[i], возвращает среднеквадратичное расстояние до центра int mostFarPoint(pnt &a); // индекс в списке p самой дальней от a точки int nearestPoint(pnt &a); // индекс в списке p самой близкой к a точки
сократить список до заданного размера:
void reduceList( pvector &list, int newSize); // this:= проредить список точек list // так, чтобы осталось ~newSize точек
// Координаты всех точек поделить на k (точки должны остаться различными) // Если заданы mx, my, то новые координаты не должны превышать (mx,my) void listDividQ( pvector &list, int k, int mx=0, int my=0);
Нахождение выпуклой оболочки множества точек:
void convexHull(pvector &p);// this = выпуклая оболочка(p)
Пример.
pvector l,l1; // создали объекты l.createCircle(10, 10, 3); // l:= круг радиуса 3 l.save("l.txt", "circle", 10, "(%2d,%2d)"); // сохранить по 10 в ряд l1.convexHull(l); // l1:=выпуклая оболочка l1.save("l1.txt", "Hull"); // сохранить по одной точке в ряд.
В файле l.txt получим:
10) circle, #29 0( 0): (10, 7)( 8, 8)( 9, 8)(10, 8)(11, 8)(12, 8)( 8, 9)( 9, 9)(10, 9)(11, 9) 10( 1): (12, 9)( 7,10)( 8,10)( 9,10)(10,10)(11,10)(12,10)(13,10)( 8,11)( 9,11) 20( 2): (10,11)(11,11)(12,11)( 8,12)( 9,12)(10,12)(11,12)(12,12)(10,13)
В файле l1.txt получим:
10) circle, #29 0( 0): (10, 7)( 8, 8)( 9, 8)(10, 8)(11, 8)(12, 8)( 8, 9)( 9, 9)(10, 9)(11, 9) 10( 1): (12, 9)( 7,10)( 8,10)( 9,10)(10,10)(11,10)(12,10)(13,10)( 8,11)( 9,11) 20( 2): (10,11)(11,11)(12,11)( 8,12)( 9,12)(10,12)(11,12)(12,12)(10,13)