Мегаобучалка Главная | О нас | Обратная связь


П .1.9 ТЕКСТ МОДУЛЯ TAnalysePicture.cpp



2020-02-03 174 Обсуждений (0)
П .1.9 ТЕКСТ МОДУЛЯ TAnalysePicture.cpp 0.00 из 5.00 0 оценок




#include "StdAfx.h"

#include "TAnalysePicture.h"

TAnalysePicture::TAnalysePicture(const CString src, CDC *screen)

{

pic = new TFingPicture(screen);

err = -1;

if(!pic->Load(src)) err = 0;

pic->Rectangle(CPoint(0, 0), pic->GetSize(), 10);

srcImg = src;

tmpPic = new TFingPicture(screen);

tmpPic->Load(src);

pic2 = new TFingPicture(screen);

pic2->Load(BLANK);

}

TAnalysePicture::~TAnalysePicture(void)

{

delete(tmpPic);

delete(pic2);

delete(pic);

}

//Код ошибки

int TAnalysePicture::getErr()

{

return err;

}

//Сообщение ошибки

CString TAnalysePicture::getErrMsg()

{

CString msg = "";

switch (err)

{

case -1: {msg = "Ошибок при загрузке изображения нет"; break;}

case 0: {msg = "Изображение не загружено"; break;}

case 1: {msg = "Возникла ошибка при загрузке изображения"; break;}

default: {msg = "Нераспознанная ошибка";}

}

return msg;

}

// Обработка загруженного изображения и получение образа

TAbsFing TAnalysePicture::AnalysePicture()

{

TAbsFing ret, ret2;

if(err != -1)

{

if(MESSAGEOUT) MessageBox(NULL, getErrMsg(), "Ошибка", MB_OK);

return ret;

}

int prevCol;

int changeN = 0; //Счетчик произведенных изменений на изображении

list<TMapElDot> map; //Карта точек принадлежащих линиям

list<TMapElDot>::iterator imap; //Итератор для map

map = LookPic(); //сканирование картинки и нахождение линий на ней

do{

changeN = 0;

prevCol = (int)map.size();

imap = map.begin();

do{     //Изображение можно модифицировать

if(imap->pr1)           //Линия нуждается в обработке

changeN += ChangeLine(imap, map);  //Обработка (преобразование) изображения

imap++;          //Переход для обработки следующей линии

}while(imap != map.end()); //Изображение можно модифицировать

}while(prevCol<0.1*map.size()); //Изображение можно модифицировать

map = LookPic(); //сканирование картинки и нахождение линий на ней

imap = map.begin();

do{        //Изображение можно модифицировать

ret.merge(ReadPic(imap));

imap++;          //Переход для обработки следующей линии

}while(imap != map.end()); //Изображение можно модифицировать

////////////////////////////////////////////////////////////////////

/////////////////////Фильтрование полученных точек//////////////////

///отсеиваются близкостоящие направленные в противоположные строки//

//////////а так же точки слева и справа от которых нет линий////////

int leftDots = 0; //число отсеянных точек

leftDots = DotsFilter(ret);  //Фильтрование полученных точек

////////////////////////////////////////////////////////////////////

ret2.clear();

for(TAbsFing::iterator iter = ret.begin(); iter != ret.end(); iter++)

{       

if(!iter->show) continue;

//рисование найденных точек (цвет окончания и раздвоения различный)

COLORREF col = (iter->type)?0xFF0000:0x000000;

pic2->Line(iter->coord, iter->coord, 5, col);

pic2->Line(iter->coord,

CPoint(iter->coord.x+(int)(10.0*cos(iter->alpha)),iter->coord.y-(int)(10.0*sin(iter->alpha))),

2, col);

ret2.push_back(*iter);

}

ret.clear();

return ret2;

}

TAbsFing TAnalysePicture::ReadPic(list<TMapElDot>::iterator _dot)

//Нахождение на изображении спец точек

