1.8. Функция search_tops.
Принимает на вход указатель на структуру с данными BmpBasket и массив с данными arr[][]. Рекурсивно проходит по фигуре алгоритмом заливки, ища наибольшие и наименьшие вершины и модифицируя данный BmpBasket. Ничего не возвращает.
void search_tops(uint32_t y,uint32_t x,BmpBasket* basket, uint8_t arr[basket->height][basket->width]){
arr[y][x]= 2;
if((y >= basket->top1.Y) && (x <= basket->top1.X)) {
basket->top1.X = x; basket->top1.Y = y;
}
if((y >= basket->top2.Y) && (x >= basket->top2.X)) {
basket->top2.X = x; basket->top2.Y = y;
}
if((y <= basket->top3.Y) && (x >= basket->top3.X)) {
basket->top3.X = x; basket->top3.Y = y;
}
if((y <= basket->top4.Y) && (x <= basket->top4.X)) {
basket->top4.X = x; basket->top4.Y = y;
}
if((x < (basket->width-1)) && (arr[y][x+1] == 1)){
search_tops(y,x+1,basket,arr);
}
if((y < (basket->height-1)) && (arr[y+1][x] == 1)){
search_tops(y+1,x,basket,arr);
}
if((x > 0) && (arr[y][x-1] == 1)){
search_tops(y,x-1,basket,arr);
}
if((y > 0) && (arr[y-1][x] == 1)){
search_tops(y-1,x,basket,arr);
}
return;}
1.9. Функция main.
В этой функции были созданы следующие переменные:
-
BitMapFileHeader file_header и BitMapInfoHeader info_header - необходимые для считывания информации о файле;
-
RGB rgb - для считывания пикселей;
-
BmpBasket basket – для хранение информации;
-
Point p1_max и p2_max – для хранения итоговых точек;
-
uint8_t pixel_grid[basket.height][basket.width] - для хранения массива в подготовленном виде.
В этой функции осуществляется считывание входных данных, проверка на наличие файла и вызов функций для поиска вершин фигуры и проверки, является ли она прямоугольником.
int main(){
BitMapFileHeader file_header;
BitMapInfoHeader info_header;
RGB rgb;
BmpBasket basket;
Point p1_max;
Point p2_max;
char input_file[20];
printf("Enter file name: ");
scanf("%s", input_file);
FILE* file = fopen(input_file,"rb");
if(!file){
printf("Fail with file\n");
return 0;
}
fread(&file_header, sizeof(struct BitMapFileHeader), 1, file);
fread(&info_header, sizeof(struct BitMapInfoHeader), 1, file);
basket.height = info_header.biHeight;
basket.width = info_header.biWidth;
uint8_t pixel_grid[basket.height][basket.width];
Находим число пустых байтов необходимых для дописывания.
uint8_t empty_bytes = 0;
if ((basket.width * 3) % 4) {
empty_bytes = 4 -( (basket.width * 3) % 4);
}
Считываем картинку создавая двухцветный массив pixel_grid( 1 -белый цвет, 0 -остальные).
for (int32_t i = basket.height -1; i >= 0 ; i--) {
for (uint32_t j = 0; j < basket.width; j++) {
fread(&rgb, sizeof(RGB), 1, file);
if(rgb.red == 255 && rgb.blue == 255 && rgb.green == 255){
pixel_grid[i][j] = 1;
}else{
pixel_grid[i][j] = 0;
}
}
if (empty_bytes) {
fread(&rgb, empty_bytes, 1, file);
}
}
Инициализируем переменные для площади фигуры и максимальной площади фигуры. В циклах движемся по массиву, пытаясь найти часть фигуры, и перекрашивая пройденные ячейки. В случае успеха запускаем search_tops для поиска вершин и rectangle для проверки на прямоугольник. И сравниваем площадь с максимальной и перезаписываем итоговые точки, если нужно.
int32_t S,S_max = 0;
for (uint32_t i = 0; i < basket.height; i++) {
for (uint32_t j = 0; j < basket.width; j++) {
if(pixel_grid[i][j] == 1){
basket.top1.X = j; basket.top1.Y = i;
basket.top2.X = j; basket.top2.Y = i;
basket.top3.X = j; basket.top3.Y = i;
basket.top4.X = j; basket.top4.Y = i;
search_tops(i,j,&basket,pixel_grid);
S = rectangle(&basket,pixel_grid);
if( S > S_max){
S_max = S;
p1_max.X = basket.top1.X; p1_max.Y = basket.top1.Y;
p2_max.X = basket.top3.X; p2_max.Y = basket.top3.Y;
}
}
pixel_grid[i][j] = 2;
}
}
Если нашли прямоугольник, то выводим точки и закрываем файл.
if(S_max > 0){
printf("X1:%5d Y1:%5d\n",p1_max.X,p1_max.Y);
printf("X2:%5d Y2:%5d\n",p2_max.X,p2_max.Y);
}else{
printf("Not rectangle\n");
}
fclose(file);
return 0;
}