(495) 925-0049, ITShop - 229-0436, 925-0049
 

 
 
 
 
 

Smart pointers Object Pascal Delphi 2009.

:

.

Smart pointers. . . , Object Pascal Delphi 2009. Delphi 2009 for Win32. , Delphi 2009, Object Pascal , , .

?

, , . , .

type

TSomeClass = class

private

// ................

protected

// ................

public

constructor Create;

destructor Destroy; override;

// ................

published

// ................

end;

// .......................

// .......................

implementation


procedure SomeProcedure({..- ....});

var

SomeClass: TSomeClass;

begin

// .

SomeClass:=TSomeClass.Create;

try

// .......................

// .......................

// .....- .....

// .......................

// ......................

finally

// .

SomeClass.Free;

end;

// .......................

// .......................

// .....- .....

// .......................

// .......................

end;

// .......................

// .......................

end.


: , . , .

SomeClass:=TSomeClass.Create;

SomeClass.Free;

. , : .

-: , , .

type

ISomeClass = interface(IInterface)

// ................

// ................

// ................

end;

TSomeClass = class( TIntefacedObject, ISomeClass)

private

// ................

protected

// ................

public

constructor Create;

destructor Destroy; override;

// ................

published

// ................

end;

implementation

// .......................

// .......................

procedure SomeProcedure({......});

var

SomeClass: ISomeClass;

begin

// .

SomeClass:=TSomeClass.Create;

try

// .......................

// .......................

// .....- .....

// .......................

// .......................

except

// .......................

// .......................

// .

// .......................

// .......................

end;

end;

// .......................

// .......................

end.

. , TIntefacedObject IInterface, TSomeClass - .

: TIntefacedObject ( ) . () , .

// .......................

// .......................

// .

SomeClass:=TSomeClass.Create;

// .......................

// .......................

// .....- .....

// .......................

, . . , "" Win32. Delphi for .Net .

" "

" " (Marco Cantu) Delphi 2009 [1].

, "". "" , (, ). 2- .

- TPointD2.

TPointD2 = packed record

strict private

FX,

FY: single;

private

function GetX: single;

procedure SetX( const Value: single);

function GetY: single;

procedure SetY( const Value: single);

public

procedure Empty;

function IsEmpty: boolean;

function Min( const PT: TPointD2): TPointD2;

function Max( const PT: TPointD2): TPointD2;

function Distance: single;

function Angle: single;

function Invert: TPointD2;

property X: single read GetX write SetX;

property Y: single read GetY write SetY;

end;

(X,Y) , .

  1. TPointD2

procedure Empty;

. "" .

function IsEmpty: boolean;

"".

function Min( const PT: TPointD2): TPointD2;

"" PT. TPointD2 .

function Max( const PT: TPointD2): TPointD2;

"" PT. TPointD2 .

function Distance: single;

.

function Angle: single;

.

Function Invert: TPointD2;

, : . , 180 ().

() 2- . , Delphi 2009 (generic) , uses Generics.Default Generics.Collections,

TPointsD2 = class(TList<TPointD2>)

public

destructor Destroy; override;

// GetComparer ,

// .

// class function GetComparer: TComparerPoint; virtual;

end;

TList. . , TPointsD2.

destructor TPointsD2.Destroy;

begin

ShowMessage(' TPointsD2!');

inherited Destroy;

end;

.

" " "" - TMultiPointD2:

? !

TMultiPointD2 = record

strict private

FValue: TPointsD2;

function GetValue: TPointsD2;

public

constructor Create( AValue: TPointsD2); overload;

property Value: TPointsD2 read GetValue;

end;

, (generics). , .

:

constructor TMultiPointD2.Create( AValue: TPointsD2);

begin

FValue:=AValue;

end;

function TMultiPointD2.GetValue: TPointsD2;

begin

Result:=FValue;

end;

.

Var

VPT: TPointsD2;

MPT: TMultiPointD2;

PT: TPointD2;

begin

//.........................

//.........................

//.........................

VPT:=TPointsD2.Create;

MPT.Create( VPT);

with PT do

begin

X:=0.1;

Y:=221.3;

end;

VPT.Add(PT);

MPT.Value.Add(PT);

//.........................

//.........................

//.........................

end;

, . , TPointsD2. . , ( FValue) MPT , nil .

" " , , , " " (, ). ? . IInterface.

, TMultiPointD2 IInterface. .

(. ).

type

TFreeTheValue = class(TInterfacedObject)

private

FObjectToFree: TObject;

public

constructor Create( AObjectToFree: TObject);

destructor Destroy; override;

end;

TFreeTheValue (. ). FObjectToFree . :

constructor TFreeTheValue.Create( AObjectToFree: TObject);

begin

FObjectToFree:=AObjectToFree;

End;

:

destructor TFreeTheValue.Destroy;

begin

FObjectToFree.Free; // !

inherited Destroy;

end;

TMultiPointD2 .

TMultiPointD2 = record

strict private

FValue: TPointsD2;

FFreeTheValue: IInterface;

function GetValue: TPointsD2;

private

type

TFreeTheValue = class (TInterfacedObject)

private

FObjectToFree: TObject;

public

constructor Create( AObjectToFree: TObject);

destructor Destroy; override;

end;

public

constructor Create( AValue: TPoints); overload;

property Value: T read GetValue;

end;

//.........................

//.........................

//.........................

, FFreeTheValue IInterface TFreeTheValue.

FFreeTheValue? TMultiPointD2. Delphi 2009 , .

constructor TMultiPointD2.Create( AValue: TPointsD2);

begin

FValue:=AValue;

FFreeTheValue:=TFreeTheValue.Create( FValue);

end;

.

unit TestMultiPoints;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Controls,

Dialogs,

Generics.Collections, Generics.Defaults, ExtCtrls;

type

TPointD2 = packed record

strict private

FX,

FY: single;

private

function GetX: single;

procedure SetX( const Value: single);

function GetY: single;

procedure SetY( const Value: single);

public

procedure Empty;

function IsEmpty: boolean;

function Min( const PT: TPointD2): TPointD2;

function Max( const PT: TPointD2): TPointD2;

function Distance: single;

function Angle: single;

function Invert: TPointD2;

property X: single read GetX write SetX;

property Y: single read GetY write SetY;

end;

TPointsD2 = class(TList<TPointD2>)

public

destructor Destroy; override;

// class function GetComparer: TComparerPoint; virtual;

end;

TMultiPointD2 = record

strict private

FValue: TPointsD2;

FFreeTheValue: IInterface;

function GetValue: TPointsD2;

private

type

TFreeTheValue = class (TInterfacedObject)

private

FObjectToFree: TObject;

public

constructor Create( AObjectToFree: TObject);

destructor Destroy; override;

end;

public

constructor Create( AValue: TPoints); overload;

property Value: TPointsD2 read GetValue;

end;

implementation

uses

Math;

//===========================================================================

// TPointD2.

function TPointD2.GetX: single;

begin

Result:=FX;

end;

procedure TPointD2.SetX( const Value: single);

begin

FX:=Value;

end;

function TPointD2.GetY: single;

begin

Result:=FY;

end;