{

TAbsFing retFing;             //Образ отпечатка в абсолютных координатах

int kol = 0; //количество пройденных точек

int vec = 0;      //направление поиска очередной точки

int tekS = 0;    //Текущее количество коротких векторов

CPoint   A,          //Начало вектора

B; //Конец вектора

TAbsFing vecDotS; //массив точек для коротких векторов

TAbsFing vecDotL; //массив точек для длинных векторов

TAbsFing historyDotL; //история точек для длинных векторов

TAbsDot _tmpDotFing, bestDot;

TAbsFing::iterator iter;

double alpha;           //направление вектора (в радианах)

int stopKol = 2000; //предел шагов

int ret = 0; //счетчик шагов после прохождения начальной точки

bool homeOver = false;     //признак окончания обработки

A = _dot->coord; B = _dot->coord;

CPoint olddot, dot = _dot->coord;                //Текущая точка на линии

do{

//основной цикл обработки,

//варианты завершения цикла

//продолжается до тех пор, пока вся линия не будет пройдена (нормальный вариант)

//зацикливание (не нормальный вариант, их несколько)

//

olddot = dot;

dot = pic->NextDotCW(dot, vec);        //Поиск следующей точки _по часовой_ стрелке

if(dot.x == olddot.x && dot.y == olddot.y)

{//положение точки не изменилось => выход//

CString s;

s.Format("x = %d, y = %d, kol= %d", dot.x, dot.y, kol);

if(MESSAGEOUT)MessageBox(0, "положение точки не изменилось => выход\n" + s, "", MB_OK);

return retFing;

}

kol++;   //подсчет пройденных точек

if(kol % LEN_S == 0)

{//появился новый короткий вектор

tekS++;

A = B;

B = dot;

pic2->Line(A,B, 1, 0x999999);

_tmpDotFing.coord = A;

alpha = GetAlpha(A, B);   //расчет локального направления между KOL_S пикселями (направление короткого вектора)//

double dAlpha = 0.0;        //Разница углов

if(vecDotS.size() > 0)         //в списке можно взять предыдущее значение

dAlpha = alpha - vecDotS.begin()->alpha;

/**/ if (abs(dAlpha) >= M_PI)  //разница между новым углом и предыдущим не нормальная!

{//необходимо скорректировать текущую alpha

/**/ if (dAlpha < 0.0)

{

while (abs(dAlpha) > M_PI)

{

alpha += 2.0 * M_PI;

dAlpha += 2.0 * M_PI;

}

}else

{       

while (dAlpha >= M_PI)

{

alpha -= 2.0 * M_PI;

dAlpha -= 2.0 * M_PI;

}       

}

}

_tmpDotFing.alpha = alpha; //запоминание направления из точки А//

vecDotS.push_front(_tmpDotFing);

///////////////////////////////////////////////////////////////////////

///////проверяем два соседних длинных вектора при условии что//////////

///////пройдено достаточно точек, чтоб сравнивать длнинные вектора/////

if(vecDotS.size() < KOL_S) continue;

//Вычисление среднего направления LEN_L коротких векторов//

//запись данных по длинному вектору////////////////////////

double sumAlpha = 0.0;

iter = vecDotS.begin();

vecDotL.clear(); //пересчитаем длинные вектора

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

{

sumAlpha += iter->alpha;

if ((i+1) % LEN_L == 0)

{

_tmpDotFing = *iter;

_tmpDotFing.alpha = sumAlpha / LEN_L;

vecDotL.push_back(_tmpDotFing);

sumAlpha = 0.0;

}

iter++;

}

if (abs(vecDotL.begin()->alpha) > 3*2*M_PI)

{//слишком много оборотов//

CString s;

s.Format("alpha = %.2f", vecDotL.begin()->alpha*180);

if(MESSAGEOUT)MessageBox(0, "слишком много оборотов\n"+s, "", MB_OK);

return retFing;

}

//проверяем два соседних длинных вектора//

dAlpha = vecDotL.begin()->alpha - (++vecDotL.begin())->alpha;

if (abs(dAlpha) > (TEST_ALPHA / 180.0 * M_PI)) //сильный изгиб//

{

if (historyDotL.empty())

{ //сохранение состояния//

bestDot.alpha = 0.0;

}

if (dAlpha > 0)         //раздвоение

alpha = (vecDotL.begin()->alpha - M_PI + (++vecDotL.begin())->alpha) / 2.0;

else //окончание

alpha = (vecDotL.begin()->alpha + M_PI + (++vecDotL.begin())->alpha) / 2.0;

_tmpDotFing = vecDotL.front();

_tmpDotFing.alpha = alpha; //направление в СТ (специфичная точка)//

_tmpDotFing.type = dAlpha<0;          //тип СТ//

historyDotL.push_front(_tmpDotFing);

if(bestDot.alpha <= abs(dAlpha))

{       

bestDot.coord = _tmpDotFing.coord;

bestDot.alpha = abs(dAlpha);

}

}

else //сильный изгиб//

{

if (!historyDotL.empty())  //был _пройден_ сильный изгиб

{

alpha = 0;

for(iter = historyDotL.begin(); iter != historyDotL.end(); iter++)

alpha += iter->alpha;

alpha /= historyDotL.size();        //среднее значение в пройденной СТ

iter = historyDotL.begin();

for(unsigned int i = 0; i<(historyDotL.size()/2); i++) iter++;

//CPoint wdot = iter->coord; //наиболее вероятная точка для СТ

CPoint wdot = bestDot.coord;    //наиболее вероятная точка для СТ

//Если раскомментировать эти строки, то исключатся точки имеющие продолжение

//CPoint dotForAccept = FindAcceptDot(wdot, alpha, iter->type);

//if (dotForAccept.x == -1)

{   //точка не имеет продолжения, запомним ее//

_tmpDotFing.alpha = ChangeAlphaInterval(alpha);

_tmpDotFing.coord = wdot;

_tmpDotFing.show = true;

_tmpDotFing.type = historyDotL.begin()->type;

retFing.push_back(_tmpDotFing);

}

historyDotL.clear();

stopKol += (kol*1.5 > stopKol)?1000:0;

}

}

}

if (dot.x == _dot->coord.x && dot.y == _dot->coord.y)

{//вероятно обход линии завершен

if (kol <= 2)

{//Линия подозрительно короткая

CString s;

s.Format("%d", kol);

if(MESSAGEOUT)MessageBox(0, "kol<=2 kol = " + s, "", MB_OK);

return retFing;

}else

{

homeOver = true; //пройти необходимо дальше начала    

stopKol = kol + KOL_L*LEN_L*LEN_S;

}

}

if (homeOver) ret++;

}while(ret < (LEN_L*LEN_S*KOL_L) && ret < stopKol && kol <= stopKol);

_dot->pr1 = false;

_dot->pr2 = false;

return retFing;

}

