向量定義筆記

雲水浮萍發表於2015-04-01
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TVerctor = record
    X,Y,Z:Pointer;
    VerctorType :(vtInteger,vtDouble);
  public
     class operator Equal(const Left,Right:TVerctor): Boolean;
  end;

  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

{ TVerctor }
const
  verctor_offset_integer=0;
  verctor_offset_double=0.0001;

class operator TVerctor.Equal(const Left, Right: TVerctor): Boolean;
begin
  if (Left.VerctorType<>Right.VerctorType) then Exit(False);
  if (Left.VerctorType=vtInteger) then
    result := (abs(PInteger(Left.X)^-PInteger(Right.X)^)<=verctor_offset_integer)
      and (abs(PInteger(Left.Y)^-PInteger(Right.Y)^)<=verctor_offset_integer)
      and (abs(PInteger(Left.Z)^-PInteger(Right.Z)^)<=verctor_offset_integer)
  else if (Left.VerctorType=vtDouble) then
    Result := (abs(PDouble(Left.X)^-PDouble(Right.X)^)<=verctor_offset_double)
      and (abs(PDouble(Left.Y)^-PDouble(Right.Y)^)<=verctor_offset_double)
      and (abs(PDouble(Left.Z)^-PDouble(Right.Z)^)<=verctor_offset_double)
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  Verctor1,Verctor2:TVerctor;
  x,y,z:Double;
  x1,y1,z1:Double;
begin
  x:=100.1;
  y:=200.2;
  z:=300.0001;
  Verctor1.X:=@x;
  Verctor1.Y:=@y;
  Verctor1.Z:=@z;
  Verctor1.VerctorType:=vtDouble;

  x1:=100.1;
  y1:=200.2;
  z1:=300.0002;
  Verctor2.X:=@x1;
  Verctor2.Y:=@y1;
  Verctor2.Z:=@z1;
  Verctor2.VerctorType:=vtDouble;

  if Verctor1=Verctor2 then ShowMessage('ok');




end;

end.

 

雖然可以實現,但不是我想要的

調整後

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Rtti,

  Types;

type

  VectorType = (vt2D, vt3d);

  Vector = record
    case VectorType of
      vt2D:
        (X, Y: Integer);
      vt3d:
        (X1, Y2, Z2: Real;);
  end;

  TVector3<T> = record
    X, Y, Z: T;
  end;

  TVectorHelper = record helper for TVector3<Real>

  end;

  TVectorRec<T> = record
    X, Y, Z: T;
    class operator Equal(const Left, Right: TVectorRec<T>): Boolean;
  end;

  TVector<T> = class
  private
    FX, FY, FZ: T;
  public
    property X: T read FX Write FX;
    property Y: T read FY Write FY;
    property Z: T read FZ Write FZ;
  end;

  TVector2D = class(TVector<Integer>)
  public
    class function Equal(const Left, Right: TVector2D): Boolean;
  end;

  TVector3D = class(TVector<Double>)
  public
    class function Equal(const Left, Right: TVector3D): Boolean;
  end;

  TEntity<T> = class
  private
    FID: T;
    procedure SetID(const Value: T);
  public
    property ID: T read FID write SetID;
  end;

  TOrderItem = class(TEntity<Integer>)
  end;

  TOrder = class(TEntity<Integer>)
  end;

  TCustomer = class(TEntity<TGUID>)
  end;

  TForm2 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button5: TButton;
    btnTBinaryWriter: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);

    procedure btnTBinaryWriterClick(Sender: TObject);
    procedure Button5Click(Sender: TObject);

    procedure Button7Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure test<T>(a, b: T);

  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

uses
  typinfo;

procedure TForm2.Button1Click(Sender: TObject);
var
  m_pCustomer: TCustomer;
  abc: TValueData;
begin
  m_pCustomer := TCustomer.Create;
  // m_pCustomer.ID:=TGuidHelper.NewGuid;

  with TVector2D.Create do
  begin
    X := 1;
    Y := 2;
    ShowMessage(format('x=%d,y=%d', [X, Y]));
  end;
  abc.FAsUByte := 1;
end;

{ TVectorRec<T> }