procedure TPointD2.SetY( const Value: single);

begin

FY:=Value;

end;

procedure TPointD2.Empty;

begin

Self:=Default(TPointD2); // !!!! !

end;

function TPointD2.IsEmpty: boolean;

begin

Result:=false; // !!!! !

end;

function TPointD2.Min( const PT: TPointD2): TPointD2;

begin

Result.Empty;

if(Self.IsEmpty and (not PT.IsEmpty)) then

exit(PT);

if((not IsEmpty) and PT.IsEmpty) then

exit(Self);

if(not (Self.IsEmpty or PT.IsEmpty)) then

begin

Result.X:=Math.Min( X, PT.X);

Result.Y:=Math.Min( Y, PT.Y);

end;

end;

function TPointD2.Max( const PT: TPointD2): TPointD2;

begin

Result.Empty;

if(not (Self.IsEmpty or PT.IsEmpty)) then

begin

Result.X:=Math.Max( X, PT.X);

Result.Y:=Math.Max( Y, PT.Y);

end;

end;

function TPointD2.Distance: single;

begin

Result:=Sqr(X)+Sqr(Y);

end;

function ArcTg( X, Y: double): double;

begin

if(X = 0.0) then

begin

Result:=Pi/2.0;

if(Y < 0.0) then

Result:=-Result;

end

else

Result:=ArcTan2( Y, X);

end;

function TPointD2.Angle: single;

begin

Result:=ArcTg( X, Y);

end;

function TPointD2.Invert: TPointD2;

begin

Result.X:=-X;

Result.Y:=-Y;

end;

//===========================================================================

// TPointsD2.

destructor TPointsD2.Destroy;

begin

ShowMessage(' TPointsD2!');

inherited Destroy;

end;

//===========================================================================

// TMultiPointD2.

constructor TMultiPointD2.Create( AValue: TPoints);

begin

FValue:=AValue;

FFreeTheValue:=TFreeTheValue.Create( FValue);

end;

function TMultiPointD2.GetValue: TPointsD2;

begin

Result:=FValue;

end;

//===========================================================================

// TMultiPointD2.TFreeTheValue.

constructor TMultiPointD2.TFreeTheValue.Create( AObjectToFree: TObject);

begin

FObjectToFree:=AObjectToFree;

end;

destructor TMultiPointD2.TFreeTheValue.Destroy;

begin

FObjectToFree.Free;

inherited Destroy;

end;

end.

, . .

procedure TForm1.tbTestClick( Sender: TObject);

var

VPT: TPointsD2;

MPT: TMultiPointD2;

PT: TPointD2;

begin

VPT:=TPointsD2.Create;

MPT.Create( VPT);

with PT do

begin

X:=0.1;

Y:=221.3;

end;

VPT.Add(PT);

MPT.Value.Add(PT);

end;

, . TMultiPointD2 . VPT , ShowMessage VPT (TPointsD2).

. , . :

VPT:=TPointsD2.Create;

MPT.Create( VPT);

. ? , ! VPT " ". , .

GetValue :

function TMultiPointD2.GetValue: TPointsD2;

begin

if( not Assigned(FFreeTheValue)) then

Empty;

Result:=FValue;

end;

//.........................

if( not Assigned(FFreeTheValue)) then

Empty;

//.........................

FFreeTheValue . FFreeTheValue , , . Empty.

procedure TMultiPointD2.Empty();

begin

Create( TPointsD2.Create( nil));

end;

, " " :

procedure TForm1.tbTestClick( Sender: TObject);

var

// VPT: TPointsD2; // !

MPT: TMultiPointD2;

PT: TPointD2;

begin

// VPT:=TPointsD2.Create; // !

// MPT.Create( VPT); // !

with PT do

begin

X:=0.1;

Y:=221.3;

end;

// VPT.Add(PT); // !

MPT.Value.Add(PT);

with PT do

begin

X:=Random*100;

Y:=221.3*Random;

end;

MPT.Value.Add(PT);

End;

! ,

? :

//.........................

//.........................

MPT.Value.Add(PT);

//.........................

//.........................

MPT.Value.Add(PT);

//.........................

//.........................

! GetValue " ", : MPT.Value.Add(PT). ?

, :

  1. " ", GetValue .
  2. , Delphi 2007 , Implicit.

, :

procedure TMultiPointD2.Add( PT: TPointD2);

begin

if(not PT.IsEmpty) then

Value.Add( PT);

end;

procedure TMultiPointD2.Add( AValue: TMultiPointD2);

begin

Value.AddRange( AValue.Value);

end;

function TMultiPointD2.GetCount: integer;

begin

Result:=Value.Count;

end;

procedure TMultiPointD2.Clear;

begin

Value.Clear;

end;

:

class operator TMultiPointD2.Implicit( MPT: TMultiPointD2): TPointD2;

begin

Result:=MPT.Value;

end;

class operator TMultiPointD2.Implicit( MPT: TPointD2): TMultiPointD2;

begin

Result:=TMultiPointD2.Create(MPT);

end;

class operator TMultiPointD2.Implicit( PT: TPointD2): TMultiPointD2;

begin

Result.Clear();

Result.Add( PT);

end;

, :

procedure TForm1.tbTestClick( Sender: TObject);

var

MPT: TMultiPointD2;

PT: TPointD2;

begin

with PT do

begin

X:=0.1;

Y:=221.3;

end;

MPT.Add(PT);

for I:= 1 to 25 do

begin

with PT do

begin

X:=Random*100;

Y:=221.3*Random;

end;

MPT.Add(PT);

end;

for PT in MPT.Value do

Memo1.Lines.Add(format('(X:%e,Y:%e)',[PT.X, PT.Y]));

End;

TMultiPointD2.

, TMultiPointD2. . , .

. .

2- . :

:

procedure Delete( const AIndex: integer);

:

procedure TMultiPointD2.Delete( const AIndex: integer);

begin

Value.Delete( AIndex);

end;

:

procedure TForm1.tbTestDeleteClick( Sender: TObject);

var

MPT: TMultiPointD2<TPointsD2>;

PT: TPointD2;

begin

with PT do

begin

X:=0.1;

Y:=221.3;

end;

MPT.Add(PT);

for I:= 1 to 25 do

begin

with PT do

begin

X:=Random*100;

Y:=221.3*Random;

end;

MPT.Add(PT);

end;

for PT in MPT.Value do

Memo1.Lines.Add(format('(X:%e,Y:%e)',[PT.X, PT.Y]));

// .

MPT.Delete( 1);

end;

, :

,

Generics.Collections :

procedure TList<T>.DoDelete(Index: Integer; Notification: TCollectionNotification);

var

OldItem: T;

begin

if (Index < 0) or (Index >= Count) then

raise EArgumentOutOfRangeException.CreateRes(@sArgumentOutOfRange);

OldItem:=FItems[Index];

FItems[Index]:=Default(T); // - !

Dec(FCount);

if Index <> Count then

begin

Move(FItems[Index + 1], FItems[Index], (Count - Index) * SizeOf(T));

FillChar(FItems[Count], SizeOf(T), 0);

end;

Notify(oldItem, Notification);

end;

