问题描述:
    在Form上有若干个动态创建的Panel,要求从Form上的任意两点Point1和Point2之间用线连接,并且要求连线横平竖直,不得穿过任意一个Panel,连线也尽量不要相交。这有点像Visio等绘图软件中的连线功能,可以自动绕过已有的控件或图形,寻找最佳路径。    谁做过这方面的最优算法?可否给点建议?急!立即给分!!

解决方案 »

  1.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;  //X1   Point1(X1, Y1)
        Edit2: TEdit;  //Y1
        Edit3: TEdit;  //X2   Point2(X2, Y2)
        Edit4: TEdit;  //Y2
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    const
      PanelName = 'MyPanel';
    var
      Form1: TForm1;
      panel_Left: array of integer;
      panel_Top: array of integer;
    implementation{$R *.dfm}//动态创建Panel,假设Panel个数已知
    procedure TForm1.FormCreate(Sender: TObject);
    var
      i: Integer;
    begin
      SetLength(panel_Left, 4);
      SetLength(panel_Top, 4);
      for i := 1 to 4 do
      begin
        TPanel.Create(self).Name := PanelName + IntToStr(i);
        with TPanel(FindComponent(PanelName + IntToStr(i))) do
        begin
          Left := i * 20;
          Top := i * 50;
          Parent := self;
          panel_Left[i - 1] := Left;
          panel_Top[i - 1] := Top;
        end;
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      i: integer;
      s_Point: TStringList;
      X1,X2,Y1,Y2: integer;
    begin
      if (Trim(Edit1.Text) = '') and
         (Trim(Edit2.Text) = '') and
         (Trim(Edit3.Text) = '') and
         (Trim(Edit4.Text) = '') then Exit;
      X1 := StrToInt(Edit1.Text);
      Y1 := StrToInt(Edit2.Text);
      X2 := StrToInt(Edit3.Text);
      Y2 := StrToInt(Edit4.Text);
      if (X1 = X2) and (Y1 = Y2) then
      begin
        ShowMessage('2个点不能重合');
        Exit;
      end;
      //默认Point1在Point2的左边 (反过来同理)
      if X1 > X2 then Exit;
      //判断2个点是否不在Panel的区域内
      for i := 1 to 4 do
      with TPanel(FindComponent(PanelName + IntToStr(i))) do
        begin
          if ((X1 >= Left) and
             (X1 <= (Left + Width)) and
             (Y1 >= Top) and
             (Y1 <= (Top + Height))) or
             ((X2 >= Left) and
             (X2 <= (Left + Width)) and
             (Y2 >= Top) and
             (Y2 <= (Top + Height))) then
          begin
            ShowMessage('输入的点在某个Panel里,不符合要求');
            Exit;
          end;
        end;
      Form1.Canvas.MoveTo(X1, Y1);   //移到point1
      Form1.Canvas.Pen.Width := 4;
      Form1.Canvas.Pen.Color := clRed;
      //先画纵向的线
      //Point2在Point1的右上方
      if Y1 >= Y2 then
      begin
        for i := 1 to 4 do
          with TPanel(FindComponent(PanelName + IntToStr(i))) do
          begin
            if (X1 > Left) and (X1 < Left + Width) and
               (Y1 > (Top + Height)) and (Y2 < Top) then
            begin
              if X1 <= (Left + Width/2) then
              begin
                with Form1.Canvas do
                begin
                  LineTo(X1, Top + Height);
                  LineTo(Left, Top + Height);
                  LineTo(Left, Top);
                  LineTo(X1, Top);
                end;
              end else
              begin
                with Form1.Canvas do
                begin
                  LineTo(X1, Top + Height);
                  LineTo(Left + Width, Top + Height);
                  LineTo(Left + Width, Top);
                  LineTo(X1, Top);
                end;
              end;
            end;
          end;
      end;
      //Point2在Point1的右下方
      if Y1 <= Y2 then
      begin
        for i := 1 to 4 do
         with TPanel(FindComponent(PanelName + IntToStr(i))) do
         begin
          if (X1 > Left) and (X1 < Left + Width) and
             (Y2 > (Top + Height)) and (Y1 < Top) then
          begin
            if X1 <= (Left + Width/2) then
            begin
              with Form1.Canvas do
              begin
                LineTo(X1, Top);
                LineTo(Left, Top);
                LineTo(Left, Top + Height);
                LineTo(X1, Top + Height);
              end;
            end else
            begin
              with Form1.Canvas do
              begin
                LineTo(X1, Top);
                LineTo(Left + Width, Top);
                LineTo(Left + Width, Top + Height);
                LineTo(X1, Top + Height);
              end;
            end;
          end;
         end;
      end;
      Form1.Canvas.LineTo(X1, Y2);
      //再画横向的线
      for i := 1 to 4 do
       with TPanel(FindComponent(PanelName + IntToStr(i))) do
       begin
         if (X1 > Top) and (X1 < Top + Height) and
            (Y2 < Left) and (Y2 > Left + Width) then
         begin
           if Y2 <= (Top + Height/2) then
           begin
             with Form1.Canvas do
              begin
                LineTo(Left, Y2);
                LineTo(Left, Top);
                LineTo(Left + Width, Top);
                LineTo(Left + Width, Y2);
              end;
           end else
           begin
             with Form1.Canvas do
              begin
                LineTo(Left, Y2);
                LineTo(Left, Top + Height);
                LineTo(Left + Width, Top + Height);
                LineTo(Left + Width, Y2);
              end;
           end;
         end;
       end;
      Form1.Canvas.LineTo(X2, Y2);
    end;end.
      

  2.   

    luke5678(奇异),所言极是,我再稍加灵活应用将满足要求。
    给分!
    Up的也有分!