where : ibrtses delphi

plotting complex functions

disclaimer

the source code of this page may not appear correctly in certain browsers
due to special characters. Have a look at the source of this HTML page
with notepad instead


There are various ways to plot complex functions. This component was thought
to do them all, but till now, only amplitude(as log) and phase(as linear) against
a log horizontal are implemented.
A sample plot (frequency response of a parallel resonance):

the code

the code as it is plots the amplitude as log in the upper half image,
the phase as linear in the lower half of the image with a common log
frequency axis. It is composed of two float plots and requires the complex unit
{ nonvisual component - does the mapping of coordinate system to screen
                        requires an image to plot on.

  uses two float plot fields, one for the amplitude and one for the phase

  advantage : multiple plots can be done onto one image

  the image has to exist before assigning the image

  use :

procedure TForm1.gobtnClick(Sender: TObject);
var
 S,D,U:ComplexPtr;
 x:integer;
begin
 cpw:=TComplexMapWin.create(image1);
 cpw.clear;
 cpw.flow:=1e6;
 cpw.fhigh:=3e7;
 cpw.mina:=1e-1;
 cpw.maxa:=1e4;
 Ra:=new(ComplexPtr);
 Ca:=new(ComplexPtr);
 La:=new(ComplexPtr);
 for x:=0 to image1.width-1 do begin // scan horizontally
   xs:=cpw.getx(x);			// get real x
   Ca^.a:=0;
   Ca^.b:=-1/(2*pi*xs*cav);
   La^.a:=0;
   La^.b:=2*pi*xs*lav;
   Ra^.a:=rav;
   Ra^.b:=0;
   s:=C_ParallelN(La,Ca);
   d:=C_ParallelN(S,Ra);
   C_R2P(d);
   cpw.putpixel(d^,xs,clblack);         // display this value
   dispose(S);
   dispose(D);
  end;
 cpw.destroy;
 cpw:=nil;
end;


}
unit ComplexPlotWin;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  extctrls,ComplexRec,PlotWin;

type
  float=extended;

  cwmodetype=(saAP,saRI);   // real/imag or abs/phase

  TComplexMapWin = class(TObject)
  private
    { Private declarations }
   fimage:TImage;
   fmw1,fmw2:TMapWin;
   ftlx,ftly,fbrx,fbry,fwidth,fheight:integer;
   fflow,ffhigh,fmina,fmaxa:float;
   fmode:cwmodetype;
  protected
    { Protected declarations }
   procedure setimage(i:TImage);
   procedure setTLX(u:integer);
   procedure setTLY(u:integer);
   procedure setWidth(u:integer);
   procedure setHeight(u:integer);
   procedure setflow(f:float);
   procedure setfhigh(f:float);
   procedure setmina(a:float);
   procedure setmaxa(a:float);
  public
    { Public declarations }
   constructor create(image:TImage);    // must exist or NIL
   destructor destroy; override;
   procedure ComplexToScreen(z:Complex;f:float;var xs,ya,yp:integer); virtual;
   procedure ScreenToFloat(xs,ys:integer;var xf,yf:float); virtual;
   procedure clear;
   procedure putpixel(z:Complex;f:float;color:TColor); virtual;
   function getX(i:integer):float;             // i:=0..width-1
  published
    { Published declarations }
   property image:TImage read fimage write setimage;
   property left:integer read ftlx write setTLX;     // with respect to image
   property top:integer read ftly write setTLY;     // with respect to image
   property width:integer read fwidth write setWidth;     // with respect to image
   property height:integer read fheight write setHeight;     // with respect to image
   property mode:cwmodetype read fmode write fmode;
   property flow:float read fflow write setflow;        // frequency
   property fhigh:float read ffhigh write setfhigh;      // frequency
   property mina:float read fmina write setmina;        // absolute value
   property maxa:float read fmaxa write setmaxa;        // absolute value

  end;

procedure Register;

implementation


uses math;

type TMyPlotException=Class(Exception);

//...........................................................................
procedure TComplexMapWin.setimage(i:TImage);
begin
 fimage:=i;
 fmw1.image:=i;
 fmw2.image:=i;