, . , Generics.Collections "" .

:

procedure TList<T>.DoDelete(Index: Integer; Notification: TCollectionNotification);

var

OldItem: T;

DefItem: T;

begin

if (Index < 0) or (Index >= Count) then

raise EArgumentOutOfRangeException.CreateRes(@sArgumentOutOfRange);

OldItem:=FItems[Index];

// ?!

// FItems[Index]:=Default(T);

// !

DefItem:=Default(T);

FItems[Index]:=DefItem;

//----------------

Dec(FCount);

if Index <> Count then

begin

Move(FItems[Index + 1], FItems[Index], (Count - Index) * SizeOf(T));

FillChar(FItems[Count], SizeOf(T), 0);

end;

Notify(oldItem, Notification);

end;

. .

TMultiPointD2 . .. :

procedure Remove( const AValue: TPointD2);

, TMultiPointD2 TPointD2. Generics.Default Generics.Collections TComparer<T>, function Compare( const Left, Right: T): integer; .

IComparer<T> = interface

function Compare(const Left, Right: T): Integer;

end;

IEqualityComparer<T> = interface

function Equals(const Left, Right: T): Boolean;

function GetHashCode(const Value: T): Integer;

end;

TComparison<T> = reference to function(const Left, Right: T): Integer;

// Abstract base class for IComparer<T> implementations, and a provider

// of default IComparer<T> implementations.

TComparer<T> = class(TInterfacedObject, IComparer<T>)

public

class function Default: IComparer<T>;

class function Construct(const Comparison: TComparison<T>): IComparer<T>;

function Compare(const Left, Right: T): Integer; virtual; abstract;

end;

, Generics.Default.

- TLinePointsComparer:

IComparerPoint = IComparer<TPointD2>;

TComparerPoint = class(TComparer<TPointD2>, IComparerPoint)

public

constructor Create;

end;

TLinePointsComparer = class(TComparerPoint)

public

function Compare( const Left, Right: TPointD2): integer; override;

end;

, - : PTA < PTB, PTA.X < PTB.X, PTA.X = PTB.X PTA.Y < PTB.Y. PTA.X = PTB.X PTA.Y = PTB.Y. :

function TLinePointsComparer.Compare( const Left, Right: TPointD2): integer;

begin

if(Abs(Left.X-Right.X)<=MinSingle) then

begin

if(Abs(Left.Y-Right.Y)<=MinSingle) then

Exit( +0);

if(Left.Y < Right.Y) then

Exit( -1);

if(Left.Y > Right.Y) then

Exit( +1);

end;

if(Left.X < Right.X) then

Exit( -1);

Exit( +1);

end;

, ?

TPointsD2. :

// class function GetComparer: TComparerPoint; virtual;

" " :

class function GetComparer: TComparerPoint; virtual;

//.........................

//.........................

class function TPointsD2.GetComparer: TComparerPoint;

begin

Result:=TLinePointsComparer.Create;

End;

? Empty TMultiPointD2 .

procedure TMultiPointD2.Empty();

begin

Create( TPointsD2.Create( nil));

end;

, TPointsD2 -. Empty :

procedure TMultiPointD2.Empty;

begin

Create( TPointsD2.Create( TLinePointsComparer.Create));

end;

procedure TMultiPointD2.Empty;

begin

Create( TPointsD2.Create( TPointsD2.GetComparer));

end;

, TMultiPointD2.

Remove

procedure TForm1.tbTestDeleteClick( Sender: TObject);

var

MPT: TMultiPointD2<TPointsD2>;

PT: TPointD2;

begin

with PT do

begin

X:=0.1;

Y:=221.3;

end;

MPT.Add(PT);

for I:= 1 to 25 do

begin

with PT do

begin

X:=Random*100;

Y:=221.3*Random;

end;

MPT.Add(PT);

end;

for PT in MPT.Value do

Memo1.Lines.Add(format('(X:%e,Y:%e)',[PT.X, PT.Y]));

// .

MPT.Remove(MPT.Value[3]);

end;

.

TMultiPointD2

. , :

function Equals( AValue: TMultiPointD2): boolean;

function IsEmpty: boolean;

function Min: TPointD2; overload;

function Max: TPointD2; overload;

function Min( MPT: TMultiPointD2): TPointD2; overload;

function Max( MPT: TMultiPointD2): TPointD2; overload;

procedure Offset( const PT: TPointD2);

class operator Implicit( MPT: TPointsD2): TMultiPointD2;

class operator Implicit( MPT: TMultiPointD2): TPointsD2;

class operator Implicit( PT: TPointD2): TMultiPointD2;

class operator Add( MPT: TMultiPointD2; PT: TPointD2): TMultiPointD2; overload;

class operator Add( PT: TPointD2; MPT: TMultiPointD2): TMultiPointD2; overload;

class operator Add( MPTA, MPTB: TMultiPointD2): TMultiPointD2; overload;

class operator Subtract( MPT: TMultiPointD2; PT: TPointD2): TMultiPointD2; overload;

class operator Subtract( MPTA, MPTB: TMultiPointD2): TMultiPointD2; overload;

class operator Multiply( PT: TPointD2; MPT: TMultiPointD2): TPointD2; overload;

class operator Multiply( MPT: TMultiPointD2; PT: TPointD2): TPointD2; overload;

class operator Multiply( MPTA, MPTB: TMultiPointD2): TMultiPointD2; overload;

class operator LessThan( PT: TPointD2; MPT: TMultiPointD2): boolean; overload;

class operator GreaterThan( MPT: TMultiPointD2; PT: TPointD2): boolean; overload;

class operator LessThanOrEqual( PT: TPointD2; MPT: TMultiPointD2): boolean; overload;

class operator GreaterThanOrEqual( MPT: TMultiPointD2; PT: TPointD2): boolean; overload;

  1. TMultiPointD2

function Equals( AValue: TMultiPointD2): boolean;

TPointD2.

function IsEmpty: boolean;

"".

function Min: TPointD2;

"" .

function Max: TPointD2;

""

function Min( MPT: TMultiPointD2): TPointD2;

"" MPT.

function Max( MPT: TMultiPointD2): TPointD2;

"" MPT.

class operator Add( MPT: TMultiPointD2; PT: TPointD2): TMultiPointD2

MPT MP. : X:=MPT+PT.

class operator Add( PT: TPointD2; MPT: TMultiPointD2): TMultiPointD2; overload;

MPT MP. : X:=PT+MPT.

class operator Add( MPTA, MPTB: TMultiPointD2): TMultiPointD2

MPTA MPTB . : X:=MPTA+MPTB.

class operator Subtract( MPT: TMultiPointD2; PT: TPointD2): TMultiPointD2;

MPT PT. : X:=MPT-PT.

class operator Subtract( MPTA, MPTB: TMultiPointD2): TMultiPointD2;

MPTA MPTB. : X:=MPTA-MPTB.

class operator Multiply( PT: TPointD2; MPT: TMultiPointD2): TPointD2;

PT MPT. PT MPT, PT; - . : X:=PT*MPT.

class operator Multiply( MPT: TMultiPointD2; PT: TPointD2): TPointD2;