list<TMapElDot> TAnalysePicture::LookPic()

//Попиксельное "пробегание" по картинке и

//запоминание черных точек, после нахождения черной точки

//заливка всей линии в цвет фона (удаление линии с картинки)

{

list<TMapElDot> map;

TMapElDot dot;

tmpPic->Copy(*pic);

 

for(int j = 0; j < pic->GetSize().y; j++)

for(int i = 0; i < pic->GetSize().x; i++)

{

if(!tmpPic->GetPixel(i,j))   //найден черный пиксель

{

dot.coord.x = i; dot.coord.y = j;

dot.pr1 = dot.pr2 = true;

map.push_back(dot);

tmpPic->FloodFill(i, j, 0xffffff);  //удаление линии

}

}       

tmpPic->Copy(*pic);

return map;

}

int TAnalysePicture::ChangeLine(list<TMapElDot>::iterator _dot, list<TMapElDot> &_map)

//Обработка картинки, ее изменение

//Обработка линии на которую указывает imap

//Исправление псевдо-раздвоений и псевдо-окончаний на указанной линии

{

int changeN = 0; //количество модификаций на линии

int kol = 0; //количество пройденных точек

int vec = 0; //направление поиска очередной точки

int tekS = 0;    //Текущее количество коротких векторов

CPoint   A, //Начало вектора

B; //Конец вектора

TAbsFing vecDotS; //массив точек для коротких векторов

TAbsFing vecDotL; //массив точек для длинных векторов

TAbsFing historyDotL; //история точек для длинных векторов

TAbsDot _tmpDotFing;

TAbsFing::iterator iter;

TAbsDot resetDot, bestDot;

double alpha;  //направление вектора (в радианах)

int stopKol = 1500; //предел шагов

int ret = 0; //счетчик шагов после прохождения начальной точки

bool homeOver = false;     //признак окончания обработки

_dot->pr1 = false;

A = _dot->coord; B = _dot->coord;

CPoint olddot, dot = _dot->coord;       //Текущая точка на линии

do{

//основной цикл обработки,

//варианты завершения цикла

//продолжается до тех пор пока вся линия не будет пройдена (нормальный вариант)

//зацикливание (не нормальный вариант, их несколько)

//

olddot = dot;

dot = pic->NextDotCW(dot, vec);        //Поиск следующей точки _по часовой_ стрелке

if(dot.x == olddot.x && dot.y == olddot.y)

{//положение точки не изменилось => выход//

CString s;

s.Format("x = %d, y = %d, kol= %d", dot.x, dot.y, kol);

if(MESSAGEOUT)MessageBox(0, "положение точки не изменилось => выход\n" + s, "", MB_OK);

return changeN;

}

kol++;   //подсчет пройденных точек

if(kol % LEN_S == 0)

{//появился новый короткий вектор

tekS++;

A = B;

B = dot;

//pic2->Line(A,B, 1, 0x999999);

_tmpDotFing.coord = A;

alpha = GetAlpha(A, B);            //расчет локального направления между KOL_S пикселями (направление короткого вектора)//

double dAlpha = 0.0;        //Разница углов

if(vecDotS.size() > 0)         //в списке можно взять предыдущее значение

dAlpha = alpha - vecDotS.begin()->alpha;

/**/ if (abs(dAlpha) >= M_PI)  //разница между новым углом и предыдущим не нормальная!

{//необходимо скорректировать текущую alpha

/**/ if (dAlpha < 0.0)

{

while (abs(dAlpha) > M_PI)

{

alpha += 2.0 * M_PI;

dAlpha += 2.0 * M_PI;

}

}else

{       

while (dAlpha >= M_PI)

{

alpha -= 2.0 * M_PI;

dAlpha -= 2.0 * M_PI;

}       

}

}

_tmpDotFing.alpha = alpha;      //запоминание направления из точки А//

vecDotS.push_front(_tmpDotFing);

///////////////////////////////////////////////////////////////////////

///////проверяем два соседних длинных вектора при условии что//////////

///////пройдено достаточно точек, чтоб сравнивать длнинные вектора/////

if(vecDotS.size() < KOL_S) continue;

//Вычисление среднего направления LEN_L коротких векторов//

//запись данных по длинному вектору////////////////////////

double sumAlpha = 0.0;

iter = vecDotS.begin();

vecDotL.clear(); //пересчитаем длинные вектора

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

{

sumAlpha += iter->alpha;

if ((i+1) % LEN_L == 0)

{

_tmpDotFing = *iter;

_tmpDotFing.alpha = sumAlpha / LEN_L;

vecDotL.push_back(_tmpDotFing);

sumAlpha = 0.0;

}

iter++;

}

if (abs(vecDotL.begin()->alpha) > 3*2*M_PI)

{//слишком много оборотов//

CString s;

s.Format("alpha = %.2f", vecDotL.begin()->alpha*180);

if(MESSAGEOUT)MessageBox(0, "слишком много оборотов\n"+s, "", MB_OK);

return changeN;

}

//проверяем два соседних длинных вектора//

dAlpha = vecDotL.begin()->alpha - (++vecDotL.begin())->alpha;

if (abs(dAlpha) > (TEST_ALPHA / 180.0 * M_PI)) //сильный изгиб//

{

if (historyDotL.empty())

{ //сохранение состояния//

resetDot = vecDotL.back();

bestDot.alpha = 0.0;

}

if (dAlpha > 0)         //раздвоение

alpha = (vecDotL.front().alpha - M_PI + (vecDotL.back().alpha)) / 2.0;

else //окончание

alpha = (vecDotL.front().alpha + M_PI + (vecDotL.back().alpha)) / 2.0;

_tmpDotFing = vecDotL.front();

_tmpDotFing.alpha = alpha; //направление в СТ (специфичная точка)//

_tmpDotFing.type = dAlpha<0;          //тип СТ//

historyDotL.push_front(_tmpDotFing);

if(bestDot.alpha <= abs(dAlpha))

{       

bestDot.coord = _tmpDotFing.coord;

bestDot.alpha = abs(dAlpha);

}

}

else //сильный изгиб//

{

if (!historyDotL.empty())  //был _пройден_ сильный изгиб

{

alpha = 0.0;

for(iter = historyDotL.begin(); iter != historyDotL.end(); iter++)

alpha += iter->alpha;

alpha /= historyDotL.size();        //среднее значение в пройденной СТ

iter = historyDotL.begin();

for(unsigned int i = 0; i<(historyDotL.size()/2); i++) iter++;

CPoint wdot = bestDot.coord;             //наиболее вероятная точка для СТ

CPoint dotForAccept = FindAcceptDot(wdot, alpha, iter->type);

if (dotForAccept.x != -1)

{   //точка имеет продолжение//

COLORREF cl;

cl = (historyDotL.begin()->type)?0x000000:0xffffff;

//здесь можно поиграть с разной толщиной линии//

pic->Line(wdot, dotForAccept, 4, cl);

_dot->pr1 = true; //эту линию необходио еще раз проанализировать

changeN++;

stopKol += (stopKol-kol < 200)?200:0;

//stopKol += (kol*1.5 > stopKol)?500:0;

//загрузить начальное состояние

if(!historyDotL.begin()->type)

{   //если ликвидировано слипание то необходимо добавить новую точку на карту

_map.push_back(TMapElDot(dot));

}

//пройдена начальная точка, продлим анализ

//очень возможно, что начальную точку мы больше не попадем

if(ret-KOL_S*LEN_S < 0)

{

ret = 0;

homeOver = false;

stopKol = 500;

}

A = B = dot = resetDot.coord;

vecDotS.clear();           

vecDotL.clear();           

//------------------------------

}

historyDotL.clear();

}

}

}

if (dot.x == _dot->coord.x && dot.y == _dot->coord.y)

{//вероятно обход линии завершен

if (kol <= 2)

{//Линия подозрительно короткая

CString s;

s.Format("%d", kol);

if(MESSAGEOUT)MessageBox(0, "kol<=2 kol = " + s, "", MB_OK);

return changeN;

}else

{

homeOver = true; //пройти необходимо дальше начала    

stopKol = kol + KOL_L*LEN_L*LEN_S;

}

}

if (homeOver) ret++;

}while(ret < (LEN_L*LEN_S*KOL_L) && ret < stopKol && kol <= stopKol);

_dot->pr2 = false;

return changeN;

}