end;
procedure TComplexMapWin.setTLX(u:integer);
begin ftlx:=u; end;
procedure TComplexMapWin.setTLY(u:integer);
begin ftly:=u; end;
procedure TComplexMapWin.setWidth(u:integer);
begin fbrx:=ftlx+u; fwidth:=u; end;
procedure TComplexMapWin.setHeight(u:integer);
begin fbry:=ftly+u; fheight:=u; end;
procedure TComplexMapWin.setflow(f:float);
begin
 fflow:=f;
 fmw1.xlow:=f;
 fmw2.xlow:=f;
end;
procedure TComplexMapWin.setfhigh(f:float);
begin
 ffhigh:=f;
 fmw1.xhigh:=f;
 fmw2.xhigh:=f;
end;
procedure TComplexMapWin.setmina(a:float);
begin
 fmina:=a;
 fmw1.ylow:=a;
end;
procedure TComplexMapWin.setmaxa(a:float);
begin
 fmaxa:=a;
 fmw1.yhigh:=a;
end;

constructor TComplexMapWin.create(image:TImage);
begin
 inherited create;
 fimage:=image;
 fmode:=saAP;
 fmw1:=TMapwin.create(image);
 fmw2:=TMapWin.create(image);
 if fmode=saAP then begin
  flow:=0.1; fhigh:=100;
  fmina:=1e-9; fmaxa:=1;
  fmw1.xlow:=flow;           fmw2.xlow:=flow;
  fmw1.xhigh:=fhigh;         fmw2.xhigh:=fhigh;
  fmw1.YLow:=fmina;          fmw2.YLow:=-pi;
  fmw1.YHigh:=fmaxa;             fmw2.YHigh:=pi;
  fmw1.xlog:=true;           fmw2.xlog:=true;
  fmw1.ylog:=true;           fmw2.ylog:=false;
  fmw1.protectlog:=true;
  fmw1.top:=0;               fmw2.top:=image.height div 2;
  fmw1.height:=
    image.height div 2-1;    fmw2.height:=fmw1.height;
  fmw1.left:=0;              fmw2.left:=0;
  fmw1.width:=image.width;  fmw2.width:=image.width;
  end
 else begin//fmode=saRI

  end;
end;

destructor TComplexMapWin.destroy;
begin
 fmw1.destroy;
 fmw2.destroy;
 inherited destroy;
end;


procedure TComplexMapWin.ComplexToScreen(z:Complex;f:float;var xs,ya,yp:integer);
var ax,ay,bx,by:integer;
begin
 if fmode=saAP then begin   // z:=a,p
  fmw1.floattoscreen(f,z.a,ax,ay);
  fmw2.floattoscreen(f,z.b,bx,by);
  xs:=ax; ya:=ay; yp:=by;
 end;
end;

procedure TComplexMapWin.ScreenToFloat(xs,ys:integer;var xf,yf:float);
begin
 if fmode=saAP then begin
  if (ys>=fheight div 2) then  // in the phase part
   fmw2.ScreenToFloat(xs,ys-(fheight div 2),xf,yf)
  else // absolute part
   fmw1.ScreenToFloat(xs,ys,xf,yf);
 end;
end;
procedure TComplexMapWin.clear;
begin
 if assigned(fimage) then begin
  fimage.canvas.Pen.color:=clWhite;
  fimage.canvas.brush.color:=clWhite;
  fimage.canvas.rectangle(ftlx,ftly,fbrx,fbry);
  fimage.canvas.Pen.color:=clblack;
  fimage.canvas.moveto(0,fimage.height div 2);
  fimage.canvas.lineto(fimage.width,fimage.height div 2);
  fimage.canvas.Pen.color:=clWhite;
  end;
end;
procedure TComplexMapWin.putpixel(z:Complex;f:float;color:TColor);
begin
 fmw1.putpixel(f,z.a,color);
 fmw2.putpixel(f,z.b,color);
end;

function TComplexMapWin.getX(i:integer):float;             // i:=0..width-1
begin
 result:=fmw1.getx(i);
end;



procedure Register;
begin
 // RegisterComponents('Samples', [TComplexMapWin]);
end;

end.
 

notes

This component is not yet complete, it just served the purpose
it was designed for.
I'll update it at a later date.



Feedback is welcome





sponsored links




Delphi
home

last updated: 26.jan.00

Copyright (99,2000) Ing.Büro R.Tschaggelar