. . : X:=MPT*PT.

class operator LessThan( PT: TPointD2; MPT: TMultiPointD2): boolean;

PT MPT. : B:=PT < MPT.

class operator GreaterThan( MPT: TMultiPointD2; PT: TPointD2): boolean;

PT MPT. : B:=MPT > PT.

class operator LessThanOrEqual( PT: TPointD2; MPT: TMultiPointD2): boolean;

PT MPT. : B:=PT <= MPT.

class operator GreaterThanOrEqual( MPT: TMultiPointD2; PT: TPointD2): boolean;

PT MPT. : B:=MPT >= PT.

(. ).

function TMultiPointD2.Equals( AValue: TMultiPointD2): boolean;

begin

Result:=Value.Equals( AValue.Value);

end;

class operator TMultiPointD2.Implicit( MPT: TMultiPointD2): TPointsD2;

begin

Result:=MPT.Value;

end;

class operator TMultiPointD2.Implicit( MPT: TPointsD2): TMultiPointD2;

begin

Result:=TMultiPointD2.Create(MPT);

end;

class operator TMultiPointD2.Implicit( PT: TPointD2): TMultiPointD2;

begin

Result.Add( PT);

end;

function TMultiPointD2.IsEmpty: boolean;

begin

Result:=(Count = 0);

end;

function TMultiPointD2.Min: TPointD2;

var

PT: TPointD2;

begin

Result.Empty;

if(not IsEmpty) then

begin

Result:=Self[0];

for PT in Value do

Result:=Result.Min( PT);

end;

end;

function TMultiPointD2.Min( const MPT: TMultiPointD2): TPointD2;

var

MPTA,

MPTB: TPointD2;

begin

MPTA:=Self.Min;

MPTB:=MPT.Min;

Result:=MPTA.Min( MPTB);

end;

function TMultiPointD2.Max: TPointD2;

var

PT: TPointD2;

begin

Result.Empty;

if(not IsEmpty) then

begin

Result:=Self[0];

for PT in Value do

Result:=Result.Max( PT);

end;

end;

function TMultiPointD2.Max( const MPT: TMultiPointD2): TPointD2;

var

MPTA,

MPTB: TPointD2;

begin

MPTA:=Self.Max;

MPTB:=MPT.Max;

Result:=MPTA.Max( MPTB);

end;

class operator TMultiPointD2.LessThan( const PT: TPointD2; const MPT: TMultiPointD2): boolean;

begin

Result:=(MPT.Value.IndexOf( PT) > -1);

end;

class operator TMultiPointD2.LessThanOrEqual( const PT: TPointD2; const MPT: TMultiPointD2): boolean;

begin

Result:=(PT < MPT);

end;

class operator TMultiPointD2.GreaterThan( const MPT: TMultiPointD2; const PT: TPointD2): boolean;

begin

Result:=(PT < MPT);

end;

class operator TMultiPointD2.GreaterThanOrEqual(const MPT: TMultiPointD2; const PT: TPointD2): boolean;

begin

Result:=(PT <= MPT);

end;

function TMultiPointD2.Copy: TMultiPointD2;

begin

if(not Result.Equals( Self)) then

begin

Result.Clear;

Result.Add(Self);

end;

end;

procedure TMultiPointD2.Add( const PT: TPointD2);

begin

if(not PT.IsEmpty) then

Value.Add( PT);

end;

procedure TMultiPointD2.Add( const AValue: TMultiPointD2);

begin

Value.AddRange( AValue.Value);

end;

function TMultiPointD2.GetCount: integer;

begin

Result:=Value.Count;

end;

class operator TMultiPointD2.Add( const MPT: TMultiPointD2; const PT: TPointD2): TMultiPointD2;

begin

if(not Result.Equals( MPT)) then // X:=A+PT

begin

Result.Clear;

Result.Value.AddRange(MPT);

end;

Result.Add(PT);

end;

class operator TMultiPointD2.Add( const PT: TPointD2; const MPT: TMultiPointD2): TMultiPointD2;

begin

if(not Result.Equals( MPT)) then // X:=PT+A;

Result.Clear;

Result.Value.Insert( 0, PT);

if(not Result.Equals( MPT)) then // not A:=PT+A;

Result.Value.AddRange(MPT);

end;

class operator TMultiPointD2.Add( const MPTA, MPTB: TMultiPointD2): TMultiPointD2;

begin

if(Result.Equals( MPTA)) then

begin

if(not Result.Equals( MPTB)) then // A:=A+B.

// A:=A+A ! !

Result.Value.AddRange(MPTB)

end

else if(Result.Equals( MPTB)) then // B:=A+B.

Result.Value.InsertRange( 0, MPTA)

else

begin // X:=A+B.

Result.Clear;

Result.Value.AddRange(MPTA);

Result.Value.AddRange(MPTB);

end;

end;

class operator TMultiPointD2.Subtract( const MPT: TMultiPointD2; const PT: TPointD2): TMultiPointD2;

begin

if(not Result.Equals( MPT)) then // X:=A-PT.

begin

Result.Clear;

Result.Value.AddRange( MPT);

end;

Result.Delete(PT); // X:=A-PT A:=A-PT.

end;

class operator TMultiPointD2.Subtract( const MPTA, MPTB: TMultiPointD2): TMultiPointD2;

var

PT: TPointD2;

VP: TMultiPointD2;

begin

if(Result.Equals( MPTA)) then

begin

if(not Result.Equals( MPTB)) then // A:=A-B.

begin

for PT in MPTB.Value do

Result.Delete( PT);

end;

end

else if(Result.Equals( MPTB)) then // B:=A-B.

begin

VP:=MPTA.Copy();

VP:=VP - MPTB;

Result:=VP.Copy();

end

else

begin // X:=A-B.

Result:=MPTA.Copy();

for PT in MPTB.Value do

Result.Delete( PT);

end;

end;

class operator TMultiPointD2.Multiply( const PT: TPointD2; const MPT: TMultiPointD2): TPointD2;

begin

Result.Empty;

if((not (PT.IsEmpty or MPT.IsEmpty)) and (PT < MPT)) then

Result:=PT;

end;

class operator TMultiPointD2.Multiply( const MPT: TMultiPointD2; const PT: TPointD2): TPointD2;

begin

Result:=PT*MPT;

end;

class operator TMultiPointD2.Multiply( const MPTA, MPTB: TMultiPointD2): TMultiPointD2;

var

PT: TPointD2;

begin

Result.Empty;

for PT in MPTA.Value do

Result.Add(PT*MPTB);

end;

. . - . , .

, , , . - .. .. . , , generic , .

, , , , . , () TMultiPointD2 TPointD2. - -. - " " . .

?

, "" TMultiPointD2 "" TPolygonD2 ( 2- , , , ). - . , " ", .

, "" TPolygonD2 "", (2- ). , , , , : "" . .., - " " -, , .

. . , , - ? , : ( ) () () , , - . .

, Generics.Collections -, - TList<T> . - , , procedure Sort(const AComparer: IComparer<T>). TList<T> . - , , .

, : -. : (" "), .

? -, , . -, TMultiPointD2 - .