inline double TAnalysePicture::GetAlpha(const CPoint A, const CPoint B)

//Направлени из точки А в В [-pi,pi)

{

if(A == B) return 0.0;

double alpha;

if (A.x - B.x == 0)

{

if (A.y > B.y) alpha = M_PI_2;

else alpha = -M_PI_2;

}else

{

double a = ((double)A.y-B.y)/((double)B.x-A.x);

alpha = atan(a);

if (A.x > B.x)

{

if (alpha < 0) alpha += M_PI;

else alpha -= M_PI;

if (A.y == B.y) alpha = -M_PI;

}

}

return alpha;

}

bool TAnalysePicture::TestFindDot(int _x, int _y)

//тест точки: Разность направлений вперед и назад должно быть меньше 110 градусов

{

const int len = 7;

CPoint A(_x, _y), B, C;

//первый вектор

B = A;

int vec = 0;

for(int i = 1; i<=len; i++)

B = tmpPic->NextDotCW(B, vec);

//------расчет угла-------//

double alpha1 = GetAlpha(A, B);

//второй вектор

C = B;

B = A;

vec = 0;

for(int i = 1; i<=len; i++)

{

B = tmpPic->NextDotCCW(B, vec);

if(abs(B.x-C.x) < 3 && abs(B.y-C.y) < 3) return true;

}

//------расчет угла-------//

double alpha2 = GetAlpha(A, B);

//-----alpha1, alpha2------//

alpha1 = abs(alpha2 - alpha1);

if (alpha1 > M_PI) alpha1 = 2.0*M_PI - alpha1;

return alpha1 < (110.0/180.0 * M_PI);

}

