多线程绘图

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,ExtCtrls, StdCtrls,unit2,math,th1,th2, iComponent, iVCLComponent,
  iCustomComponent, iPlotComponent, iXYPlot, TeEngine, Series, TeeProcs,
  Chart;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Image1: TImage;
    Image2: TImage;
    Timer1: TTimer;
    Edit4: TEdit;
    Edit5: TEdit;
    Button6: TButton;
    Timer2: TTimer;
    Edit6: TEdit;
    Edit7: TEdit;
    Button7: TButton;
    Button8: TButton;
    Label1: TLabel;
    iXYPlot1: TiXYPlot;
    iXYPlot2: TiXYPlot;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
   shuju = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  public
  end;
var
  Form1: TForm1;
  thd1:test1;
  thd2:test2;
  shujucaiji:shuju ;
 // th2:Tbal;
  shu1,shu2:Real;
  bb:Boolean ;


implementation
 function Mydraw(p: Pointer): Integer; stdcall;
//  var
//  maxnj,maxjd:real;
//  dvol1,djd:real;
//  imag:TPaintBox ;
begin
// imag:=Form1.PaintBox1;

while  bb do

 

//setviewportorgex(imag.Canvas.Handle,imag.Width div 2,imag.Height div 2,nil);
begin
  // plotline(form1.Image2,shu1,shu2);
//   maxnj:=30;
//   maxjd:=6;
//   dvol1:=shu1;
//   djd:=shu2;
//   imag.Canvas.Pen.Style:=pssolid;      //边线
//   imag.Canvas.pen.Color:=clred;
//   imag.Canvas.font.Size:=8;
//   //image1.Canvas.moveto(trunc(djd*(image1.Width div 2-40)/maxnj),-trunc(dvol1*(image1.Height div 2-40)/maxjd));
//   imag.Canvas.lineto(trunc(dvol1*(imag.Width div 2-40)/maxnj),-trunc(djd*(imag.Height div 2-40)/maxjd));
//   imag.Canvas.moveto(trunc(dvol1*(imag.Width div 2-40)/maxnj),-trunc(djd*(imag.Height div 2-40)/maxjd));
//

 

Form1.Edit3.Text :=FloatToStr(shu1) ;
 //Application.MessageBox('', '', MB_OK);

end;
Result := 0;
end;
{$R *.dfm}

 

{ Tball }
procedure shuju.Execute;
begin
  FreeOnTerminate :=true;  //设置线程终止许可
  repeat
    Randomize;
    shu1:=( shu1+0.005)*randg(1,0.0001);
    shu2:=( shu2+0.009)*randg(1,0.0001);
    if   (shu1>30) or  (shu1<-30.0) then shu1:=0;
    if   (shu2>6.0) or  (shu2<-6.0) then shu2:=0;
   until  Terminated;    // 如果Terminated属性为True,则终止n

end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ThreadId1, ThreadId2: THandle ;
  id:DWORD;
begin
  Draw(image1);
  iXYPlot1.ClearAllData;
  thd1:=test1.Create();
  thd1.Resume ;
 
end;

 

procedure TForm1.Button2Click(Sender: TObject);
begin
    Daw(image2);
    iXYPlot2.ClearAllData;
    thd2:=test2.Create();
    thd2.Resume ;
end;

{ Tbal }

procedure TForm1.FormCreate(Sender: TObject);
begin

    shujucaiji:=shuju.Create(False );   //数据采集线程启动
     Dw(image2);
     Dw(image1);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
           Edit1 .Text :=FormatFloat('0.00',shu1);
           Edit2 .Text :=FormatFloat('0.00',shu2);
          
end;

procedure TForm1.Button6Click(Sender: TObject);
var
  bit: TBitmap;
begin
  bit := TBitmap.Create;
  bit.Width := Width;
  bit.Height := Height;
  BitBlt(bit.Canvas.Handle, 0, 0, Width, Height, GetWindowDC(Handle), 0, 0, SRCCOPY);
  bit.SaveToFile('c:\Form1.bmp');
  bit.Free;


end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
plotline(Image1,shu1,shu2);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
Draw(Image1);
Timer2.Enabled :=True;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  Timer2.Enabled :=False ;
plotfree;
end;

