: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actExitExecute(TObject *Sender)
{
frmLineSeg->Close();
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::FormCreate(TObject *Sender)
{
scb1->Enabled=false;
logs=true;
zoom=1.0f; dzoom=1.0f;
maxzoom=100.0f;
selline=-1;
Image1->Left=0; Image1->Top=0;
Image2->Left=0; Image2->Top=0;
w=0; h=0;
c0=TColor(RGB(0,0,0)); c1=TColor(RGB(255,255,255));
c2=TColor(RGB(0,255,0)); c3=TColor(RGB(0,0,255));
c4=TColor(RGB(255,0,0)); c21=TColor(RGB(255,255,0));
c5=TColor(RGB(200,200,200));
for(int i=0;i<=maxw-1;i++)
for(int j=0;j<=maxh-1;j++)
{
apix[i][j][0]=0;
apix[i][j][1]=apix[i][j][2]=apix[i][j][3]=-1;
}
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::FormCloseQuery(TObject *Sender, bool &CanClose)
{
CanClose=MessageBox(Handle,"Выход ?", "ЛС", MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2)==ID_YES;
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actZoomInExecute(TObject *Sender)
{
zoom+=dzoom;
ZoomTo(zoom);
DrawGrid();
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actZoomOutExecute(TObject *Sender)
{
if(zoom>dzoom) zoom-=dzoom;
ZoomTo(zoom);
DrawGrid();
}
//---------------------------------------------------------------------------
void TfrmLineSeg::DrawGrid()
{
if(Image2->Visible)
{
Image2->Picture->Bitmap->Width=Image1->Width;
Image2->Picture->Bitmap->Height=Image1->Height;
Image2->Width=Image1->Width;
Image2->Height=Image1->Height;
Image2->Canvas->Pen->Color=c5;
Image2->Canvas->FillRect(Image2->ClientRect);
if(actGridCheck->Checked)
{
for(int i=1;i<=Image2->Height;i++)
{
Image2->Canvas->MoveTo(int(zoom*i),0);
Image2->Canvas->LineTo(int(zoom*i),Image2->Height);
}
for(int i=1;i<=Image2->Width;i++)
{
Image2->Canvas->MoveTo(0,int(zoom*i));
Image2->Canvas->LineTo(Image2->Width,int(zoom*i));
}
}
} // Image2->Visible
}
void __fastcall TfrmLineSeg::actOpenFileExecute(TObject *Sender)
{
OpenDialog1->Title="Открыть изображение";
OpenDialog1->Filter="Файлы изображений (*.bmp)|*.bmp|Все файлы (*.*)|*.*";
if(OpenDialog1->Execute())
{
sb1->SimplePanel=true; sb1->SimpleText="Открытие файла ...";
Image1->Picture->LoadFromFile(OpenDialog1->FileName);
Image1->Width=Image1->Picture->Bitmap->Width;
Image1->Height=Image1->Picture->Bitmap->Height;
w=Image1->Picture->Width;
h=Image1->Picture->Height;
scb1->Enabled=true;
ZoomTo(zoom);
for(int i=0;i<=w-1;i++) // maxw-1
for(int j=0;j<=h-1;j++) // maxh-1
{
apix[i][j][0]=Image1->Canvas->Pixels[i][j]==c0?1:0;
apix[i][j][1]=apix[i][j][2]=apix[i][j][3]=-1;
}
sb1->SimpleText=""; sb1->SimplePanel=false;
}
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actSaveFileExecute(TObject *Sender)
{
SaveDialog1->Filter="Файлы изображений (*.bmp)|*.bmp|Все файлы (*.*)|*.*";
SaveDialog1->DefaultExt="*.bmp";
SaveDialog1->Title="Сохранить изображение";
if(SaveDialog1->Execute())
{
Image1->Picture->SaveToFile(SaveDialog1->FileName);
}
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::Image2MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (actLockView->Checked) return;
int ix=int(X/zoom),iy=int(Y/zoom);
if(Button==mbLeft)
{
if(Image1->Canvas->Pixels[ix][iy]!=c0)
{
Image1->Canvas->MoveTo(ix,iy);
Image1->Canvas->Pixels[ix][iy]=c0;
apix[ix][iy][0]=1;
}
}
else if(Button==mbRight)
{
if(Image1->Canvas->Pixels[ix][iy]!=c1)
{
Image1->Canvas->MoveTo(ix,iy);
Image1->Canvas->Pixels[ix][iy]=c1;
apix[ix][iy][0]=0;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::Image2MouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
ShowInfo(X,Y);
if (actLockView->Checked) return;
int ix=int(X/zoom),iy=int(Y/zoom);
oldselline=selline;
oldselnode=selnode;
selline=apix[ix][iy][1];
selnode=apix[ix][iy][2];
TPoint p=NodeCentre(selnode);
if(Shift.Contains(ssLeft))
{
if(apix[ix][iy][0]!=1)
{
apix[ix][iy][0]=1;
Image1->Canvas->Pen->Color=c0;
Image1->Canvas->Pixels[ix][iy]=c0;
}
else
Image1->Canvas->MoveTo(ix,iy);
}
else if(Shift.Contains(ssRight))
{
if(apix[ix][iy][0]!=0)
{
apix[ix][iy][0]=0;
Image1->Canvas->Pen->Color=c1;
Image1->Canvas->Pixels[ix][iy]=c1;
}
else
Image1->Canvas->MoveTo(ix,iy);
}
if(actLineLightCheck->Checked && selline!=oldselline)
{
if(apix[ix][iy][1]>0) // есть линия
{
DrawGrid();
Image2->Canvas->Pen->Color=c2;
for(int i=0;i<w;i++) // выделяем линию
{
for(int j=0;j<h;j++)
{
if(apix[i][j][1]==selline) // линия
{
Image2->Canvas->MoveTo(int(zoom*i),int(zoom*j));
Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*j));
Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*(j+1)));
Image2->Canvas->LineTo(int(zoom*i),int(zoom*(j+1)));
Image2->Canvas->LineTo(int(zoom*i),int(zoom*j));
if(NeigCount(i,j)==1) // начало линии
{
Image2->Canvas->MoveTo(int(zoom*i),int(zoom*j));
Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*(j+1)));
Image2->Canvas->MoveTo(int(zoom*(i+1)),int(zoom*j));
Image2->Canvas->LineTo(int(zoom*i),int(zoom*(j+1)));
}
if(apix[i][j][2]>0) // пересечение линии с узлом
{
Image2->Canvas->MoveTo(int(zoom*i),int(zoom*j));
Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*(j+1)));
p=NodeCentre(apix[i][j][2]);
Image2->Canvas->Pen->Color=c4;
Image2->Canvas->MoveTo(int(zoom*p.x),int(zoom*p.y));
Image2->Canvas->LineTo(int(zoom*(p.x+1)),int(zoom*p.y));
Image2->Canvas->LineTo(int(zoom*(p.x+1)),int(zoom*(p.y+1)));
Image2->Canvas->LineTo(int(zoom*p.x),int(zoom*(p.y+1)));
Image2->Canvas->LineTo(int(zoom*p.x),int(zoom*p.y));
Image2->Canvas->Pen->Color=c2;
}
}
} // for j
} // for i
}
} // actLineLightCheck->Checked
if(actSegLightCheck->Checked && selnode!=oldselnode)
{
if(apix[ix][iy][2]>0) // есть узел
{
DrawGrid();
Image2->Canvas->Pen->Color=c3;
for(int i=0;i<w;i++) // выделяем узел
{
for(int j=0;j<h;j++)
{
if(apix[i][j][2]==selnode) // узел
{
Image2->Canvas->MoveTo(int(zoom*i),int(zoom*j));
Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*j));
Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*(j+1)));
Image2->Canvas->LineTo(int(zoom*i),int(zoom*(j+1)));
Image2->Canvas->LineTo(int(zoom*i),int(zoom*j));
if(apix[i][j][1]>0) // пересечение узла с линией
{
Image2->Canvas->MoveTo(int(zoom*i),int(zoom*j));
Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*(j+1)));
}
}
} // for j
} // for i
//
Image2->Canvas->Pen->Color=c4;
Image2->Canvas->MoveTo(int(zoom*p.x),int(zoom*p.y));
Image2->Canvas->LineTo(int(zoom*(p.x+1)),int(zoom*p.y));
Image2->Canvas->LineTo(int(zoom*(p.x+1)),int(zoom*(p.y+1)));
Image2->Canvas->LineTo(int(zoom*p.x),int(zoom*(p.y+1)));
Image2->Canvas->LineTo(int(zoom*p.x),int(zoom*p.y));
}
} // actSegLightCheck->Checked
}
//---------------------------------------------------------------------------
void TfrmLineSeg::ShowInfo(int X,int Y)
{
unsigned char r,g,b;
int ix=int(X/zoom),iy=int(Y/zoom);
if (X>=0 && Y>=0)
{
sb1->Panels->Items[1]->Text=IntToStr(ix);
sb1->Panels->Items[3]->Text=IntToStr(h-1-iy);
r=Image1->Canvas->Pixels[ix][iy];
g=Image1->Canvas->Pixels[ix][iy] >>8;
b=Image1->Canvas->Pixels[ix][iy] >>16;
sb1->Panels->Items[5]->Text=IntToStr(r);
sb1->Panels->Items[7]->Text=IntToStr(g);
sb1->Panels->Items[9]->Text=IntToStr(b);
}
sb1->Panels->Items[11]->Text=IntToStr(int(zoom));
// if(apix[ix][iy][0]!=-1)
{
sb1->Panels->Items[13]->Text=IntToStr(apix[ix][iy][0]);
sb1->Panels->Items[15]->Text=IntToStr(apix[ix][iy][1]);
}
sb1->Panels->Items[17]->Text=IntToStr(apix[ix][iy][2]);
sb1->Panels->Items[19]->Text=IntToStr(apix[ix][iy][3]);
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actZoom1Execute(TObject *Sender)
{
zoom=1.0f;
Image1->Width=Image1->Picture->Width;
Image1->Height=Image1->Picture->Height;
DrawGrid();
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actAnalyzeExecute(TObject *Sender)
{
MemoLog->Clear();
actAnalyzeNodeExecute(Sender);
actAnalyzeSegExecute(Sender);
}
//---------------------------------------------------------------------------
int __fastcall TfrmLineSeg::NeigCount(int x, int y)
{
int n=0;
if(Image1->Canvas->Pixels[x-1][y-1]==c0 && x>0 && y>0) n+=1; // lu=1
if(Image1->Canvas->Pixels[x ][y-1]==c0 && y>0) n+=1; // u=2
if(Image1->Canvas->Pixels[x+1][y-1]==c0 && x<w && y>0) n+=1; // ru=3
if(Image1->Canvas->Pixels[x-1][y ]==c0 && x>0 ) n+=1; // l=4
if(Image1->Canvas->Pixels[x+1][y ]==c0 && x<w ) n+=1; // r=5
if(Image1->Canvas->Pixels[x-1][y+1]==c0 && x>0 && y<h) n+=1; // ld=6
if(Image1->Canvas->Pixels[x ][y+1]==c0 && y<h) n+=1; // d=7
if(Image1->Canvas->Pixels[x+1][y+1]==c0 && x<w && y<h) n+=1; // rd=8
return (n);
}
//---------------------------------------------------------------------------
int TfrmLineSeg::VectMove(int &x, int &y, int vect)
{
int res=0;
if(vect>0) wlog("VectMove: new point");
else if(vect<0 && vect>-10) wlog("VectMove: new node");
else if(vect<-10 && vect>-20) wlog("VectMove: existing node");
else wlog("VectMove: ERROR POINT");
int amvect=abs(vect) % 10;
switch(amvect)
{
// точка принадлежит линии
case 1: x-=1; y-=1; res=1; break;
case 2: y-=1; res=1; break;
case 3: x+=1; y-=1; res=1; break;
case 4: x-=1; res=1; break;
case 5: x+=1; res=1; break;
case 6: x-=1; y+=1; res=1; break;
case 7: y+=1; res=1; break;
case 8: x+=1; y+=1; res=1; break;
}
return res;
}
void __fastcall TfrmLineSeg::FormCanResize(TObject *Sender, int &NewWidth,
int &NewHeight, bool &Resize)
{
if(NewHeight<300) Resize=false;
}
//---------------------------------------------------------------------------
void TfrmLineSeg::ZoomTo(double z)
{
if(z<0.1) zoom=0.1f;
else if(z>maxzoom) zoom=maxzoom;
else zoom=z;
Image1->Width=int(Image1->Picture->Width*zoom);
Image1->Height=int(Image1->Picture->Height*zoom);
DrawGrid();
ShowInfo(-1,-1);
}
//---------------------------------------------------------------------------
AnsiString TfrmLineSeg::VectToStr(int v)
{
switch(v)
{
case 1:return ("LU");
case 2:return ("U");
case 3:return ("RU");
case 4:return ("L");
case 5:return ("R");
case 6:return ("LD");
case 7:return ("D");
case 8:return ("RD");
case -1:return ("LUn");
case -2:return ("Un");
case -3:return ("RUn");
case -4:return ("Ln");
case -5:return ("Rn");
case -6:return ("LDn");
case -7:return ("Dn");
case -8:return ("RDn");
default:return("");
}
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actNewFileExecute(TObject *Sender)
{
if(frmImgSize->ShowModal()==mrOk)
{
try
{
w=StrToInt(frmImgSize->edtWidth->Text);
h=StrToInt(frmImgSize->edtHeight->Text);
Image1->Picture->Bitmap->Width=w;
Image1->Picture->Bitmap->Height=h;
Image1->Width=w;
Image1->Height=h;
Image1->Canvas->FillRect(Image1->ClientRect);
zoom=1.0f;
scb1->Enabled=true;
for(int i=0;i<=w-1;i++) // maxw-1
for(int j=0;j<=h-1;j++) // maxh-1
{
apix[i][j][0]=Image1->Canvas->Pixels[i][j]==c0?1:0;
apix[i][j][1]=apix[i][j][2]=-1;
}
}
catch (...)
{
MessageBox(Handle,"Неверно указано число", "Ошибка", MB_OK);
}
DrawGrid();
ShowInfo(-1,-1);
}
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actGridCheckExecute(TObject *Sender)
{
ValidateView();
DrawGrid();
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actLightCheckExecute(TObject *Sender)
{
ValidateView();
DrawGrid();
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actZoom10Execute(TObject *Sender)
{
ZoomTo(10.0f);
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actLineLightCheckExecute(TObject *Sender)
{
ValidateView();
DrawGrid();
}
//---------------------------------------------------------------------------
void TfrmLineSeg::wlog(AnsiString s)
{
if(logs)
if(s!="")
MemoLog->Lines->Add(s);
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actSegLightCheckExecute(TObject *Sender)
{
ValidateView();
DrawGrid();
}
//---------------------------------------------------------------------------
void TfrmLineSeg::ValidateView()
{
Image2->Visible=actGridCheck->Checked
|| actLightCheck->Checked
|| actLineLightCheck->Checked
|| actSegLightCheck->Checked;
}
double TfrmLineSeg::plDistance(double x,double y,double x1,double y1,double x2,double y2)
{
double R=0.0f;
try
{
R=((y1-y2)*x+(x2-x1)*y+(x1*y2-x2*y1))/sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
catch(...)
{ }
return fabs(R);
}
//---------------------------------------------------------------------------
void __fastcall TfrmLineSeg::actLockViewExecute(TObject *Sender)
{
ValidateView();
}
//---------------------------------------------------------------------------
AnsiString TfrmLineSeg::StrToLen(AnsiString str, int len)
{
AnsiString s=str;
while(s.Length()<len) s=" "+s;
return s;
}