CPoint TAnalysePicture::FindAcceptDot(CPoint dot, double alpha, bool type)

//Поиск продолжения из окончания/раздвоения

{

const int maxL = 11;

const int minL = 3;

COLORREF color;

color = (type)?0x000000:0xffffff;

//окончание - ищем черную точку

//раздвоение - ищем белую точку

int i = 0;

while (i<=6)    //разброс поиска в указанном направлении alpha

{

int l = minL;

int k = (i+1) / 2;

if (i % 2 == 1) k = -k;

while (l<=maxL)

{

double arg = alpha + k * M_PI * 5.0/180.0;

int x = dot.x + (int)(l*cos(arg)+0.5);

int y = dot.y - (int)(l*sin(arg)+0.5);

if (tmpPic->GetPixel(x, y) == color)    //важное условие цвета точки!!!

{

if(TestFindDot(x,y)) //проверка найденной точки (на "вшивость" :) )

return CPoint(x, y);           //найденная точка

else

break;

}

l++; //увеличение дальности поиска

}

i++;

}

return CPoint(-1, -1); //точка не найдена

}

bool TAnalysePicture::Show(int x, int y, int xt, int yt)

{

if(xt!=-1) pic2->Show(xt, yt);

return pic->Show(x, y);

}

TFingPicture *TAnalysePicture::GetPic1()