procedure TForm1.Button7Click(Sender: TObject);
begin
   if thd1<>nil then
     thd1.Terminate ;
     thd1:=nil;
end;

procedure TForm1.Button8Click(Sender: TObject);
begin
 if thd2<>nil then
     thd2.Terminate ;
     thd2:=nil;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    if thd1<>nil then
     thd1.Terminate ;
     thd1:=nil;
     if thd2<>nil then
     thd2.Terminate ;
     thd2:=nil;
end;

end.

unit Unit2;

interface
 uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,ExtCtrls;
    procedure Dw(ige:TImage );
    procedure Draw(imag:TImage );
    procedure plotline(imag:TImage;dvol1,djd:real);
    procedure plotfree;
    /////////////////////////////////////////////////////
    procedure Daw(imag:TImage );
    procedure ploline(imag:TImage;dvol1,djd:real);
    procedure plofree;
    var
      image:TBitmap;
      mage:TBitmap;
    implementation
uses Unit1;

 procedure Draw(imag:TImage);   //绘制曲线,扭矩和角度的关系坐标
 var
   I:Integer;
   maxnj,maxjd:real;
begin
   image:=TBitmap.Create;
   image.Height:=imag.Height ;
   image.Width:=imag.Width;
   image.PixelFormat:= pf24bit ;
    maxnj:=30;    //X轴数值
    maxjd:=6;    //Y轴数值
   image.Canvas.Brush.Color :=$32CD9A;
   image.Canvas.FillRect(Rect(0, 0, image.Width, image.Height ));
   setviewportorgex(image.Canvas.Handle,image.Width div 2,image.Height div 2,nil);      //API函数设置原点
   with image.Canvas do
 begin
//////////////////////////////////////////////////////////////
//波浪网格线
  pen.Style:=PsDot;
  pen.Color:=clgray;
  font.Name:='Arial';
  font.Size:=6;
  for i:=0 to 19 do
  begin
   moveto(-image.Width div 2+40+trunc(i*(image.Width-80)/20),image.Height div 2-40);
   lineto(-image.Width div 2+40+trunc(i*(image.Width-80)/20),-image.Height div 2+40);
  end;

  for i:=0 to 19 do
  begin
   moveto(image.Width div 2-40,-image.Height div 2+40+trunc(i*(image.Height-80)/20));
   lineto(-image.Width div 2+40,-image.Height div 2+40+trunc(i*(image.Height-80)/20));
  end;
 ////////////////////////////////////////////////////////////
  Pen.Style:=pssolid;      //边线
  pen.Color:=clblack;
  font.Size:=8;
  textout(-textwidth('角度关系曲线') div 2,image.Height div 2-30, '角度关系曲线');

  Pen.Style:=pssolid;      //边线
  pen.Color:=clblack;
  font.Size:=8;

  moveto(0,image.Height div 2-40);  //X轴
  lineto(0,-image.Height div 2+40);
  moveto(-image.Width div 2+40,0);  //Y轴
  lineto(image.Width div 2-40,0);
  //四边围线
  moveto(-image.Width div 2+40,image.Height div 2-40);
  lineto(image.Width div 2-40,image.Height div 2-40);
  lineto(image.Width div 2-40,-image.Height div 2+40);
  lineto(-image.Width div 2+40,-image.Height div 2+40);
  lineto(-image.Width div 2+40,image.Height div 2-40);

  textout(image.Width div 2-90,-5-textheight('扭'), '角度');
  textout(5,-image.Height div 2+42, '电');
  textout(5,-image.Height div 2+55, '压');
