unit MathObj; {=================================================================} { Версия файла 3.0.000 } { от 4 декабря 2002 г. } {==========================} interface {==========================} uses WinTypes,Math,GlType,GlProc,Classes,SysUtils, MVTU_TLB; type t_NumData = (t_Sgl,t_Dbl,t_Bool,t_Byte,t_Int,t_lInt,t_unk,t_ch); t_NumDataArray = array [t_NumData]of Integer; TNumRec = record case t_NumData of t_Sgl : (Ps : Single); t_Dbl : (Pd : Double); t_Bool: (Pbl: Boolean); t_Byte: (Pb : Byte); t_Int : (Pi : TSmallInt); t_lInt: (Pli: LongInt); t_ch : (Pch: Char); end; TNumDataRec = record Data : RealType; case t_NumData of t_Sgl : (Ps : ^Single); t_Dbl : (Pd : ^Double); t_Bool: (Pbl: ^Boolean); t_Byte: (Pb : ^Byte); t_Int : (Pi : ^TSmallInt); t_lInt: (Pli: ^LongInt); t_ch : (Pch: PChar); end; TNumArrDataRec = record case t_NumData of t_Sgl : (Ps : PSglArr); t_Dbl : (Pd : PExtArr); t_Bool: (Pbl: PBoolArr); t_Byte: (Pb : PByteArr); t_Int : (Pi : PSmallIntArr); t_lInt: (Pli: PLongIntArr); t_unk : (Data : Pointer); t_ch : (Pch: PChar); end; PNumArray = ^TNumArray;{указатель на объект - динамический массив действ. чисел} PExtArray = ^TExtArray;{указатель на объект - динамический массив действ. чисел} PIntArray = ^TIntArray;{указатель на объект - динамический массив целых чисел} PComplexArray= ^TComplexArray; PPExtArray = ^PExtArray;{указатель на указатель на объект - динамический массив действ. чисел} PPIntArray = ^PIntArray;{указатель на указатель на объект - динамический массив целых чисел} PPComplexArray = ^PComplexArray; PArray = ^TArray; PPtrArray = ^TPtrArray; PPtrExt = ^TPtrExt; PPtrInt = ^TPtrInt; PComplexPtrArray = ^TComplexPtrArray; PExtPtrArray = ^TExtPtrArray; PPtrPtrArray = ^TPtrPtrArray; PIntPtrArray = ^TIntPtrArray; PExtPtrArray2 = ^TExtPtrArray2; PExtArray2 = ^TExtArray2;{указатель на объект - двухмерный динамический массив действ. чисел} PIntArray2 = ^TIntArray2;{указатель на объект - двухмерный динамический массив целых. чисел} TArray = class(TObject) public Count, Size: Integer; constructor Create(ACount: Integer); procedure ChangeCount(NewCount: Integer);virtual;abstract; procedure AtDelete(IMin,IMax: Integer);virtual;abstract; end; TNumArray = class(TArray) d_type: t_NumData; d_Size: Byte; Arr : TNumArrDataRec; constructor Create(ACount: Integer;aType:t_NumData); destructor Destroy;override; function Val(I: Integer) : RealType; procedure Z(I : Integer;Y : RealType); function Val_(I,aType: Integer) : RealType; procedure Z_(I,aType : Integer;Y : RealType); procedure ChangeCount(NewCount:Integer;NewType:t_NumData); procedure Add(X:RealType); procedure AtDelete(IMin,IMax: Integer); procedure FillArray(Y : RealType); private procedure SetItem(Ind:Integer;aType:T_NumData;Value:RealType); function GetItem(Ind:Integer;aType:T_NumData):RealType; function GetItemSize(aType:t_NumData):Byte; end; TArray2 = class(TObject) public CountX, CountY, SizeX: Integer; procedure ChangeCount(NewCountx,NewCounty: Integer);virtual;abstract; end; TExtArray = class(TArray) Arr : PExtArr; constructor Create(ACount: Integer); destructor Destroy;override; function Val(I: Integer) : RealType; procedure Z(I : Integer;Y : RealType); procedure ChangeCount(NewCount: Integer);override; procedure Add(X:RealType); procedure AtDelete(IMin,IMax: Integer);override; procedure FillArray(Y : RealType); end; TComplexArray = class(TArray) Arr : PComplexArr; constructor Create(ACount: Integer); destructor Destroy;override; function Val(I: Integer) : TComplex; procedure Z(I : Integer;Y : TComplex); procedure ChangeCount(NewCount: Integer);override; procedure Add(X:TComplex); procedure AtDelete(IMin,IMax: Integer);override; procedure FillArray(Y : TComplex); end; TIntArray = class(TArray) Arr : PIntArr; constructor Create(ACount: Integer); destructor Destroy;override; function Val(I : Integer) : Integer; procedure Z(I : Integer;Y : Integer); procedure Add(X:Integer); procedure ChangeCount(NewCount: Integer);override; procedure AtDelete(IMin,IMax: Integer);override; procedure FillArray(Y : Integer); end; TBoolArray = class(TArray) Arr : PBoolArr; constructor Create(ACount: Integer); destructor Destroy;override; function Val(I : Integer) : Boolean; procedure Z(I : Integer;Y : Boolean); procedure Add(X:Boolean); procedure ChangeCount(NewCount: Integer);override; procedure AtDelete(IMin,IMax: Integer);override; procedure FillArray(Y : Boolean); end; TPntArray = class(TArray) Arr : PPntArr; constructor Create(ACount: Integer); destructor Destroy;override; function Val(I: Integer) : TPoint; procedure Z(I : Integer;var AX,AY : Integer); procedure DZ(I : Integer;var AX,AY : Integer); procedure ChangeCount(NewCount: Integer);override; procedure AtDelete(IMin,IMax: Integer);override; end; TPtrArray = class(TArray) Arr : PPtrArr; constructor Create(ACount: Integer); destructor Destroy;override; procedure ChangeCount(NewCount: Integer);override; procedure AtDelete(IMin,IMax: Integer);override; end; TPtrExt = class(TPtrArray) constructor Create(Cx,Cy: Integer); procedure cc(I,Acount: Integer); procedure AtFree(IMin,IMax: Integer); procedure Add(Cy : Integer); function Pta(I : Integer) : PExtArr; function Ptr(I : Integer) : TExtArray; function Val(I,J : Integer) : RealType; procedure Z(I,J: Integer;X : RealType); end; TPtrInt = class(TPtrArray) constructor Create(Cx,Cy: Integer); procedure cc(I,Acount: Integer); procedure AtFree(IMin,IMax: Integer); procedure Add(Cy : Integer); function Pta(I : Integer) : PIntArr; function Ptr(I : Integer) : TIntArray; function Val(I,J : Integer) : Integer; procedure Z(I,J: Integer;X : Integer); end; TComplexPtrArray = array[0..ArrayPtrSize] of TComplexArray; TExtPtrArray = array[0..ArrayPtrSize] of TExtArray; TPtrPtrArray = array[0..ArrayPtrSize] of TPtrArray;{указатель на объект - динамический массив массивов указателей} TIntPtrArray = array[0..ArrayPtrSize] of TIntArray;{указатель на объект - динамический массив массивов целых чисел} TComplexArray2 = class(TArray2) Arr : PComplexPtrArray; constructor Create(ACountX,ACountY: Integer); destructor Destroy;override; procedure ChangeCount(NewCountx,NewCounty: Integer);override; procedure z(AI,AJ:Integer;AY:TComplex); function Val(AI,AJ: Integer):TComplex; end; TExtArray2 = class(TArray2) Arr : PExtPtrArray; constructor Create(ACountX,ACountY: Integer); destructor Destroy;override; procedure ChangeCount(NewCountx,NewCounty: Integer);override; procedure z(AI,AJ:Integer;AY:Realtype); function Val(AI,AJ: Integer):Realtype; end; TIntArray2 = class(TArray2) Arr : PIntPtrArray; constructor Create(ACountx,ACounty: Integer); destructor Destroy;override; procedure ChangeCount(NewCountx,NewCounty: Integer);override; procedure z(AI,AJ:Integer;AY:Integer); function Val(AI,AJ: Integer):Integer; end; TPropObj = class(TObject) procedure Save(var FS:TStream);virtual; procedure Load(var F:TStream);virtual; procedure GetNumPorts(var Uc,Yc:Integer);virtual; end; TPortType = class int, outs: TIntArray; constructor Create(CU,CY : TIntArray); destructor Destroy;override; procedure SetupPortTypes(CU,CY : TIntArray); end; TMultiSelect = class Psrc : PString; selected : TIntArray; constructor Create(S : String;var Src:String;c:Char); destructor Destroy;override; end; TExtPtrArray2 = array[0..ArrayPtrSize] of TExtArray2; TInitDll = procedure(var at,adt,atfinal:PRealType;Dirs : PDirRec); TDoneDll = procedure; TInfoProcDLL = procedure(Action:Integer; var BlockId, ParamId: Integer; Info: pchar); TRunProc = function (at,adt:RealType;var time,dtime:RealType; var AU{:TPtrExt; var}, AY:TPtrExt; var AX{:array of RealType; var}, ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray; var Vars : Pointer;Action:Integer):Integer; TEditProc = function (var S : String;var P:array of Pointer;Which,Action:Integer;var FS:TStream):Integer; TRstProc = function (at,adt:RealType;var AU,AY:TPtrExt;var AX,ADX:PExtArr; var Prop:TPtrArray;var Vars : Pointer;Action:Integer;var F:File):Integer; //Тип данных - функция генерации блока для МВТУ-4 TConvertFunc = function(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; //Функция конвертации множества для МВТУ-4 function ConvertMultiSelect(Data: TMultiSelect):string; procedure StringsPosInStr(sub,src:String;var Arg : TIntArray;c:Char); function GetVectorData(Ib:Integer;AX:RealType;var Pyy,Pxx:array of RealType):RealType; function GetTableData(Ind:Integer;AX:RealType;Pyy:PExtPtrArray;Pxx,AY:TExtArray):Integer; procedure iQuickSort(var A: array of Integer; iLo, iHi: Integer); procedure rQuickSort(var A: array of RealType; iLo, iHi: Integer); procedure ChangeBufSize(NewSize:Integer;var Size:Integer;var Buf:Pointer); function LoadStrmString(var FS:TStream):String; procedure SaveStrmString(var FS:TStream;S:String); function GetFunctnValue(px1, px2: TExtArray; py: TExtArray2; ax, ay : RealType) : RealType; {$IFDEF PHG} //Не используется procedure _GetTable2Data(second:Integer;ax,ay:RealType;Px1:TExtArray;Px2:TIntArray; Data:PExtPtrArray2;var Y:array of RealType); //Не используется procedure _GetTable2WorkRect(second:Integer;ax,ay:RealType;Px1:TExtArray;Px2:TIntArray;Data:PExtPtrArray2; var Ia1,Ib1,Ia2,Ib2,Ia3,Ib3:Integer; var x0,x1,y0,y1,y2,y3:RealType); function _GetTableSegment(ax:RealType;Px:TExtArray;var Ia,Ib:Integer):RealType; {$ENDIF} var MBTY_BUF : Pointer; MBTY_BUF_SIZE : Integer = 0; const t_NumDataSize : t_NumDataArray =(4,8,1,1,2,4,1,1); {------------------------------------------------------------------------------} IMPLEMENTATION {------------------------------------------------------------------------------} function ConvertMultiSelect(Data: TMultiSelect):string; var i: integer; begin if Data.selected.Count > 0 then begin Result:='['+IntToStr(Data.Selected.Arr^[0]); for i:=1 to Data.selected.Count - 1 do Result:=Result + ','+ IntToStr(Data.Selected.Arr^[i]); Result:=Result + ']'; end else Result:='[]'; end; procedure ChangeBufSize(NewSize:Integer;var Size:Integer;var Buf:Pointer); begin if NewSize > Size then begin if Size > 0 then FreeMem(Buf,Size); GetMem(Buf,NewSize); Size:=NewSize end end; {-------------------------------------------------------------------------- TPropObj METHODS {--------------------------------------------------------------------------} procedure TPropObj.Save; begin end; procedure TPropObj.Load; begin end; procedure TPropObj.GetNumPorts; begin Uc:=0;Yc:=1 end; {-------------------------------------------------------------------------- TPortType METHODS {--------------------------------------------------------------------------} constructor TPortType.Create; begin inherited Create; int:=TIntArray.Create(1); outs:=TIntArray.Create(1); int.ChangeCount(0); outs.ChangeCount(0); if CU <> nil then begin int.ChangeCount(CU.Count); if CU.Count > 0 then Move(CU.arr^,int.arr^,CU.Count*SOfI) end; if CY <> nil then begin outs.ChangeCount(CY.Count); if CY.Count > 0 then Move(CY.arr^,outs.arr^,CY.Count*SOfI) end end; destructor TPortType.Destroy; begin int.Free; outs.Free; inherited Destroy end; //------------------------------------------------------------------------- procedure TPortType.SetupPortTypes; begin if CU <> nil then begin int.ChangeCount(CU.Count); if CU.Count > 0 then Move(CU.arr^,int.arr^,CU.Count*SOfI) end; if CY <> nil then begin outs.ChangeCount(CY.Count); if CY.Count > 0 then Move(CY.arr^,outs.arr^,CY.Count*SOfI) end end; {--------------------------------------------------------------------------} { TArray Methods } {--------------------------------------------------------------------------} constructor TArray.Create; begin inherited Create; if ACount > ArraySize then Size:=ArraySize else Size:=ACount; Count:=Size end; {--------------------------------------------------------------------------} { TExtArray Methods } {--------------------------------------------------------------------------} procedure TExtArray.FillArray; var i : Integer; begin for i:=0 to Count-1 do Arr^[i]:=Y end; {-------------------------------------------------------------------------------------------------------} constructor TExtArray.Create; begin inherited Create(ACount); if Size > 0 then GetMem(Arr,Size*SOfR); FillArray(0) end; {-------------------------------------------------------------------------------------------------------} procedure TExtArray.Add; var P : Pointer; begin if Size < (Count+1) then begin GetMem(P,(count+1)*SOfR); if Size > 0 then Move(arr^,P^,count*SOfR); if Size > 0 then FreeMem(arr,Size*SOfR); arr:=P; Size:=Count+1 end; arr^[count]:=X; Inc(count) end; {-------------------------------------------------------------------------------------------------------} destructor TExtArray.Destroy; begin if Size > 0 then FreeMem(Arr,Size*SOfR); inherited Destroy end; {-------------------------------------------------------------------------------------------------------} procedure TExtArray.Z; begin Arr^[I]:=Y end; {-------------------------------------------------------------------------------------------------------} function TExtArray.Val; begin Val:=Arr^[I] end; {-------------------------------------------------------------------------------------------------------} procedure TExtArray.ChangeCount; var Pe : PExtArr; begin if Size < NewCount then begin if NewCount > ArraySize then NewCount:=ArraySize; GetMem(Pe,NewCount*SOfR); FillChar(Pe^,NewCount*SOfR,0); if Size > 0 then Move(Arr^,Pe^,Count*SOfR); if Size > 0 then FreeMem(Arr,Size*SOfR); Arr:=Pe; Size:=NewCount end; Count:=NewCount end; {-------------------------------------------------------------------------------------------------------} procedure TExtArray.AtDelete; var i,j : Integer; begin if Imax > Count-1 then Imax:=Count-1; if Imin < 0 then Imin:=0; if Imin > Imax then exit; j:=0; for i:=Imax+1 to Count-1 do begin Arr^[Imin+j]:=Arr^[i]; inc(j) end; Dec(Count,Imax-Imin+1) end; {--------------------------------------------------------------------------} { TExtArray Methods } {--------------------------------------------------------------------------} const cpZero: TComplex = (Re:0;Im:0); procedure TComplexArray.FillArray; var i : Integer; begin for i:=0 to Count-1 do Arr^[i]:=Y end; {-------------------------------------------------------------------------------------------------------} constructor TComplexArray.Create; begin inherited Create(ACount); if Size > 0 then GetMem(Arr,Size*2*SOfR); FillArray(cpZero) end; {-------------------------------------------------------------------------------------------------------} procedure TComplexArray.Add; var P : Pointer; begin if Size < (Count+1) then begin GetMem(P,(count+1)*SOfR); if Size > 0 then Move(arr^,P^,count*2*SOfR); if Size > 0 then FreeMem(arr,Size*2*SOfR); arr:=P; Size:=Count+1 end; arr^[count]:=X; Inc(count) end; {-------------------------------------------------------------------------------------------------------} destructor TComplexArray.Destroy; begin if Size > 0 then FreeMem(Arr,Size*2*SOfR); inherited Destroy end; {-------------------------------------------------------------------------------------------------------} procedure TComplexArray.Z; begin Arr^[I]:=Y end; {-------------------------------------------------------------------------------------------------------} function TComplexArray.Val; begin Val:=Arr^[I] end; {-------------------------------------------------------------------------------------------------------} procedure TComplexArray.ChangeCount; var Pe : PComplexArr; begin if Size < NewCount then begin if NewCount > ArraySize then NewCount:=ArraySize; GetMem(Pe,NewCount*2*SOfR); FillChar(Pe^,NewCount*2*SOfR,0); if Size > 0 then Move(Arr^,Pe^,Count*2*SOfR); if Size > 0 then FreeMem(Arr,Size*2*SOfR); Arr:=Pe; Size:=NewCount end; Count:=NewCount end; {-------------------------------------------------------------------------------------------------------} procedure TComplexArray.AtDelete; var i,j : Integer; begin if Imax > Count-1 then Imax:=Count-1; if Imin < 0 then Imin:=0; if Imin > Imax then exit; j:=0; for i:=Imax+1 to Count-1 do begin Arr^[Imin+j]:=Arr^[i]; inc(j) end; Dec(Count,Imax-Imin+1) end; {-------------------------------------------------------------------------- TNumArray Methods --------------------------------------------------------------------------} procedure TNumArray.SetItem; begin case aType of t_Sgl : Arr.Ps^[Ind]:=Value; t_Dbl : Arr.Pd^[Ind]:=Value; t_Bool : Arr.Pbl^[Ind]:=Value <> 0; t_Byte : Arr.Pb^[Ind]:=round(Value); t_Int : Arr.Pi^[Ind]:=round(Value); t_lInt : Arr.Pli^[Ind]:=round(Value); end end; {-------------------------------------------------------------------------------------------------------} function TNumArray.GetItem; begin case aType of t_Sgl : Result:=Arr.Ps^[Ind]; t_Dbl : Result:=Arr.Pd^[Ind]; t_Bool : if Arr.Pbl^[Ind] then Result:=1 else Result:=0; t_Byte : Result:=Arr.Pb^[Ind]; t_Int : Result:=Arr.Pi^[Ind]; t_lInt : Result:=Arr.Pli^[Ind]; else Result:=0; end end; {-------------------------------------------------------------------------------------------------------} function TNumArray.GetItemSize(aType:t_NumData):Byte; begin case aType of t_Sgl : Result:=4; t_Dbl : Result:=8; t_Bool : Result:=1; t_Byte : Result:=1; t_Int : Result:=2; t_lInt : Result:=4; else Result:=4; end; end; {-------------------------------------------------------------------------------------------------------} procedure TNumArray.FillArray; var i : Integer; begin for i:=0 to Count-1 do SetItem(i,d_type,Y) end; {-------------------------------------------------------------------------------------------------------} constructor TNumArray.Create; begin inherited Create(ACount); d_Type:=aType; d_Size:=GetItemSize(aType); if Size > 0 then GetMem(Arr.Data,Size*d_Size); FillArray(0) end; {-------------------------------------------------------------------------------------------------------} procedure TNumArray.Add; var P : Pointer; begin if Size < (Count+1) then begin GetMem(P,(count+1)*d_Size); if Size > 0 then Move(arr.Data^,P^,count*d_Size); if Size > 0 then FreeMem(arr.Data,Size*d_Size); arr.Data:=P; Size:=Count+1 end; SetItem(count,d_type,X); Inc(count) end; {-------------------------------------------------------------------------------------------------------} destructor TNumArray.Destroy; begin if Size > 0 then FreeMem(Arr.Data,Size*d_Size); inherited Destroy end; {-------------------------------------------------------------------------------------------------------} procedure TNumArray.Z; begin SetItem(I,d_type,Y) end; {-------------------------------------------------------------------------------------------------------} function TNumArray.Val; begin Result:=GetItem(I,d_type) end; {-------------------------------------------------------------------------------------------------------} procedure TNumArray.Z_; begin SetItem(I,T_NumData(atype),Y) end; {-------------------------------------------------------------------------------------------------------} function TNumArray.Val_; begin Result:=GetItem(I,T_NumData(atype)) end; {-------------------------------------------------------------------------------------------------------} procedure TNumArray.ChangeCount; var P : Pointer; NewSize : Byte; begin d_type:=NewType; NewSize:=GetItemSize(NewType); if Size < trunc((NewSize/d_Size)*NewCount) then begin if NewCount > ArraySize then NewCount:=ArraySize; GetMem(P,NewCount*NewSize); FillChar(P^,NewCount*NewSize,0); if Size > 0 then Move(Arr.Data^,P^,Count*d_Size); if Size > 0 then FreeMem(Arr.Data,Size*d_Size); Arr.Data:=P; Size:=NewCount end; d_Size:=NewSize; Count:=NewCount end; {-------------------------------------------------------------------------------------------------------} procedure TNumArray.AtDelete; var i,j : Integer; begin if Imax > Count-1 then Imax:=Count-1; if Imin < 0 then Imin:=0; if Imin > Imax then exit; j:=0; for i:=Imax+1 to Count-1 do begin SetItem(Imin+j,d_type,GetItem(i,d_type)); inc(j) end; Dec(Count,Imax-Imin+1) end; {--------------------------------------------------------------------------} { TIntArray Methods } {--------------------------------------------------------------------------} procedure TIntArray.FillArray; var i : Integer; begin for i:=0 to Count-1 do Arr^[i]:=Y end; procedure TIntArray.Add; var P : Pointer; begin if Size < (Count+1) then begin GetMem(P,(count+1)*SOfI); if Size > 0 then begin Move(arr^,P^,count*SOfI); FreeMem(arr,Size*SOfI) end; arr:=P; Size:=Count+1 end; arr^[count]:=X; Inc(count) end; constructor TIntArray.Create; begin inherited Create(ACount); if Size > 0 then GetMem(Arr,Size*SOfI); FillArray(0) end; destructor TIntArray.Destroy; begin if Size > 0 then FreeMem(Arr,Size*SOfI); inherited Destroy end; procedure TIntArray.Z; begin Arr^[I]:=Y end; function TIntArray.Val; begin Val:=Arr^[I] end; procedure TIntArray.ChangeCount; var Pe : PIntArr; begin if Size < NewCount then begin if NewCount > ArraySize then NewCount:=ArraySize; GetMem(Pe,NewCount*SOfI); FillChar(Pe^,NewCount*SOfI,0); if Size > 0 then Move(Arr^,Pe^,Count*SOfI); if Size > 0 then FreeMem(Arr,Size*SOfI); Arr:=Pe; Size:=NewCount end; Count:=NewCount end; procedure TIntArray.AtDelete; var i,j : Integer; begin if Imax > Count-1 then Imax:=Count-1; if Imin < 0 then Imin:=0; if Imin > Imax then exit; j:=0; for i:=Imax+1 to Count-1 do begin Arr^[Imin+j]:=Arr^[i]; inc(j) end; Dec(Count,Imax-Imin+1) end; {-------------------------------------------------------------------------- TBoolArray Methods --------------------------------------------------------------------------} procedure TBoolArray.FillArray; var i : Integer; begin for i:=0 to Count-1 do Arr^[i]:=Y end; procedure TBoolArray.Add; var P : Pointer; begin if Size < (Count+1) then begin GetMem(P,(count+1)*SOfB); if Size > 0 then Move(arr^,P^,count*SOfB); if Size > 0 then FreeMem(arr,Size*SOfB); arr:=P; Size:=Count+1 end; arr^[count]:=X; Inc(count) end; constructor TBoolArray.Create; begin inherited Create(ACount); if Size > 0 then GetMem(Arr,Size*SOfB); FillArray(False) end; destructor TBoolArray.Destroy; begin if Size > 0 then FreeMem(Arr,Size*SOfB); inherited Destroy end; procedure TBoolArray.Z; begin Arr^[I]:=Y end; function TBoolArray.Val; begin Val:=Arr^[I] end; procedure TBoolArray.ChangeCount; var Pe : PBoolArr; begin if Size < NewCount then begin if NewCount > ArraySize then NewCount:=ArraySize; GetMem(Pe,NewCount*SOfB); FillChar(Pe^,NewCount*SOfB,0); if Size > 0 then Move(Arr^,Pe^,Count*SOfB); if Size > 0 then FreeMem(Arr,Size*SOfB); Arr:=Pe; Size:=NewCount end; Count:=NewCount end; procedure TBoolArray.AtDelete; var i,j : Integer; begin if Imax > Count-1 then Imax:=Count-1; if Imin < 0 then Imin:=0; if Imin > Imax then exit; j:=0; for i:=Imax+1 to Count-1 do begin Arr^[Imin+j]:=Arr^[i]; inc(j) end; Dec(Count,Imax-Imin+1) end; {--------------------------------------------------------------------------} { TPntArray Methods } {--------------------------------------------------------------------------} constructor TPntArray.Create; begin inherited Create(ACount); if Size > ArrayPtrSize then Size:=ArrayPtrSize; Count:=Size; if Size > 0 then GetMem(Arr,Size*SOfPt); if Size > 0 then FillChar(Arr^,Size*SOfPt,0) end; {--------------------------------------------------------------------------} destructor TPntArray.Destroy; begin if Size > 0 then FreeMem(Arr,Size*SOfPt); inherited Destroy end; {--------------------------------------------------------------------------} procedure TPntArray.Z; begin Arr^[I].X:=AX; Arr^[I].Y:=AY end; {--------------------------------------------------------------------------} procedure TPntArray.DZ; begin Inc(Arr^[I].X,AX); Inc(Arr^[I].Y,AY) end; {--------------------------------------------------------------------------} function TPntArray.Val; begin Val:=Arr^[I] end; {--------------------------------------------------------------------------} procedure TPntArray.ChangeCount; var Pe : PPntArr; begin if Size < NewCount then begin if NewCount > ArrayPtrSize then NewCount:=ArrayPtrSize; GetMem(Pe,NewCount*SOfPt); FillChar(Pe^,NewCount*SOfPt,0); if Size > 0 then Move(Arr^,Pe^,Count*SOfPt); if Size > 0 then FreeMem(Arr,Size*SOfPt); Arr:=Pe; Size:=NewCount end; Count:=NewCount end; {--------------------------------------------------------------------------} procedure TPntArray.AtDelete; var i,j : Integer; begin if Imax > Count-1 then Imax:=Count-1; if Imin < 0 then Imin:=0; if Imin > Imax then exit; j:=0; for i:=Imax+1 to Count-1 do begin Arr^[Imin+j]:=Arr^[i]; inc(j) end; Dec(Count,Imax-Imin+1) end; {-------------------------------------------------------------------------- TPtrArray Methods --------------------------------------------------------------------------} constructor TPtrArray.Create; begin inherited Create(ACount); if Size > 0 then begin GetMem(Arr,Size*SOfP); FillChar(Arr^,Size*SOfP,0) end end; destructor TPtrArray.Destroy; begin if Size > 0 then FreeMem(Arr,Size*SOfP); inherited Destroy end; procedure TPtrArray.ChangeCount; var Pe : PPtrArr; begin if Size < NewCount then begin if NewCount > ArrayPtrSize then NewCount:=ArrayPtrSize; GetMem(Pe,NewCount*SOfP); FillChar(Pe^,NewCount*SOfP,0); if Size > 0 then Move(Arr^,Pe^,Count*SOfP); if Size > 0 then FreeMem(Arr,Size*SOfP); Arr:=Pe; Size:=NewCount end; Count:=NewCount end; procedure TPtrArray.AtDelete; var i,j : Integer; begin if Imax > Count-1 then Imax:=Count-1; if Imin < 0 then Imin:=0; if Imin > Imax then exit; j:=0; for i:=Imax+1 to Count-1 do begin Arr^[Imin+j]:=Arr^[i]; inc(j) end; Dec(Count,Imax-Imin+1) end; {-------------------------------------------------------------------------- TPtrExt Methods --------------------------------------------------------------------------} constructor TPtrExt.Create; var i:Integer; begin inherited Create(Cx); for i:=0 to Count-1 do arr^[i]:=TExtArray.Create(Cy) end; procedure TPtrExt.cc; begin Ptr(I).ChangeCount(ACount) end; function TPtrExt.Ptr; begin Ptr:=Arr^[I] end; procedure TPtrExt.Z; begin Ptr(I).Arr^[j]:=X end; function TPtrExt.Pta; begin Pta:=Ptr(I).arr end; function TPtrExt.Val; begin Val:=Ptr(I).arr^[j] end; procedure TPtrExt.Add; var P : Pointer; begin if Size <= Count then begin GetMem(P,(count+1)*SOfP); if size > 0 then Move(arr^,P^,count*SOfP); if size > 0 then FreeMem(arr,Size*SOfP); arr:=P; Size:=Count+1; arr^[count]:=TExtArray.Create(Cy) end else Ptr(count).ChangeCount(Cy); Inc(count) end; procedure TPtrExt.AtFree; var i : Integer; begin for i:=IMin to IMax do Ptr(i).Free; AtDelete(IMin,IMax) end; {-------------------------------------------------------------------------- TPtrInt Methods --------------------------------------------------------------------------} constructor TPtrInt.Create; var i:Integer; begin inherited Create(Cx); for i:=0 to Count-1 do arr^[i]:=TIntArray.Create(Cy) end; procedure TPtrInt.cc; begin Ptr(I).ChangeCount(ACount) end; function TPtrInt.Ptr; begin Ptr:=Arr^[I] end; function TPtrInt.Pta; begin Pta:=Ptr(I).arr end; function TPtrInt.Val; begin Val:=Ptr(I).arr^[j] end; procedure TPtrInt.Z; begin Ptr(I).Arr^[j]:=X end; procedure TPtrInt.Add; var P : Pointer; begin if Size < (Count+1) then begin GetMem(P,(count+1)*SOfP); if size > 0 then Move(arr^,P^,count*SOfP); if size > 0 then FreeMem(arr,Size*SOfP); arr:=P; Size:=Count+1; arr^[count]:=TIntArray.Create(Cy); end else Ptr(count).ChangeCount(Cy); Inc(count) end; procedure TPtrInt.AtFree; var i : Integer; begin for i:=IMin to IMax do Ptr(i).Free; AtDelete(IMin,IMax) end; {--------------------------------------------------------------------------} { TExtArray2 Methods } {--------------------------------------------------------------------------} constructor TExtArray2.Create; var i : integer; begin inherited Create; SizeX:=ACountX; CountY:=ACountY; if SizeX > ArraySize then SizeX:=ArraySize; if CountY > ArraySize then CountY:=ArraySize; if SizeX > 0 then GetMem(Arr,SizeX*SOfP); CountX:=SizeX; for i:=0 to CountX-1 do Arr^[i]:=TExtArray.Create(CountY) end; destructor TExtArray2.Destroy; var i : integer; begin if SizeX > 0 then begin for i:=0 to CountX-1 do if Arr^[i] <> nil then Arr^[i].Free; FreeMem(Arr,SizeX*SOfP) end; inherited Destroy end; procedure TExtArray2.ChangeCount; var P : Pointer; i : Integer; begin NewCountX:=min(ArraySize,NewCountX); NewCountY:=min(ArraySize,NewCountY); if SizeX < NewCountX then begin GetMem(P,NewCountX*SOfP); if SizeX > 0 then Move(Arr^,P^,CountX*SOfP); Arr:=P; SizeX:=NewCountX end; if CountX < NewCountX then for i:=CountX to NewCountX-1 do Arr^[i]:=TExtArray.Create(NewCountY) else if CountX > NewCountX then for i:=NewCountX to CountX-1 do if Arr^[i] <> nil then Arr^[i].Free; CountX:=NewCountX; for i:=0 to CountX-1 do Arr^[i].ChangeCount(NewCountY); CountY:=NewCountY end; procedure TExtArray2.z; begin Arr^[AI].arr^[AJ]:=AY end; function TExtArray2.Val; begin Val:=0; if (AI < 0) or (AI > countx-1) then exit; if (AJ < 0) or (AJ > county-1) then exit; Val:=Arr^[AI].arr^[AJ]; end; {--------------------------------------------------------------------------} { TExtArray2 Methods } {--------------------------------------------------------------------------} constructor TComplexArray2.Create; var i : integer; begin inherited Create; SizeX:=ACountX; CountY:=ACountY; if SizeX > ArraySize then SizeX:=ArraySize; if CountY > ArraySize then CountY:=ArraySize; if SizeX > 0 then GetMem(Arr,SizeX*SOfP); CountX:=SizeX; for i:=0 to CountX-1 do Arr^[i]:=TComplexArray.Create(CountY) end; destructor TComplexArray2.Destroy; var i : integer; begin if SizeX > 0 then begin for i:=0 to CountX-1 do if Arr^[i] <> nil then Arr^[i].Free; FreeMem(Arr,SizeX*SOfP) end; inherited Destroy end; procedure TComplexArray2.ChangeCount; var P : Pointer; i : Integer; begin NewCountX:=min(ArraySize,NewCountX); NewCountY:=min(ArraySize,NewCountY); if SizeX < NewCountX then begin GetMem(P,NewCountX*SOfP); if SizeX > 0 then Move(Arr^,P^,CountX*SOfP); Arr:=P; SizeX:=NewCountX end; if CountX < NewCountX then for i:=CountX to NewCountX-1 do Arr^[i]:=TComplexArray.Create(NewCountY) else if CountX > NewCountX then for i:=NewCountX to CountX-1 do if Arr^[i] <> nil then Arr^[i].Free; CountX:=NewCountX; for i:=0 to CountX-1 do Arr^[i].ChangeCount(NewCountY); CountY:=NewCountY end; procedure TComplexArray2.z; begin Arr^[AI].arr^[AJ]:=AY end; function TComplexArray2.Val; begin Val:=cpZero; if (AI < 0) or (AI > countx-1) then exit; if (AJ < 0) or (AJ > county-1) then exit; Val:=Arr^[AI].arr^[AJ]; end; {--------------------------------------------------------------------------} { TIntArray2 Methods } {--------------------------------------------------------------------------} constructor TIntArray2.Create; var i : integer; begin inherited Create; SizeX:=ACountX; CountY:=ACountY; if SizeX > ArraySize then SizeX:=ArraySize; if CountY > ArraySize then CountY:=ArraySize; if SizeX > 0 then GetMem(Arr,SizeX*SOfP); CountX:=SizeX; for i:=0 to CountX-1 do Arr^[i]:=TIntArray.Create(CountY) end; destructor TIntArray2.Destroy; var i : integer; begin if SizeX > 0 then begin for i:=0 to CountX-1 do if Arr^[i] <> nil then Arr^[i].Free; FreeMem(Arr,SizeX*SOfP) end; inherited Destroy end; procedure TIntArray2.ChangeCount; var P : Pointer; i : Integer; begin NewCountX:=min(ArraySize,NewCountX); NewCountY:=min(ArraySize,NewCountY); if SizeX < NewCountX then begin GetMem(P,NewCountX*SOfP); if SizeX > 0 then Move(Arr^,P^,CountX*SOfP); Arr:=P; SizeX:=NewCountX end; if CountX < NewCountX then for i:=CountX to NewCountX-1 do Arr^[i]:=TIntArray.Create(NewCountY) else if CountX > NewCountX then for i:=NewCountX to CountX-1 do if Arr^[i] <> nil then Arr^[i].Free; CountX:=NewCountX; for i:=0 to CountX-1 do Arr^[i].ChangeCount(NewCountY); CountY:=NewCountY end; procedure TIntArray2.z; begin Arr^[AI].arr^[AJ]:=AY end; function TIntArray2.Val; begin Val:=0; if (AI < 0) or (AI > countx-1) then exit; if (AJ < 0) or (AJ > county-1) then exit; Val:=Arr^[AI].arr^[AJ] end; {--------------------------------------------------------------------------} { TMULTISELECT Methods } {--------------------------------------------------------------------------} procedure StringsPosInStr(sub,src:String;var Arg : TIntArray;c:Char); var j,k : Integer; s1,s2, s3,s4 : String; begin arg.ChangeCount(0); s1:=sub; while Pos(c,s1) <> 0 do begin j:=Pos(c,s1); if j = 0 then s2:=s1 else s2:=Copy(s1,1,j-1); s1:=Copy(s1,j+1,Length(s1)); s3:=src; k:=0; while Pos(c,s3) <> 0 do begin j:=Pos(c,s3); if j = 0 then s4:=s3 else s4:=Copy(s3,1,j-1); s3:=Copy(s3,j+1,Length(s3)); if s2 = s4 then break; inc(k); end; arg.Add(k); end; end; constructor TMultiSelect.Create; begin inherited Create; selected:=TIntArray.Create(0); Psrc:=@Src; StringsPosInStr(s,Psrc^,selected,c) end; destructor TMultiSelect.Destroy; begin selected.free; inherited Destroy end; {------------------------------------------------------------------------} function GetTableData; var x : RealType; Xa,Xb,Xc : RealType; i,Ia,Ib,Ic : integer; begin Ia:=0; Ib:=Ind; if pxx.arr^[ia] > pxx.arr^[ib] then begin Ib:=0; Ia:=Ind end; Xa:=pxx.arr^[ia]; Xb:=pxx.arr^[ib]; if AX <= Xa then Ib:=Ia; if AX >= Xb then Ia:=Ib; if Ia = Ib then begin for i:=0 to AY.count-1 do AY.arr^[i]:=pyy^[i].arr^[ia]; Result:=Ia; exit end; while abs(Ib-Ia) > 1 do begin Ic:=(Ia+Ib) div 2 ; Xc:=pxx.arr^[ic]; if AX < Xc then Ib:=Ic else Ia:=Ic end; x:=(AX-pxx.arr^[ia])/(pxx.arr^[ib]-pxx.arr^[ia]); for i:=0 to AY.count-1 do AY.arr^[i]:=pyy^[i].arr^[ia]+x*(pyy^[i].arr^[ib]-pyy^[i].arr^[ia]); Result:=Ia end; {------------------------------------------------------------------------} procedure iQuickSort(var A: array of Integer; iLo, iHi: Integer); var Lo, Hi, Mid, T: Integer; begin Lo := iLo; Hi := iHi; Mid := A[(Lo + Hi) div 2]; repeat while A[Lo] < Mid do Inc(Lo); while A[Hi] > Mid do Dec(Hi); if Lo <= Hi then begin T := A[Lo]; A[Lo] := A[Hi]; A[Hi] := T; Inc(Lo); Dec(Hi); end; until Lo > Hi; if Hi > iLo then iQuickSort(A, iLo, Hi); if Lo < iHi then iQuickSort(A, Lo, iHi); end; procedure rQuickSort(var A: array of RealType; iLo, iHi: Integer); var Lo, Hi : Integer; Mid, T : RealType; begin Lo := iLo; Hi := iHi; Mid := A[(Lo + Hi) div 2]; repeat while A[Lo] < Mid do Inc(Lo); while A[Hi] > Mid do Dec(Hi); if Lo <= Hi then begin T := A[Lo]; A[Lo] := A[Hi]; A[Hi] := T; Inc(Lo); Dec(Hi); end; until Lo > Hi; if Hi > iLo then rQuickSort(A, iLo, Hi); if Lo < iHi then rQuickSort(A, Lo, iHi); end; {----------------------------------------------------------} function GetVectorData; var x : RealType; Xa,Xb,Xc : RealType; Ia,Ic : integer; begin Ia:=0; if pxx[ia] > pxx[ib] then begin Ia:=Ib; Ib:=0 end; Xa:=pxx[ia]; Xb:=pxx[ib]; if AX <= Xa then Ib:=Ia; if AX >= Xb then Ia:=Ib; if Ia = Ib then begin Result:=pyy[ia]; exit end; while abs(Ib-Ia) > 1 do begin Ic:=(Ia+Ib) div 2 ; Xc:=pxx[ic]; if AX < Xc then Ib:=Ic else Ia:=Ic end; x := pxx[ib]-pxx[ia]; if x=0 then Result := (pyy[ia]+pyy[ib])/2 else Result:=pyy[ia]+(pyy[ib]-pyy[ia])*(AX-pxx[ia])/x end; function LoadStrmString; var k : Integer; pc : array[0..255] of char; begin FS.ReadBuffer(k,SOfI); if (k>255) then k:= 255 else if k<0 then k:=0; FS.ReadBuffer(pc,k); pc[k]:=#0; {$IFDEF DEMO} DecodePChar(pc,k); {$ENDIF} result:=StrPas(pc); end; procedure SaveStrmString(var FS:TStream;S:String); var k : Integer; ch : array[0..255] of char; begin k:=Length(S); StrPLCopy(ch,S,k); {$IFDEF DEMO} //EncodePChar(ch,k); {$ELSE}{$IFDEF CONVRT} EncodePChar(ch,k); {$ENDIF}{$ENDIF} FS.WriteBuffer(k,SOfI); FS.WriteBuffer(ch,k); end; function GetFunctnValue(px1, px2: TExtArray; py: TExtArray2; ax, ay : RealType) : RealType; procedure find(ax:RealType;var Xa,Xb:RealType;var Ia,Ib:Integer;var aPx:array of RealType); var Ic,k : integer; begin k:=1; if aPx[Ia] > aPx[Ib] then begin Ic:=Ia; Ia:=Ib; Ib:=Ic; k:=-1; end; if (ax <= aPx[Ia]) then Ib:=Ia+k else if (ax >= aPx[Ib]) then Ia:=Ib-k; while abs(Ib-Ia) > 1 do begin Ic:=(Ia+Ib) div 2 ; if ax < aPx[ic] then Ib:=Ic else Ia:=Ic end; Xa:=aPx[Ia]; Xb:=aPx[Ib] end; var Ia1,Ib1, Ia2,Ib2 : Integer; a,b,c,d, x0,x1, y0,y1 : RealType; begin Ia1:=0; Ib1:=px1.Count-1; find(ax,x0,x1,Ia1,Ib1,Px1.arr^); Ia2:=0; Ib2:=px2.Count-1; find(ay,y0,y1,Ia2,Ib2,Px2.arr^); a:=Py.arr^[ia1].arr^[ia2]; if Ia2 = Ib2 then c:=0 else c:=(Py.arr^[ia1].arr^[ib2]-Py.arr^[ia1].arr^[ia2])/(y1-y0); if (Ia1 = Ib1)then d:=0 else d:=(Py.arr^[ib1].arr^[ib2]-Py.arr^[ib1].arr^[ia2]-c*(y1-y0))/((x1-x0)*(y1-y0)); if Ia1 = Ib1 then b:=0 else b:=(Py.arr^[ib1].arr^[ia2]-a)/(x1-x0); Result:=a+b*(ax-x0)+c*(ay-y0)+d*(ax-x0)*(ay-y0); end; {$IFDEF PHG} //------------------------------------------------------------------------------ // FOR PHG //Не используется procedure _GetTable2WorkRect(second:Integer;ax,ay:RealType;Px1:TExtArray;Px2:TIntArray;Data:PExtPtrArray2; var Ia1,Ib1,Ia2,Ib2,Ia3,Ib3:Integer; var x0,x1,y0,y1,y2,y3:RealType); procedure find(xx:RealType;var xx0,xx1:RealType;var Ia,Ib:Integer;aPx:PExtArr); var Xc : RealType; Ic : integer; begin if (xx <= aPx^[Ia]) then Ib:=1 else if (xx >= aPx^[Ib]) then Ia:=Ib-1; if aPx^[ia] > aPx^[ib] then begin Ic:=Ia; Ia:=Ib; Ib:=Ic; if (xx <= aPx^[Ia]) then Ib:=Ia-1 else if (xx >= aPx^[Ib]) then Ia:=1 end; while abs(Ib-Ia) > 1 do begin Ic:=(Ia+Ib) div 2 ; Xc:=aPx^[ic]; if xx < Xc then Ib:=Ic else Ia:=Ic end; xx0:=aPx^[Ia]; xx1:=aPx^[Ib] end; begin Ia1:=0; Ib1:=Px1.Count-1; find(ax,x0,x1,Ia1,Ib1,Px1.arr); Ia2:=0; Ib2:=Px2.arr^[ia1]-1; find(ay,y0,y1,Ia2,Ib2,Data^[ia1].arr^[second].arr); Ia3:=0; Ib3:=Px2.arr^[ib1]-1; find(ay,y2,y3,Ia3,Ib3,Data^[ib1].arr^[second].arr) end; //Не используется procedure _GetTable2Data(second:Integer;ax,ay:RealType;Px1:TExtArray;Px2:TIntArray; Data:PExtPtrArray2;var Y:array of RealType); var Ia1,Ib1 : Integer; Ia2,Ib2 : Integer; Ia3,Ib3 : Integer; x0,x1 : RealType; y0,y1 : RealType; y2,y3 : RealType; a,b,c,d : RealType; i : integer; begin _GetTable2WorkRect(second,ax,ay,Px1,Px2,Data,Ia1,Ib1,Ia2,Ib2,Ia3,Ib3,x0,x1,y0,y1,y2,y3); for i:=0 to Data^[0].CountX-1 do begin a:=Data^[ia1].arr^[i].arr^[ia2]; if Ia2 = Ib2 then c:=0 else c:=(Data^[ia1].arr^[i].arr^[ib2]-Data^[ia1].arr^[i].arr^[ia2])/(y1-y0); if (Ia1 = Ib1) or (Ia3 = Ib3) then d:=0 else d:=(Data^[ib1].arr^[i].arr^[ib3]-Data^[ib1].arr^[i].arr^[ia3]- c*(y3-y2))/((x1-x0)*(y3-y2)); if Ia1 = Ib1 then b:=0 else b:=(Data^[ib1].arr^[i].arr^[ia3]-a-(c+d*(x1-x0))*(y2-y0))/(x1-x0); Y[i]:=a+b*(ax-x0)+c*(ay-y0)+d*(ax-x0)*(ay-y0) end end; //------------------------------------------------------------------------------ function _GetTableSegment; var Ic : integer; begin Ia:=0; Ib:=Px.Count-1; if (ax <= Px.arr^[Ia]) then Ib:=Ia+1 else if (ax >= Px.arr^[Ib]) then Ia:=Ib-1; if Px.arr^[ia] > Px.arr^[ib] then begin Ic:=Ia; Ia:=Ib; Ib:=Ic; if (ax <= Px.arr^[Ia]) then Ib:=Ia-1 else if (ax >= Px.arr^[Ib]) then Ia:=Ib+1 end; while abs(Ib-Ia) > 1 do begin Ic:=(Ia+Ib) div 2; if ax < Px.arr^[ic] then Ib:=Ic else Ia:=Ic end; Result:=(ax-Px.arr^[ia])/(Px.arr^[ib]-Px.arr^[ia]) end; {$ENDIF} end.