{

return pic;

}

TFingPicture *TAnalysePicture::GetPic2()

{

return pic2;

}

double TAnalysePicture::ChangeAlphaInterval(double _alpha)

//Приведение итрервала к [-pi,pi)

{

double ret = abs(_alpha);

while(ret >= 2.0*M_PI) ret -= 2.0*M_PI;

if(ret > M_PI) ret = 2.0*M_PI - ret;

else ret = -ret;

if(_alpha > 0) ret = -ret;

return ret;

}

/*Фильтрование полученных точек

отсеиваются близкостоящие направленные в противоположные строки

а так же точки слева и справа от которых нет линий*/

int TAnalysePicture::DotsFilter(TAbsFing &_dots)

{

int leftDots = 0;

TAbsFing::iterator iter1;

TAbsFing::iterator iter2;

for(iter1 = _dots.begin(); iter1 != _dots.end(); iter1++)

{

if(!iter1->show) continue;

//отсев точек сложным условием (условие окружения)

iter1->show = LeftDot(iter1);

}

for(iter1 = _dots.begin(); iter1 != _dots.end(); iter1++)

{

if(!iter1->show) continue;

//отсев близкостоящих точек

for(iter2 = iter1, ++iter2; iter2 != _dots.end(); iter2++)

{

if(!iter2->show) continue;

double difL = GetS(iter1->coord,iter2->coord);

if( //условия отсева

(

//на близком растоянии (15) находятся два окончания/раздвоения направленных друг на друга

(difL < 15)&&

((abs(iter2->alpha - iter1->alpha) > (165.0/180.0*M_PI))&&(abs(iter2->alpha - iter1->alpha)<(195.0/180.0*M_PI)))

)

||

(       

//или просто очень близкие точки (<5..10)

(difL < 10)&&(iter1->type == iter2->type)

)

)

{

iter1->show = false;

iter2->show = false;

}

}

}

return leftDots;

}

inline double TAnalysePicture::GetS(CPoint A, CPoint B)

//растояние между точками

{

return sqrt( (double)((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)) );

}

/*Если точка является окончанием, то слева и справа от нее должны быть линии если это не так, то точку нужно исключить из дальнейшего анализа*/

bool TAnalysePicture::LeftDot(TAbsFing::iterator &iter)

{

COLORREF color = 0x000000; //ищем черную точку для окончаний

if(!iter->type) color = 0xffffff;;    //ищем белую точку для раздвоений

int l, k = 35;

const int minL = 4, maxL = 12;

bool find = false;

while(k <= 55)

{

l = minL;

while(l <= maxL)

{

    int x = iter->coord.x + (int)(l*cos(iter->alpha + k/180.0*M_PI)+0.5);

int y = iter->coord.y - (int)(l*sin(iter->alpha + k/180.0*M_PI)+0.5);

if(pic->GetPixel(x,y) == color)   // важное условие!!!

{   find = true; break;}            //нашли точку слева

l++;

}

if(find) break;

k += 10; //Поиск с шагом 10гр

}

if(!find) return false;

k = 35;

while(k <= 55)

{

l= minL;

while(l <= maxL)

{

int x = iter->coord.x + (int)(l*cos(iter->alpha - k/180.0*M_PI)+0.5);

int y = iter->coord.y - (int)(l*sin(iter->alpha - k/180.0*M_PI)+0.5);

if(pic->GetPixel(x,y) == color) // важное условие!!!

return true; //нашли точку справа

l++;

}

k += 10;

}

return false;

}




2020-02-03 174 Обсуждений (0)
П .1.9 ТЕКСТ МОДУЛЯ TAnalysePicture.cpp 0.00 из 5.00 0 оценок









Обсуждение в статье: П .1.9 ТЕКСТ МОДУЛЯ TAnalysePicture.cpp

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Модели организации как закрытой, открытой, частично открытой системы: Закрытая система имеет жесткие фиксированные границы, ее действия относительно независимы...
Почему люди поддаются рекламе?: Только не надо искать ответы в качестве или количестве рекламы...
Почему двоичная система счисления так распространена?: Каждая цифра должна быть как-то представлена на физическом носителе...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (174)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.009 сек.)