编了一个控件:
unit Unit2;
interface
uses Classes, ExtCtrls;
type
TVector = record
i, j: Double
end;
TVoltageVectorPaintBox = class(TPaintBox)
private
FList: TStringList;
FScale: Integer;
procedure Redraw;
procedure Paint; override;
procedure DrawArrowLine(const x1, y1, x2, y2: Integer;
ArrowLen: Integer = 6);
procedure SetScale(const Value: Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure AddVector(const Name: string; Vector: TVector); overload;
procedure AddVector(const Name: string; i, j: Double); overload;
procedure DelVector(const Name: string);
published
property Scale: Integer read FScale write SetScale;
end;
implementation
uses Math;
type
PVector = ^TVector;
{ TVoltageVectorPaintBox }
procedure TVoltageVectorPaintBox.AddVector(const Name: string;
Vector: TVector);
begin
AddVector(Name, Vector.i, Vector.j)
end;
procedure TVoltageVectorPaintBox.AddVector(const Name: string; i,
j: Double);
var
Index: Integer;
p: PVector;
begin
Index:=FList.IndexOf(Name);
if Index=-1 then
begin
New(p);
FList.AddObject(Name, TObject(p))
end
else
p:=PVector(FList.Objects[Index]);
p^.i:=i;
p^.j:=j;
Redraw
end;
constructor TVoltageVectorPaintBox.Create(AOwner: TComponent);
begin
inherited;
FList:=TStringList.Create;
FScale:=1
end;
procedure TVoltageVectorPaintBox.DelVector(const Name: string);
var
Index: Integer;
p: PVector;
begin
Index:=FList.IndexOf(Name);
if Index<>-1 then
begin
p:=PVector(FList.Objects[Index]);
Dispose(p);
FList.Delete(Index);
Redraw
end
end;
destructor TVoltageVectorPaintBox.Destroy;
var
i: Integer;
p: PVector;
begin
for i:=0 to FList.Count-1 do
begin
p:=PVector(FList.Objects);
Dispose(p)
end;
FList.Free;
inherited
end;
procedure TVoltageVectorPaintBox.DrawArrowLine(const x1, y1, x2,
y2: Integer; ArrowLen: Integer);
var
SlopY, CosY, SinY: Double;
begin
SlopY:=ArcTan2(y1-y2, x1-x2);
CosY:=Cos(SlopY);
SinY:=Sin(SlopY);
Canvas.MoveTo(x1, y1);
Canvas.LineTo(x2, y2);
Canvas.LineTo(x2+Round(ArrowLen*CosY-(ArrowLen*SinY/2)),
y2+Round(ArrowLen*SinY+(ArrowLen*CosY/2)));
Canvas.MoveTo(x2, y2);
Canvas.LineTo(x2+Round(ArrowLen*CosY+ArrowLen*SinY/2),
y2-Round(ArrowLen*CosY/2-ArrowLen*SinY))
end;
procedure TVoltageVectorPaintBox.Paint;
begin
inherited;
Redraw
end;
procedure TVoltageVectorPaintBox.Redraw;
var
X0, Y0, X1, Y1: Integer;
i: Integer;
begin
Canvas.FillRect(ClientRect);
X0:=Width div 2;
Y0:=Height div 2;
DrawArrowLine(0, Y0, Width, Y0, 10);
DrawArrowLine(X0, Height, X0, 0, 10);
for i:=0 to FList.Count-1 do
begin
X1:=X0+Round(PVector(FList.Objects)^.i)*FScale;
Y1:=Y0-Round(PVector(FList.Objects)^.j)*FScale;
DrawArrowLine(X0, Y0, X1, Y1);
Canvas.TextOut(X1+5, Y1, FList.Strings)
end
end;
procedure TVoltageVectorPaintBox.SetScale(const Value: Integer);
begin
if (FScale>0) and (FScale<>Value) then
begin
FScale:=Value;
Redraw
end
end;
end.
Create和Destroy方法就不解释了.
AddVector方法是向图中加一个向量,每个向量有一个名字,就是你的例图中的A411之类的.
DelVector方法是在图中删除指定名字的向量.
Scale属性是画图时的放大倍数
其他同TPaintBox控件
简单使用的例子:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Unit2;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
PaintBox: TVoltageVectorPaintBox;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
V: TVector;
begin
PaintBox:=TVoltageVectorPaintBox.Create(Self);
PaintBox.Parent:=Self;
PaintBox.Align:=alClient;
PaintBox.AddVector('a', 10, 20);
PaintBox.AddVector('b', -30.5, 40);
PaintBox.AddVector('c', -50, -30);
V.i:=24.8;
V.j:=-30.4;
PaintBox.AddVector('d', V);
PaintBox.Scale:=2
end;
end.