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