ベクトル定義ノート

26174 ワード

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.