: TMultiPointD2 ( ) - " " .

:

  1. -:

IComparerPoint = IComparer<TPointD2>;

TComparerPoint = class(TComparer<TPointD2>, IComparerPoint)

public

constructor Create;

end;

TClassComparerPoint = class of TComparerPoint;

TLinePointsComparer = class(TComparerPoint)

public

function Compare( const Left, Right: TPointD2): integer; override;

end;

TClassLinePointsComparer = class of TLinePointsComparer;

TPolygonPointsComparer = class(TComparerPoint)

public

function Compare( const Left, Right: TPointD2): integer; override;

end;

TClassPolygonPointsComparer = class of TPolygonPointsComparer;

function TPolygonPointsComparer.Compare( const Left, Right: TPointD2): integer;

var

AL, AR: single;

DL, DR: single;

begin

AL:=Left.Angle;

AR:=Right.Angle;

if(Abs(AL-AR) <= MinSingle) then

begin

DL:=Left.Distance;

DR:=Right.Distance;

if(Abs(DL-DR) <= MinSingle) then

exit(+0);

if(DL < DR) then

exit(-1)

else

exit(+1);

end;

if(AL < AR) then

exit(-1);

exit(+1);

end;

  1. :

TMultiPointD2 = record

strict private

//........................................

//........................................

FValue: TPointsD2;

FFreeTheValue: IInterface;

FComparer: TClassComparerPoint;

//........................................

public

//........................................

//........................................

property Comparer: TClassComparerPoint read FComparer write FComparer;

end;

  1. Empty:

procedure TMultiPointD2.Empty;

begin

Create( TPointsD2.Create( FComparer.Create));

end;

  1. . :

procedure TForm4.Button7Click(Sender: TObject);

var

I: integer;

MPTR: TMultiPointD2; // ""

MPTP: TMultiPointD2; // "".

PT: TPointD2;

PTB: TPointD2;

PTC: TPointD2;

begin

// .

MPTR.Comparer:=TLinePointsComparer;

// "" .

MPTP.Comparer:=TPolygonPointsComparer;

for I:= 1 to 25 do

begin

PT.X:=100.0*Random;

PT.Y:=100.0*Random;

MPTR.Add( PT);

end;

MPTP:=MPTR.Copy;

Memo1.Lines.Add(' : .');

for PT in MPTR.Value do

Memo1.Lines.Add(format('(X:%e, Y:%e)',[PT.X, PT.Y]));

Memo1.Lines.Add(' : .');

for PT in MPTP.Value do

Memo1.Lines.Add(format('(X:%e, Y:%e)',[PT.X, PT.Y]));

//================================.

// "".

MPTR.Value.Sort;

//================================.

// "".

PTC:=MPTP.Center;

PTB:=PTC.Invert;

MPTP.Offset(PTB);

MPTP.Value.Sort;

MPTP.Offset(PTC);

//================================.