//  textout(5,-image1.Height div 2+68, '分');

    pen.Style:=pssolid;
    pen.Color:=clBlack;
    font.Name:='Arial';
    font.Size:=6;

  textout(2,2,'0');

  for i:=0 to 19 do
  begin
   moveto(-image.Width div 2+40+trunc(i*(image.Width-80)/20),0);
   lineto(-image.Width div 2+40+trunc(i*(image.Width-80)/20),-5);

   if (i<10) and (i<>0) then
    textout(-image.Width div 2+40+trunc(i*(image.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',maxnj*(i-10)*0.1));
   if (i>10) and (i<>20) then
    textout(-image.Width div 2+40+trunc(i*(image.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',(i-10)*maxnj*0.1));
  end;

  for i:=0 to 19 do
  begin
   moveto(0,-image.Height div 2+40+trunc(i*(image.Height-80)/20));
   lineto(5,-image.Height div 2+40+trunc(i*(image.Height-80)/20));

   if (i<10) and (i<>0) then
    textout(-5-textwidth('-1.0'),-image.Height div 2+40+trunc(i*(image.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
   if (i>10) and (i<>20) then
    textout(-5-textwidth('-1.0'),-image.Height div 2+40+trunc(i*(image.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
  end;
  pen.Color:=clblack;
  pen.Color:=clblue;
 end;
 setviewportorgex(image.Canvas.Handle,image.Width div 2,image.Height div 2,nil);
 image.Canvas.moveto(0,0);
 imag.Picture.Bitmap:=image;
 image.SaveToFile('c:\Form1.bmp');
end;

 

procedure plotline(imag:TImage;dvol1,djd:real);  //绘制曲线,扭矩和角度的关系
var
 maxnj,maxjd:real;
begin
   setviewportorgex(image.Canvas.Handle,image.Width div 2,image.Height div 2,nil);
   maxnj:=30;
   maxjd:=6;
   image.Canvas.Pen.Style:=pssolid;      //边线
   image.Canvas.pen.Color:=clred;
   image.Canvas.font.Size:=8;
   image.Canvas.lineto(trunc(dvol1*(image.Width div 2-40)/maxnj),-trunc(djd*(image.Height div 2-40)/maxjd));
   image.Canvas.moveto(trunc(dvol1*(image.Width div 2-40)/maxnj),-trunc(djd*(image.Height div 2-40)/maxjd));
   imag.Picture.Bitmap:=image;
end;

 procedure plotfree;
 begin
     image.Free
 end;
 /////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
 procedure Daw(imag:TImage);   //绘制曲线,扭矩和角度的关系坐标
 var
   I:Integer;
   maxnj,maxjd:real;
begin
   mage:=TBitmap.Create;
   mage.Height:=imag.Height ;
   mage.Width:=imag.Width;
   mage.PixelFormat:= pf24bit ;
    maxnj:=30;    //X轴数值
    maxjd:=6;    //Y轴数值
   mage.Canvas.Brush.Color := $32CD9A;
   mage.Canvas.FillRect(Rect(0, 0, mage.Width, mage.Height ));
   setviewportorgex(mage.Canvas.Handle,mage.Width div 2,mage.Height div 2,nil);      //API函数设置原点
   with mage.Canvas do
 begin
//////////////////////////////////////////////////////////////
//波浪网格线
  pen.Style:=PsDot;
  pen.Color:=clgray;
  font.Name:='Arial';
  font.Size:=6;
  for i:=0 to 19 do
  begin
   moveto(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20),mage.Height div 2-40);
   lineto(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20),-mage.Height div 2+40);
  end;

  for i:=0 to 19 do
  begin
   moveto(mage.Width div 2-40,-mage.Height div 2+40+trunc(i*(mage.Height-80)/20));
   lineto(-mage.Width div 2+40,-mage.Height div 2+40+trunc(i*(mage.Height-80)/20));
  end;
 ////////////////////////////////////////////////////////////
  Pen.Style:=pssolid;      //边线
  pen.Color:=clblack;
  font.Size:=8;
  textout(-textwidth('角度关系曲线') div 2,mage.Height div 2-30, '角度关系曲线');

  Pen.Style:=pssolid;      //边线
  pen.Color:=clblack;
  font.Size:=8;

  moveto(0,mage.Height div 2-40);  //X轴
  lineto(0,-mage.Height div 2+40);
  moveto(-mage.Width div 2+40,0);  //Y轴
  lineto(mage.Width div 2-40,0);
  //四边围线
  moveto(-mage.Width div 2+40,mage.Height div 2-40);
  lineto(mage.Width div 2-40,mage.Height div 2-40);
  lineto(mage.Width div 2-40,-mage.Height div 2+40);
  lineto(-mage.Width div 2+40,-mage.Height div 2+40);
  lineto(-mage.Width div 2+40,mage.Height div 2-40);

  textout(mage.Width div 2-90,-5-textheight('扭'), '角度');
  textout(5,-mage.Height div 2+42, '电');
  textout(5,-mage.Height div 2+55, '压');
//  textout(5,-image1.Height div 2+68, '分');

    pen.Style:=pssolid;
    pen.Color:=clBlack;
    font.Name:='Arial';
    font.Size:=6;

  textout(2,2,'0');

  for i:=0 to 19 do
  begin
   moveto(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20),0);
   lineto(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20),-5);

   if (i<10) and (i<>0) then
    textout(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',maxnj*(i-10)*0.1));
   if (i>10) and (i<>20) then
    textout(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',(i-10)*maxnj*0.1));
  end;

  for i:=0 to 19 do
  begin
   moveto(0,-mage.Height div 2+40+trunc(i*(mage.Height-80)/20));
   lineto(5,-mage.Height div 2+40+trunc(i*(mage.Height-80)/20));

   if (i<10) and (i<>0) then
    textout(-5-textwidth('-1.0'),-mage.Height div 2+40+trunc(i*(mage.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
   if (i>10) and (i<>20) then
    textout(-5-textwidth('-1.0'),-mage.Height div 2+40+trunc(i*(mage.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
  end;
  pen.Color:=clblack;
  pen.Color:=clblue;
 end;
 setviewportorgex(mage.Canvas.Handle,mage.Width div 2,mage.Height div 2,nil);
 mage.Canvas.moveto(0,0);
 imag.Picture.Bitmap:=mage;
// mage.SaveToFile('c:\Form1.bmp');
end;

 

procedure ploline(imag:TImage;dvol1,djd:real);  //绘制曲线,扭矩和角度的关系
var
 maxnj,maxjd:real;
begin
   setviewportorgex(mage.Canvas.Handle,mage.Width div 2,mage.Height div 2,nil);
   maxnj:=30;
   maxjd:=6;
   mage.Canvas.Pen.Style:=pssolid;      //边线
   mage.Canvas.pen.Color:=clred;
   mage.Canvas.font.Size:=8;
   mage.Canvas.lineto(trunc(dvol1*(mage.Width div 2-40)/maxnj),-trunc(djd*(mage.Height div 2-40)/maxjd));
   mage.Canvas.moveto(trunc(dvol1*(mage.Width div 2-40)/maxnj),-trunc(djd*(mage.Height div 2-40)/maxjd));
   imag.Picture.Bitmap:=mage;
end;

 procedure plofree;
 begin
     mage.Free
 end;
 procedure Dw(ige:TImage);   //绘制曲线,扭矩和角度的关系坐标
 var
   I:Integer;
   maxnj,maxjd:real;
begin
    maxnj:=30;    //X轴数值
    maxjd:=6;    //Y轴数值
   ige.Canvas.Brush.Color :=$32CD9A;
   ige.Canvas.FillRect(Rect(0, 0, ige.Width, ige.Height ));
   setviewportorgex(ige.Canvas.Handle,ige.Width div 2,ige.Height div 2,nil);      //API函数设置原点
   with ige.Canvas do
 begin
//////////////////////////////////////////////////////////////
//波浪网格线
  pen.Style:=PsDot;
  pen.Color:=clgray;
  font.Name:='Arial';
  font.Size:=6;
  for i:=0 to 19 do
  begin
   moveto(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20),ige.Height div 2-40);
   lineto(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20),-ige.Height div 2+40);
  end;

  for i:=0 to 19 do
  begin
   moveto(ige.Width div 2-40,-ige.Height div 2+40+trunc(i*(ige.Height-80)/20));
   lineto(-ige.Width div 2+40,-ige.Height div 2+40+trunc(i*(ige.Height-80)/20));
  end;
 ////////////////////////////////////////////////////////////
  Pen.Style:=pssolid;      //边线
  pen.Color:=clblack;
  font.Size:=8;
  textout(-textwidth('角度关系曲线') div 2,ige.Height div 2-30, '角度关系曲线');

  Pen.Style:=pssolid;      //边线
  pen.Color:=clblack;
  font.Size:=8;

  moveto(0,ige.Height div 2-40);  //X轴
  lineto(0,-ige.Height div 2+40);
  moveto(-ige.Width div 2+40,0);  //Y轴
  lineto(ige.Width div 2-40,0);
  //四边围线
  moveto(-ige.Width div 2+40,ige.Height div 2-40);
  lineto(ige.Width div 2-40,ige.Height div 2-40);
  lineto(ige.Width div 2-40,-ige.Height div 2+40);
  lineto(-ige.Width div 2+40,-ige.Height div 2+40);
  lineto(-ige.Width div 2+40,ige.Height div 2-40);

  textout(ige.Width div 2-90,-5-textheight('扭'), '角度');
  textout(5,-ige.Height div 2+42, '电');
  textout(5,-ige.Height div 2+55, '压');
//  textout(5,-image1.Height div 2+68, '分');

    pen.Style:=pssolid;
    pen.Color:=clBlack;
    font.Name:='Arial';
    font.Size:=6;

  textout(2,2,'0');

  for i:=0 to 19 do
  begin
   moveto(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20),0);
   lineto(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20),-5);

   if (i<10) and (i<>0) then
    textout(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',maxnj*(i-10)*0.1));
   if (i>10) and (i<>20) then
    textout(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',(i-10)*maxnj*0.1));
  end;

  for i:=0 to 19 do
  begin
   moveto(0,-ige.Height div 2+40+trunc(i*(ige.Height-80)/20));
   lineto(5,-ige.Height div 2+40+trunc(i*(ige.Height-80)/20));

   if (i<10) and (i<>0) then
    textout(-5-textwidth('-1.0'),-ige.Height div 2+40+trunc(i*(ige.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
   if (i>10) and (i<>20) then
    textout(-5-textwidth('-1.0'),-ige.Height div 2+40+trunc(i*(ige.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
  end;
  pen.Color:=clblack;
  pen.Color:=clblue;
 end;
end;


end.

unit th1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,ExtCtrls,unit2;

type
  test1 = class(TThread)
  private
    { Private declarations }
    FImg:TImage;
    FVmax,FVmin:Real;         //曲线绘图区域的最大值和最小值
  protected
    procedure Execute; override;
    procedure Exe;
  public
   Constructor Create();
  end;

implementation

uses Unit1;

{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure test1.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ test1 }

constructor test1.Create;
begin
 Inherited Create(true);
end;

procedure test1.Exe;
begin
   plotline(form1.Image1,shu1,shu2);
   Form1.iXYPlot1.Channel[0].AddXY(shu1,shu2);
  // Form1.Chart1.Series[0].AddXY(shu1,shu2);
   Form1.Edit4 .Text :=FormatFloat('0.00',shu1);
   form1. Edit5 .Text :=FormatFloat('0.00',shu2);
end;

procedure test1.Execute;
begin
   FreeOnTerminate:=True ;
     While not Terminated do
     begin
      Synchronize( Exe);
        Sleep(1);//解决CPU占用过高问题  Sleep(0)告诉系统切换CPU时间片,就是把当时CPU时间片切换到其它线程去执行,也是会起到延迟效果。sleep不会占用CPU,不过会让CPU去处理其他的内容,有可能切换到其他线程的时候,其他线程占用了cpu

     end;
    plotfree;

end;

 


end.

unit th2;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,ExtCtrls,unit2;

type
  test2 = class(TThread)
  private
    { Private declarations }
    FImge:TImage;
  protected
    procedure Execute; override;
    procedure Exee;
    public
   Constructor Create();
  end;

implementation

uses Unit1;

{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure test2.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ test2 }

constructor test2.Create;
begin
Inherited Create(true);
end;

procedure test2.Execute;
begin
  FreeOnTerminate:=True ;
     While not Terminated do
     begin
      Synchronize(Exee);
      Sleep(1);   //解决CPU占用过高问题
     end;
    plofree;
end;

procedure test2.Exee;
begin
   ploline(form1.Image2,shu1,shu2);
   Form1.iXYPlot2.Channel[0].AddXY(shu1,shu2);
   Form1.Edit6 .Text :=FormatFloat('0.00',shu1);
   form1. Edit7 .Text :=FormatFloat('0.00',shu2);
end;

end.

  

posted @ 2023-10-24 21:15  大大章鱼  阅读(17)  评论(0编辑  收藏  举报