class operator TVectorRec<T>.Equal(const Left, Right: TVectorRec<T>): Boolean;
begin
  // ShowMessage(PTypeInfo(TypeInfo(T)).Name);
  case PTypeInfo(TypeInfo(T)).Kind of
    tkInteger:
      Result := (abs(PInteger(@Left.X)^ - PInteger(@Right.X)^) <= 0) and
        (abs(PInteger(@Left.Y)^ - PInteger(@Right.Y)^) <= 0) and
        (abs(PInteger(@Left.Z)^ - PInteger(@Right.Z)^) <= 0);
    tkFloat:
      Result := (abs(PDouble(@Left.X)^ - PDouble(@Right.X)^) <= 0.0005) and
        (abs(PDouble(@(Left.Y))^ - PDouble(@(Right.Y))^) <= 0.0005) and
        (abs(PDouble(@Left.Z)^ - PDouble(@Right.Z)^) <= 0.0005);
      //ShowMessage(FloatToStr(PDouble(@(Left.Y))^));
      //ShowMessage(FloatToStr(PDouble(@(Right.Y))^));
      //ShowMessage(FloatToStr(abs(PDouble(@(Left.Y))^ - PDouble(@(Right.Y))^) ));
  else
    Result := false;
  end;
end;

{ TVector3D }

class function TVector3D.Equal(const Left, Right: TVector3D): Boolean;
begin
  Result := (abs(Left.X - Right.X) < 0.0001) and
    (abs(Left.Y - Right.Y) < 0.0001) and (abs(Left.Z - Right.Z) < 0.0001)
end;

{ TVector2D }

class function TVector2D.Equal(const Left, Right: TVector2D): Boolean;
begin
  Result := (abs(Left.X - Right.X) < 0) and (abs(Left.Y - Right.Y) < 0) and
    (abs(Left.Z - Right.Z) < 0)
end;

{ TEntity<T> }

procedure TEntity<T>.SetID(const Value: T);
begin
  FID := Value;
end;

procedure TForm2.test<T>(a, b: T);
begin

end;

procedure TForm2.Button2Click(Sender: TObject);
begin
  test<Integer>(1, 2);
end;

procedure TForm2.Button3Click(Sender: TObject);
type
  TShapeList = (Rectangle, Triangle, Circle, Ellipse, Other);

  TFigure = record
    case TShapeList of
      Rectangle:
        (Height, Width: byte);
      Triangle:
        (Side1, Side2, Angle: Real);
      Circle:
        (Radius: Real);
      Ellipse, Other:
        ();
  end;
var
  Figure: TFigure;
begin
  // Figure.Height:=1;
  // Figure.Width:=2;
  Figure.Side1 := 3;
  Figure.Side2 := 4;
  Figure.Angle := 5;
  // Figure.Radius:=6;
  ShowMessage(inttostr(SizeOf(Real)));
  ShowMessage(inttostr(SizeOf(TFigure)));
  ShowMessage(format('%d,%d,%f,%f,%f,%f', [Figure.Height, Figure.Width,
    Figure.Side1, Figure.Side2, Figure.Angle, Figure.Radius]));
end;

procedure TForm2.btnTBinaryWriterClick(Sender: TObject);
var
  bw: TBinaryWriter;
begin
  bw := TBinaryWriter.Create('C:BinaryData.data', false, TEncoding.UTF8);
  try
    bw.Write(Caption);
    bw.Write(Left);
    bw.Write(Now);
  finally
    bw.Free;
  end;
end;

procedure TForm2.Button5Click(Sender: TObject);
begin
  test<Integer>(1, 2);
end;

procedure TForm2.Button7Click(Sender: TObject);
var
  m_pCustomer: TCustomer;
  abc: TValueData;
begin
  m_pCustomer := TCustomer.Create;
  // m_pCustomer.ID:=TGuidHelper.NewGuid;

  with TVector2D.Create do
  begin
    X := 1;
    Y := 2;
    ShowMessage(format('x=%d,y=%d', [X, Y]));
  end;
  abc.FAsUByte := 1;
end;

procedure TForm2.Button8Click(Sender: TObject);
begin
  test<Integer>(1, 2);
end;

procedure TForm2.Button4Click(Sender: TObject);
var
  a, b: TVectorRec<Double>;
begin
  a.X := 1.000;
  a.Y := 2.000;
  a.Z := 3;

  b.X := 1.0002;
  b.Y := 2.0001;
  b.Z := 3.0006;
  if a = b then
    ShowMessage('a,b一樣')
  else
    ShowMessage('a,b不一樣');
end;

end.

 

相關文章