Memo1.Lines.Add('' : .');

for PT in MPTR.Value do

Memo1.Lines.Add(format('(X:%e, Y:%e)',[PT.X, PT.Y]));

Memo1.Lines.Add(' : .');

for PT in MPTP.Value do

Memo1.Lines.Add(format('(X:%e, Y:%e)',[PT.X, PT.Y]));

end;

:

  1. .

(X:2,328306E-008, Y:3,137994E+000)

(X:2,328306E-008, Y:3,137994E+000)

(X:8,610484E+001, Y:2,025809E+001)

(X:8,610484E+001, Y:2,025809E+001)

(X:2,729212E+001, Y:6,716544E+001)

(X:2,729212E+001, Y:6,716544E+001)

(X:3,186912E+001, Y:1,617954E+001)

(X:3,186912E+001, Y:1,617954E+001)

(X:3,722383E+001, Y:4,256737E+001)

(X:3,722383E+001, Y:4,256737E+001)

(X:8,201215E+000, Y:4,747940E+001)

(X:8,201215E+000, Y:4,747940E+001)

(X:7,056932E+000, Y:8,408544E+001)

(X:7,056932E+000, Y:8,408544E+001)

(X:5,972423E+000, Y:2,932965E+001)

(X:5,972423E+000, Y:2,932965E+001)

(X:9,172846E+001, Y:3,679064E+001)

(X:9,172846E+001, Y:3,679064E+001)

(X:7,746649E+001, Y:3,279255E+001)

(X:7,746649E+001, Y:3,279255E+001)

(X:6,976749E+001, Y:8,441709E+001)

(X:6,976749E+001, Y:8,441709E+001)

(X:7,179828E+001, Y:3,066413E+001)

(X:7,179828E+001, Y:3,066413E+001)

(X:1,626258E+001, Y:3,294964E+001)

(X:1,626258E+001, Y:3,294964E+001)

(X:4,660204E+001, Y:2,466536E+001)

(X:4,660204E+001, Y:2,466536E+001)

(X:8,256764E+001, Y:2,790294E+001)

(X:8,256764E+001, Y:2,790294E+001)

(X:4,817663E+001, Y:1,491849E+001)

(X:4,817663E+001, Y:1,491849E+001)

(X:8,743350E+001, Y:2,872941E+001)

(X:8,743350E+001, Y:2,872941E+001)

(X:7,727532E+001, Y:9,764598E+001)

(X:7,727532E+001, Y:9,764598E+001)

(X:4,925279E+001, Y:8,879360E+001)

(X:4,925279E+001, Y:8,879360E+001)

(X:8,272766E+001, Y:2,029689E+000)

(X:8,272766E+001, Y:2,029689E+000)

(X:1,410562E+001, Y:1,435042E+001)

(X:1,410562E+001, Y:1,435042E+001)

(X:5,008077E+001, Y:2,167585E+000)

(X:5,008077E+001, Y:2,167585E+000)

(X:5,929344E+001, Y:9,648999E-001)

(X:5,929344E+001, Y:9,648999E-001)

(X:7,744779E+001, Y:6,506576E+001)

(X:7,744779E+001, Y:6,506576E+001)

(X:7,704886E+001, Y:7,081069E+001)

(X:7,704886E+001, Y:7,081069E+001)

(X:2,328306E-008, Y:3,137994E+000)

(X:1,626258E+001, Y:3,294964E+001)

(X:5,972423E+000, Y:2,932965E+001)

(X:5,972423E+000, Y:2,932965E+001)

(X:7,056932E+000, Y:8,408544E+001)

(X:1,410562E+001, Y:1,435042E+001)

(X:8,201215E+000, Y:4,747940E+001)

(X:0,000000E+000, Y:3,137992E+000)

(X:1,410562E+001, Y:1,435042E+001)

(X:3,186912E+001, Y:1,617954E+001)

(X:1,626258E+001, Y:3,294964E+001)

(X:4,660204E+001, Y:2,466536E+001)

(X:2,729212E+001, Y:6,716544E+001)

(X:4,817663E+001, Y:1,491849E+001)

(X:3,186912E+001, Y:1,617954E+001)

(X:5,008077E+001, Y:2,167583E+000)

(X:3,722383E+001, Y:4,256737E+001)

(X:5,929344E+001, Y:9,649009E-001)

(X:4,660204E+001, Y:2,466536E+001)

(X:8,272766E+001, Y:2,029689E+000)

(X:4,817663E+001, Y:1,491849E+001)

(X:8,610484E+001, Y:2,025809E+001)

(X:4,925279E+001, Y:8,879360E+001)

(X:7,179828E+001, Y:3,066413E+001)

(X:5,008077E+001, Y:2,167585E+000)

(X:8,256764E+001, Y:2,790294E+001)

(X:5,929344E+001, Y:9,648999E-001)

(X:8,743350E+001, Y:2,872941E+001)

(X:6,976749E+001, Y:8,441709E+001)

(X:7,746649E+001, Y:3,279255E+001)

(X:7,179828E+001, Y:3,066413E+001)

(X:9,172846E+001, Y:3,679064E+001)

(X:7,704886E+001, Y:7,081069E+001)

(X:7,744779E+001, Y:6,506576E+001)

(X:7,727532E+001, Y:9,764598E+001)

(X:7,704886E+001, Y:7,081069E+001)

(X:7,744779E+001, Y:6,506576E+001)

(X:7,727532E+001, Y:9,764598E+001)

(X:7,746649E+001, Y:3,279255E+001)

(X:6,976749E+001, Y:8,441709E+001)

(X:8,256764E+001, Y:2,790294E+001)

(X:4,925279E+001, Y:8,879360E+001)

(X:8,272766E+001, Y:2,029689E+000)

(X:2,729212E+001, Y:6,716544E+001)

(X:8,610484E+001, Y:2,025809E+001)

(X:7,056934E+000, Y:8,408544E+001)

(X:8,743350E+001, Y:2,872941E+001)

(X:3,722383E+001, Y:4,256737E+001)

(X:9,172846E+001, Y:3,679064E+001)

(X:8,201213E+000, Y:4,747940E+001)

: procedure TMultiPointD2.Offset( const PT: TPointD2) (. ).

procedure TMultiPointD2.Offset( const PT: TPointD2);

var

PTA,

PTB: TPointD2;

MPT: TMultiPointD2;

begin

MPT.Comparer:=Comparer; // !

for PTA in Value do

begin

PTB.X:=PTA.X+PT.X;

PTB.Y:=PTA.Y+PT.Y;

MPT.Add(PTB);

end;

Self.Clear;

Self.Add(MPT);

end;

, " ".

, Empty:

procedure TMultiPointD2.Empty;

begin

if(not Assigned(FComparer)) then

FComparer:=TLinePointsComparer; // !

Create( TPointsD2.Create( FComparer.Create));

end;

? , FComparer nil ( ).

:

procedure TMultiPointD2.Empty;

begin

if( FComparer <> Default(TClassComparerPoint)) then

FComparer:=TLinePointsComparer;

Create( TPointsD2.Create( FComparer.Create));

end;

...

-

, , TList<TPointD2>, "". , " " "" . .

1. ,

TPointsD2 = class(TList<TPointD2>)

public

// .

function Empty: TPointsD2; virtual;

destructor Destroy; override;

function IsEmpty: boolean;

procedure Sort; virtual;

procedure Add( const Value: TPointD2); virtual;

procedure Offset( const PT: TPointD2); virtual;

function Center: TPointD2;

end;

TPolygonPointsD2 = class(TPointsD2)

public

function Empty: TPointsD2; override;

destructor Destroy; override;

procedure Sort; override;

procedure Add( const Value: TPointD2); override;

end;

2. :

// TPointsD2.

function TPointsD2.Empty: TPointsD2;

begin

Result:=TPointsD2.Create( TLinePointsComparer.Create);

end;

function TPointsD2.IsEmpty: boolean;

begin

Result:=(Count = 0);

end;

destructor TPointsD2.Destroy;

begin

inherited Destroy;

end;

function TPointsD2.Center: TPointD2;

var

PT: TPointD2;

begin

Result.Empty;

if(not IsEmpty) then

begin

Result.X:=0.0;

Result.Y:=0.0;

for PT in Self do

begin

Result.X:=Result.X+PT.X;

Result.Y:=Result.Y+PT.Y;

end;

Result.X:=Result.X/Count;

Result.Y:=Result.Y/Count;

end;

end;

procedure TPointsD2.Offset( const PT: TPointD2);

var

TPT: TPointD2;

begin

for TPT in Self do

begin

TPT.X:=TPT.X+PT.X;

TPT.Y:=TPT.Y+PT.Y;

end;

end;

procedure TPointsD2.Sort;

begin

inherited Sort;

end;

procedure TPointsD2.Add( const Value: TPointD2);

begin

inherited Add( Value);

end;

//================================================================

// TPolygonPointsD2.

function TPolygonPointsD2.Empty: TPointsD2;

begin

Result:=TPointsD2.Create( TPolygonPointsComparer.Create);

end;

destructor TPolygonPointsD2.Destroy;

begin

inherited Destroy;

end;

procedure TPolygonPointsD2.Sort;

var

PTB: TPointD2;

PTC: TPointD2;

begin

PTC:=Center;

PTB:=PTC.Invert;

Offset( PTB);

inherited Sort;

Offset(PTC);

end;

procedure TPolygonPointsD2.Add( const Value: TPointD2);

begin

inherited Add( Value);

// !

Sort;

end;

3. " ":

  1. TMultiPointD2<TPoints: TPointsD2>

TMultiPointD2<TPoints: TPointsD2> = record

strict private

FValue: TPointsD2;

FFreeTheValue: IInterface;

function GetValue: TPointsD2;

private

type

TFreeTheValue = class (TInterfacedObject)

private

FObjectToFree: TObject;

public

constructor Create( AObjectToFree: TObject);

destructor Destroy; override;

end;

private

function GetCount: integer;

function GetPoint( const Index: integer): TPointD2;

procedure SetPoint( const Index: integer; const AValue: TPointD2);

public

constructor Create( AValue: TPointsD2); overload;

procedure Empty; overload;

function IsEmpty: boolean;

function Equals( AValue: TMultiPointD2<TPoints>): boolean;

procedure Clear;

procedure Add( const PT: TPointD2); overload;

procedure Add( const AValue: TMultiPointD2<TPoints>); overload;

function Copy: TMultiPointD2<TPoints>;

procedure Delete( const AValue: TPointD2);

procedure Remove( const AValue: TPointD2);

function Min: TPointD2; overload;

function Max: TPointD2; overload;

function Min( const MPT: TMultiPointD2<TPoints>): TPointD2; overload;

function Max( const MPT: TMultiPointD2<TPoints>): TPointD2; overload;

procedure Offset( const PT: TPointD2);

class operator Implicit( const MPT: TPointsD2): TMultiPointD2<TPoints>;

class operator Implicit( const MPT: TMultiPointD2<TPoints>): TPointsD2;

class operator Implicit( const PT: TPointD2): TMultiPointD2<TPoints>;

class operator Add( const MPT: TMultiPointD2<TPoints>; const PT: TPointD2): TMultiPointD2<TPoints>; overload;

class operator Add( const PT: TPointD2; const MPT: TMultiPointD2<TPoints>): TMultiPointD2<TPoints>; overload;

class operator Add( const MPTA, MPTB: TMultiPointD2<TPoints>): TMultiPointD2<TPoints>; overload;

class operator Subtract( const MPT: TMultiPointD2<TPoints>; const PT: TPointD2): TMultiPointD2<TPoints>; overload;

class operator Subtract( const MPTA, MPTB: TMultiPointD2<TPoints>): TMultiPointD2<TPoints>; overload;

class operator Multiply( const PT: TPointD2; const MPT: TMultiPointD2<TPoints>): TPointD2; overload;

class operator Multiply( const MPT: TMultiPointD2<TPoints>; const PT: TPointD2): TPointD2; overload;

class operator Multiply( const MPTA, MPTB: TMultiPointD2<TPoints>): TMultiPointD2<TPoints>; overload;

class operator LessThan( const PT: TPointD2; const MPT: TMultiPointD2<TPoints>): boolean; overload;

class operator GreaterThan( const MPT: TMultiPointD2<TPoints>; const PT: TPointD2): boolean; overload;

class operator LessThanOrEqual( const PT: TPointD2; const MPT: TMultiPointD2<TPoints>): boolean; overload;

class operator GreaterThanOrEqual( const MPT: TMultiPointD2<TPoints>; const PT: TPointD2): boolean; overload;

function Center: TPointD2;

property Value: TPointsD2 read GetValue;

property Count: integer read GetCount;

property Points[ const Index: integer]: TPointD2 read GetPoint write SetPoint; default;

property Comparer: TClassComparerPoint read FComparer write FComparer;

end;

4. TMultiPointD2<TPoints: TPointsD2>:

  1. TMultiPointD2<TPoints: TPointsD2>

constructor TMultiPointD2<TPoints>.Create( AValue: TPointsD2);

begin

FValue:=AValue;

FFreeTheValue:=TFreeTheValue.Create( FValue);

end;

procedure TMultiPointD2<TPoints>.Empty;

begin

Create( TPoints.Empty);

end;

function TMultiPointD2<TPoints>.IsEmpty: boolean;

begin

Result:=(Count = 0);

end;

function TMultiPointD2<TPoints>.Center: TPointD2;

var

PT: TPointD2;

begin

Result.Empty;

if(not IsEmpty) then

begin

Result.X:=0.0;

Result.Y:=0.0;

for PT in Value do

begin

Result.X:=Result.X+PT.X;

Result.Y:=Result.Y+PT.Y;

end;

Result.X:=Result.X/Count;

Result.Y:=Result.Y/Count;

end;

end;

procedure TMultiPointD2<TPoints>.Clear;

begin

Value.Clear;

end;

function TMultiPointD2<TPoints>.GetValue: TPointsD2;

begin

if( not Assigned(FFreeTheValue)) then

Empty;

Result:=FValue;

end;

function TMultiPointD2<TPoints>.GetCount: integer;

begin

Result:=Value.Count;

end;

function TMultiPointD2<TPoints>.GetPoint( const Index: integer): TPointD2;

begin

Result:=Self.Value[ Index];

end;

procedure TMultiPointD2<TPoints>.SetPoint( const Index: integer; const AValue: TPointD2);

begin

Self.Value[ Index]:=AValue;

end;

function TMultiPointD2<TPoints>.Equals( AValue: TMultiPointD2<TPoints>): boolean;

begin

Result:=Value.Equals( AValue.Value);

end;

function TMultiPointD2<TPoints>.Min: TPointD2;

var

PT: TPointD2;

begin

Result.Empty;

if(not IsEmpty) then

begin

Result:=Self[0];

for PT in Value do

Result:=Result.Min( PT);

end;

end;

function TMultiPointD2<TPoints>.Max: TPointD2;

var

PT: TPointD2;

begin

Result.Empty;

if(not IsEmpty) then

begin

Result:=Self[0];

for PT in Value do

Result:=Result.Max( PT);

end;

end;

function TMultiPointD2<TPoints>.Min( const MPT: TMultiPointD2<TPoints>): TPointD2;

var

MPTA,

MPTB: TPointD2;

begin

MPTA:=Self.Min;

MPTB:=MPT.Min;

Result:=MPTA.Min( MPTB);

end;

function TMultiPointD2<TPoints>.Max( const MPT: TMultiPointD2<TPoints>): TPointD2;

var

MPTA,

MPTB: TPointD2;

begin

MPTA:=Max;

MPTB:=MPT.Max;

Result:=MPTA.Max( MPTB);

end;

class operator TMultiPointD2<TPoints>.Implicit( const MPT: TMultiPointD2<TPoints>): TPointsD2;

begin

Result:=MPT.Value;

end;

class operator TMultiPointD2<TPoints>.Implicit( const MPT: TPointsD2): TMultiPointD2<TPoints>;

begin

Result:=TMultiPointD2<TPoints>.Create(MPT);

end;

class operator TMultiPointD2<TPoints>.Implicit( const PT: TPointD2): TMultiPointD2<TPoints>;

begin

Result.Add( PT);

end;

class operator TMultiPointD2<TPoints>.LessThan( const PT: TPointD2; const MPT: TMultiPointD2<TPoints>): boolean;

begin

Result:=(MPT.Value.IndexOf( PT) > -1);

end;

class operator TMultiPointD2<TPoints>.LessThanOrEqual( const PT: TPointD2; const MPT: TMultiPointD2<TPoints>): boolean;

begin

Result:=(PT < MPT);

end;

class operator TMultiPointD2<TPoints>.GreaterThan( const MPT: TMultiPointD2<TPoints>; const PT: TPointD2): boolean;

begin

Result:=(PT < MPT);

end;

class operator TMultiPointD2<TPoints>.GreaterThanOrEqual( const MPT: TMultiPointD2<TPoints>; const PT: TPointD2): boolean;

begin

Result:=(PT <= MPT);

end;

function TMultiPointD2<TPoints>.Copy: TMultiPointD2<TPoints>;

begin

if(not Result.Equals( Self)) then

begin

Result.Clear;

Result.Add(Self);

end;

end;

procedure TMultiPointD2<TPoints>.Add( const PT: TPointD2);

begin

if(not PT.IsEmpty) then

Value.Add( PT);

end;

procedure TMultiPointD2<TPoints>.Add( const AValue: TMultiPointD2<TPoints>);

begin

Value.AddRange( AValue.Value);

end;

class operator TMultiPointD2<TPoints>.Add( const MPT: TMultiPointD2<TPoints>; const PT: TPointD2): TMultiPointD2<TPoints>;

begin

if(not Result.Equals( MPT)) then // X:=A+PT

begin

Result.Clear;

Result.Add(MPT);

end;

Result.Add(PT);

end;

class operator TMultiPointD2<TPoints>.Add( const PT: TPointD2; const MPT: TMultiPointD2<TPoints>): TMultiPointD2<TPoints>;

begin

if(not Result.Equals( MPT)) then // X:=PT+A;

Result.Clear;

Result.Value.Insert( 0, PT);

if(not Result.Equals( MPT)) then // not A:=PT+A;

Result.Add(MPT);

end;

class operator TMultiPointD2<TPoints>.Add( const MPTA, MPTB: TMultiPointD2<TPoints>): TMultiPointD2<TPoints>;

begin

if(Result.Equals( MPTA)) then

begin

if(not Result.Equals( MPTB)) then // A:=A+B.

// A:=A+A ! !

Result.Add(MPTB)

end

else if(Result.Equals( MPTB)) then // B:=A+B.

Result.Value.InsertRange( 0, MPTA.Value)

else

begin // X:=A+B.

Result.Clear;

Result.Add(MPTA);

Result.Add(MPTB);

end;

end;

class operator TMultiPointD2<TPoints>.Subtract( const MPT: TMultiPointD2<TPoints>; const PT: TPointD2): TMultiPointD2<TPoints>;

begin

if(not Result.Equals( MPT)) then // X:=A-PT.

begin

Result.Clear;

Result.Add( MPT);

end;

Result.Delete(PT); // X:=A-PT A:=A-PT.

end;

class operator TMultiPointD2<TPoints>.Subtract( const MPTA, MPTB: TMultiPointD2<TPoints>): TMultiPointD2<TPoints>;

var

PT: TPointD2;

VP: TMultiPointD2<TPoints>;

begin

if(Result.Equals( MPTA)) then

begin

if(not Result.Equals( MPTB)) then // A:=A-B.

begin

for PT in MPTB.Value do

Result.Delete( PT);

end;

end

else if(Result.Equals( MPTB)) then // B:=A-B.

begin

VP:=MPTA.Copy();

VP:=VP - MPTB;

Result:=VP.Copy();

end

else

begin // X:=A-B.

Result:=MPTA.Copy();

for PT in MPTB.Value do

Result.Delete( PT);

end;

end;

class operator TMultiPointD2<TPoints>.Multiply( const PT: TPointD2; const MPT: TMultiPointD2<TPoints>): TPointD2;

begin

Result.Empty;

if((not (PT.IsEmpty or MPT.IsEmpty)) and (PT < MPT)) then

Result:=PT;

end;

class operator TMultiPointD2<TPoints>.Multiply( const MPT: TMultiPointD2<TPoints>; const PT: TPointD2): TPointD2;

begin

Result:=PT*MPT;

end;

class operator TMultiPointD2<TPoints>.Multiply( const MPTA, MPTB: TMultiPointD2<TPoints>): TMultiPointD2<TPoints>;

var

PT: TPointD2;

begin

Result.Empty;

if(not (MPTA.IsEmpty or MPTB.IsEmpty)) then

begin

for PT in MPTA.Value do

begin

if((not PT.IsEmpty) and (PT < MPTB)) then

Result.Add(PT);

end;

end;

end;

procedure TMultiPointD2<TPoints>.Delete( const AValue: TPointD2);

begin

Value.Remove( AValue);

end;

procedure TMultiPointD2<TPoints>.Remove( const AValue: TPointD2);

begin

Value.Remove( AValue);

end;

// TPointsD2.TFreeTheValue.

constructor TMultiPointD2<TPoints>.TFreeTheValue.Create( AObjectToFree: TObject);

begin

FObjectToFree:=AObjectToFree;

end;

destructor TMultiPointD2.TFreeTheValue.Destroy;

begin

FObjectToFree.Free;

inherited Destroy;

end;

, :

  1. E2037 Declaration of " " differs from previous declaration

. . "" : const . (. 4).

. ,

class operator TMultiPointD2<TPoints>.LessThanOrEqual( PT: TPointD2; MPT: TMultiPointD2<TPoints>): boolean;

begin

Result:=(PT < MPT);

end;

  1. E2015 Operator not applicable to this operand type.

:

class operator TMultiPointD2<TPoints>.LessThanOrEqual( PT: TPointD2; MPT: TMultiPointD2<TPoints>): boolean;

begin

Result:=(MPT.Value.IndexOf( PT) > -1);

end;

5. . :

  1. .

procedure TForm4.Button7Click(Sender: TObject);

var

I: integer;

MPTR: TMultiPointD2; // ""

MPTP: TMultiPointD2; // "".

PT: TPointD2;

PTB: TPointD2;

PTC: TPointD2;

begin

for I:= 1 to 25 do

begin

PT.X:=100.0*Random;

PT.Y:=100.0*Random;

MPTR.Add( PT);

end;

MPTP:=MPTR.Copy;

Memo1.Lines.Add(' : .');

for PT in MPTR.Value do

Memo1.Lines.Add(format('(X:%e, Y:%e)',[PT.X, PT.Y]));

Memo1.Lines.Add(' : .');

for PT in MPTP.Value do

Memo1.Lines.Add(format('(X:%e, Y:%e)',[PT.X, PT.Y]));

//================================.

// "".

MPTR.Value.Sort;

//================================.

// "".

MPTP.Value.Sort;

//================================.

Memo1.Lines.Add('' : .');

for PT in MPTR.Value do

Memo1.Lines.Add(format('(X:%e, Y:%e)',[PT.X, PT.Y]));

Memo1.Lines.Add(' : .');

for PT in MPTP.Value do

Memo1.Lines.Add(format('(X:%e, Y:%e)',[PT.X, PT.Y]));

end;

  1. .

//........................................

//........................................

MPTP:=MPTR.Copy;

//........................................

//........................................

, Copy:

  1. Copy.

procedure TPointsD2.Copy( AValue: TPointsD2);

var

PT: TPointD2;

begin

AValue.Clear;

for PT in Self do

AValue.Add( PT);

end;

:

  1. Copy.

//........................................

//........................................

MPTR.Value.Copy( MPTP.Value);

//........................................

//........................................

" " . , .

, - ! ?! : "---". ????!

smart pointers Delphi 2009. , , .

, "smart pointers" . , "smart pointers" .

, , . , . Delphi -


1. Cantu M. Delphi 2009. Handbook. pp. 171-176.

2. Cantu M. Delphi 2007. Handbook.

3. Kelly B. Smart pointers in Delphi. - http://blog.barrkel.com/2008/09/smart-pointers-in-delphi.html



  »
   »
   Embarcadero »
 
  » : 28.09.2009 
 

   WWW.ITSHOP.RU
Delphi Professional Named User
Enterprise Connectors (1 Year term)
IBM RATIONAL Quality Manager Quality Professional Authorized User Single Install License + Sw Subscription & Support 12 Months
EMS SQL Management Studio for PostgreSQL (Business) + 1 Year Maintenance
GFI LanGuard 1 (25-49 )
 
...
 
   WWW.ITSHOP.RU
 
...
 
   WWW.ITSHOP.RU
 
...
 
3D | 3D    WWW.ITSHOP.RU
 
...
 
 
 Subscribe.ru
: CASE, RAD, ERP, OLAP
ITShop.ru - , , ,
Microsoft Access
CASE-
Oracle " "
AutoCAD
: , ,
 
 
Download
 
 
 
(73)
, , ...
 
2021 (12)
, , ...
 
? (9)
2021 https://casino2021.net/ , ...
 
2021 (5)
...
 
(6)
Pragmatic Play...
 
 
 



    
rambler's top100 Rambler's Top100