Procedure Schet;
Var i,j,k:integer;
    dx:RealVector;
    Centre:RealVector;
begin
   With frmMain do begin
     MinX[1]:=StrToFloat(Edit1.Text);
     MaxX[1]:=StrToFloat(Edit2.Text);
     MinX[2]:=StrToFloat(Edit3.Text);
     MaxX[2]:=StrToFloat(Edit4.Text);
     Angle[1]:=StrToFloat(Edit7.Text)*2*Pi/360;
     Angle[2]:=StrToFloat(Edit8.Text)*2*Pi/360;
     Angle[3]:=StrToFloat(Edit9.Text)*2*Pi/360;
   end;

   For i:=1 to 2 do dx[i]:=(MaxX[i]-MinX[i])/nGrid;

   MinX[3]:=1e38;MaxX[3]:=-1e38;
   For i:=0 to nGrid do
      For j:=0 to nGrid do begin
          x[i,j,1]:=MinX[1]+dx[1]*i;
          x[i,j,2]:=MinX[2]+dx[2]*j;
          x[i,j,3]:=F(x[i,j,1],x[i,j,2]);
          If MinX[3]>x[i,j,3] then MinX[3]:=x[i,j,3];
          If MaxX[3]<x[i,j,3] then MaxX[3]:=x[i,j,3];
      end;

   For i:=1 to 3 do begin
      Centre[i]:=(MinX[i]+MaxX[i])/2;
      dx[i]:=Centre[i]-MinX[i];
   end;

   For i:=0 to nGrid do
      For j:=0 to nGrid do
          For k:=1 to 3 do
             x[i,j,k]:=(x[i,j,k]-Centre[k])/dx[k]//(MaxX[k]-MinX[k]);
end;

Procedure Rotate;
Var xx,yy:real;
    i,j,k:integer;
begin
   For i:=1 to 3 do begin
      Min[i]:=1e38;
      Max[i]:=-1e38
   end;
   x1:=x;
   For i:=0 to nGrid do
      For j:=0 to nGrid do begin
          xx:=x[i,j,2];yy:=x[i,j,3];
            x[i,j,2]:= xx*Cos(Angle[1])+yy*Sin(Angle[1]);
            x[i,j,3]:=-xx*Sin(Angle[1])+yy*Cos(Angle[1]);
          xx:=x[i,j,1];yy:=x[i,j,3];
            x[i,j,1]:= xx*Cos(Angle[2])+yy*Sin(Angle[2]);
            x[i,j,3]:=-xx*Sin(Angle[2])+yy*Cos(Angle[2]);
          xx:=x[i,j,1];yy:=x[i,j,2];
            x[i,j,1]:= xx*Cos(Angle[3])+yy*Sin(Angle[3]);
            x[i,j,2]:=-xx*Sin(Angle[3])+yy*Cos(Angle[3]);
          If Min[1]>x[i,j,1] then Min[1]:=x[i,j,1];
          If Min[2]>x[i,j,2] then Min[2]:=x[i,j,2];
          If Min[3]>x[i,j,3] then Min[3]:=x[i,j,3];
          If Max[1]<x[i,j,1] then Max[1]:=x[i,j,1];
          If Max[2]<x[i,j,2] then Max[2]:=x[i,j,2];
          If Max[3]<x[i,j,3] then Max[3]:=x[i,j,3];
      end; 
end;

Procedure BuildSurface;
Var i,j:integer;
    hx,hy:integer;
    g:array[1..4] of tPoint;

    Procedure Convert(x:RealVector;Var g:tPoint);
    begin
       g.x:=Round(10+(hx-20)*(x[1]-Min[1])/(Max[1]-Min[1]));
       g.y:=Round(10+(hy-20)*(Max[3]-x[3])/(Max[3]-Min[3]));
    end;

begin
    With frmMain.Image1 do begin
       hx:=frmMain.Image1.Width;
       hy:=frmMain.Image1.Height;
       With Canvas do begin
          Brush.Style:=bsSolid;
          Brush.Color:=clWhite;
          Rectangle(0,0,hx,hy);
          Pen.Color:=clBlack;

          For i:=0 to nGrid-1 do
             For j:=0 to nGrid-1 do begin
                Convert(x[i,j],g[1]);
                Convert(x[i+1,j],g[2]);
                Convert(x[i+1,j+1],g[3]);
                Convert(x[i,j+1],g[4]);
                Brush.Color:=clBlue;//clWhite;
                Pen.Color:=clWhite;
                Polygon(g)
             end;
       end
    end
end;

Procedure BuildGrid;
Var i,j:integer;
    hx,hy:integer;
    g:tPoint;

    Procedure Convert(x:RealVector;Var g:tPoint);
    begin
       g.x:=Round(10+(hx-20)*(x[1]-Min[1])/(Max[1]-Min[1]));
       g.y:=Round(10+(hy-20)*(Max[3]-x[3])/(Max[3]-Min[3]));
    end;
begin
    With frmMain.Image1 do begin
       hx:=Width;
       hy:=Height;
       With Canvas do begin
          Brush.Style:=bsSolid;
          Brush.Color:=clWhite;
          Rectangle(0,0,hx,hy);
          Pen.Color:=clBlack;
          For i:=0 to nGrid do begin
             Convert(x[i,0],g);
             MoveTo(g.x,g.y);
             For j:=1 to nGrid do begin
               Convert(x[i,j],g);
               LineTo(g.x,g.y)
             end;
          end;
          For j:=0 to nGrid do begin
             Convert(x[0,j],g);
             MoveTo(g.x,g.y);
             For i:=1 to nGrid do begin
               Convert(x[i,j],g);
               LineTo(g.x,g.y)
             end;
          end;
       end;
    end
end;

Procedure BuildLine;
Const nGrid=200;
      kLevel=10;
Var i,j,k:integer;
    Level:array[1..kLevel] of real;
    hx,hy:integer;
    x,y,z:array[0..nGrid,0..nGrid] of real;
    MinX,MaxX,MinY,MaxY,MinZ,MaxZ:real;
    dx,dy,dz,a,b,c,d:real;
    //ur:array[1..5] of real;
    xr,yr:array[1..2] of real;
    xg,yg:array[1..2] of integer;
    //p,p1,p2,p3,p4:boolean;
    kPoint,kr,s:integer;

    Procedure Convert(x1,x2:Real;Var xg,yg:integer);
    begin
       xg:=Round(10+(hx-20)*(x1-MinX)/(MaxX-MinX));
       yg:=Round(10+(hy-20)*(MaxY-x2)/(MaxY-MinY));
    end;
begin
    MinX:=StrToFloat(frmMain.Edit1.Text);
    MaxX:=StrToFloat(frmMain.Edit2.Text);
    MinY:=StrToFloat(frmMain.Edit3.Text);
    MaxY:=StrToFloat(frmMain.Edit4.Text);
    MinZ:=1e38;MaxZ:=-1e38;
    dx:=(MaxX-MinX)/nGrid;
    dy:=(MaxY-MinY)/nGrid;
    For i:=0 to nGrid do
      For j:=0 to nGrid do begin
          x[i,j]:=MinX+j*dx;
          y[i,j]:=MinY+i*dy;
          z[i,j]:=F(x[i,j],y[i,j]);
          If z[i,j]>MaxZ then MaxZ:=z[i,j];
          If z[i,j]<MinZ then MinZ:=z[i,j];
      end;
    dz:=(MaxZ-MinZ)/(kLevel+1);
    For i:=1 to kLevel do Level[i]:=MinZ+i*dz;
    With frmMain.Image1 do begin
       hx:=frmMain.Image1.Width;
       hy:=frmMain.Image1.Height;
       With Canvas do begin
          Brush.Style:=bsSolid;
          Brush.Color:=clWhite;
          Rectangle(0,0,hx,hy);
          Pen.Color:=clBlack;

          For k:=1 to kLevel do begin
             //s:=Round(255*(Level[k]-MinZ)/(MaxZ-MinZ));
             Pen.Color:=clBlack;//RGB(s,0,255-s);
             For i:=0 to nGrid-1 do
                For j:=0 to nGrid-1 do begin
                   a:=Level[k]-z[i,j];
                   b:=Level[k]-z[i+1,j];
                   c:=Level[k]-z[i+1,j+1];
                   d:=Level[k]-z[i,j+1];
                   kPoint:=0;
                   If a*b<0 then begin
                        kPoint:=kPoint+1;
                        xr[kPoint]:=x[i,j];
                        yr[kPoint]:=y[i,j]+dy*Abs(a/(b-a));
                   end;
                   If b*c<0 then begin
                        kPoint:=kPoint+1;
                        xr[kPoint]:=x[i+1,j]+dx*Abs(b/(c-b));
                        yr[kPoint]:=y[i+1,j];
                   end;
                   If c*d<0 then begin
                        kPoint:=kPoint+1;
                        xr[kPoint]:=x[i+1,j+1];
                        yr[kPoint]:=y[i,j+1]+dy*Abs(c/(d-c));
                   end;
                   If a*d<0 then begin
                        kPoint:=kPoint+1;
                        xr[kPoint]:=x[i,j]+dx*Abs(a/(d-a));
                        yr[kPoint]:=y[i,j];
                   end;

                   If kPoint>0 then begin
                      Convert(xr[1],yr[1],xg[1],yg[1]);
                      Convert(xr[2],yr[2],xg[2],yg[2]);
                      MoveTo(xg[1],yg[1]);
                      LineTo(xg[2],yg[2])
                   end
                end
          end
       end
    end
end;

Procedure Build;
begin
    If frmMain.rbtnGrid.Checked then BuildGrid;
    If frmMain.rbtnSurface.Checked then BuildSurface;
    If frmMain.rbtnLine.Checked then BuildLine;
    x:=x1
end;
