Ignore:
Timestamp:
Apr 17, 2019, 12:58:41 AM (5 years ago)
Author:
chronos
Message:
  • Modified: Propagate project build mode options to used packages.
  • Added: Check memory leaks using heaptrc.
  • Modified: Update BGRABitmap package.
Location:
GraphicTest
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • GraphicTest

    • Property svn:ignore
      •  

        old new  
        88GraphicTest.lps
        99GraphicTest.dbg
         10heaptrclog.trc
  • GraphicTest/Packages/bgrabitmap/bgratransform.pas

    r494 r521  
    1313  { Contains an affine matrix, i.e. a matrix to transform linearly and translate TPointF coordinates }
    1414  TAffineMatrix = BGRABitmapTypes.TAffineMatrix;
    15 
    16   { TAffineBox }
    17 
    18   TAffineBox = object
    19   private
    20     function GetAsPolygon: ArrayOfTPointF;
    21     function GetBottomRight: TPointF;
    22     function GetIsEmpty: boolean;
    23   public
    24     TopLeft, TopRight,
    25     BottomLeft: TPointF;
    26     class function EmptyBox: TAffineBox;
    27     class function AffineBox(ATopLeft, ATopRight, ABottomLeft: TPointF): TAffineBox;
    28     property BottomRight: TPointF read GetBottomRight;
    29     property IsEmpty: boolean read GetIsEmpty;
    30     property AsPolygon: ArrayOfTPointF read GetAsPolygon;
    31   end;
     15  { Contains an affine base and information on the resulting box }
     16  TAffineBox = BGRABitmapTypes.TAffineBox;
    3217
    3318  { TBGRAAffineScannerTransform allow to transform any scanner. To use it,
     
    8772    procedure Init(ABitmap: TBGRACustomBitmap; ARepeatImageX: Boolean= false; ARepeatImageY: Boolean= false; AResampleFilter: TResampleFilter = rfLinear; AIncludeEdges: boolean = false);
    8873  public
    89     constructor Create(ABitmap: TBGRACustomBitmap; ARepeatImage: Boolean= false; AResampleFilter: TResampleFilter = rfLinear; AIncludeEdges: boolean = false);
    90     constructor Create(ABitmap: TBGRACustomBitmap; ARepeatImageX: Boolean; ARepeatImageY: Boolean; AResampleFilter: TResampleFilter = rfLinear; AIncludeEdges: boolean = false);
     74    constructor Create(ABitmap: TBGRACustomBitmap; ARepeatImage: Boolean= false; AResampleFilter: TResampleFilter = rfLinear; AIncludeEdges: boolean = false); overload;
     75    constructor Create(ABitmap: TBGRACustomBitmap; ARepeatImageX: Boolean; ARepeatImageY: Boolean; AResampleFilter: TResampleFilter = rfLinear; AIncludeEdges: boolean = false); overload;
    9176    destructor Destroy; override;
    9277    function InternalScanCurrentPixel: TBGRAPixel; override;
     
    137122    constructor Create(ASource: IBGRAScanner;
    138123      ASourceMatrix: TAffineMatrix; const APoints: array of TPointF;
    139       ATextureInterpolation: boolean = true);
     124      ATextureInterpolation: boolean = true); overload;
    140125    constructor Create(ASource: IBGRAScanner;
    141126      const ATexCoords: array of TPointF; const APoints: array of TPointF;
    142       ATextureInterpolation: boolean = true);
     127      ATextureInterpolation: boolean = true); overload;
    143128    destructor Destroy; override;
    144129    property Culling: TFaceCulling read GetCulling write SetCulling;
     
    191176{---------------------- Affine matrix functions -------------------}
    192177//fill a matrix
    193 function AffineMatrix(m11,m12,m13,m21,m22,m23: single): TAffineMatrix;
     178function AffineMatrix(m11,m12,m13,m21,m22,m23: single): TAffineMatrix; overload;
     179function AffineMatrix(AU,AV: TPointF; ATranslation: TPointF): TAffineMatrix; overload;
    194180
    195181//matrix multiplication
     
    200186operator *(M: TAffineMatrix; V: TPointF): TPointF;
    201187operator *(M: TAffineMatrix; A: array of TPointF): ArrayOfTPointF;
     188operator *(M: TAffineMatrix; ab: TAffineBox): TAffineBox;
    202189
    203190//check if matrix is inversible
     
    221208//define a scaling matrix
    222209function AffineMatrixScale(sx,sy: single): TAffineMatrix;
     210function AffineMatrixScaledRotation(ASourceVector, ATargetVector: TPointF): TAffineMatrix;
     211function AffineMatrixScaledRotation(ASourcePoint, ATargetPoint, AOrigin: TPointF): TAffineMatrix;
    223212
    224213function AffineMatrixSkewXDeg(AngleCW: single): TAffineMatrix;
     
    228217
    229218//define a linear matrix
    230 function AffineMatrixLinear(v1,v2: TPointF): TAffineMatrix;
     219function AffineMatrixLinear(v1,v2: TPointF): TAffineMatrix; overload;
     220function AffineMatrixLinear(const AMatrix: TAffineMatrix): TAffineMatrix; overload;
    231221
    232222//define a rotation matrix (positive radians are counter-clockwise)
     
    242232
    243233function IsAffineMatrixOrthogonal(M: TAffineMatrix): boolean;
     234function IsAffineMatrixScaledRotation(M: TAffineMatrix): boolean;
    244235
    245236type
     
    278269    procedure SetIncludeOppositePlane(AValue: boolean);
    279270  public
    280     constructor Create(texture: IBGRAScanner; texCoord1,texCoord2: TPointF; const quad: array of TPointF);
    281     constructor Create(texture: IBGRAScanner; const texCoordsQuad: array of TPointF; const quad: array of TPointF);
     271    constructor Create(texture: IBGRAScanner; texCoord1,texCoord2: TPointF; const quad: array of TPointF); overload;
     272    constructor Create(texture: IBGRAScanner; const texCoordsQuad: array of TPointF; const quad: array of TPointF); overload;
    282273    destructor Destroy; override;
    283274    procedure ScanMoveTo(X, Y: Integer); override;
     
    298289  public
    299290    constructor Create; overload;
    300     constructor Create(x1,y1,x2,y2: single; const quad: array of TPointF);
    301     constructor Create(const quad: array of TPointF; x1,y1,x2,y2: single);
    302     constructor Create(const srcQuad,destQuad: array of TPointF);
     291    constructor Create(x1,y1,x2,y2: single; const quad: array of TPointF); overload;
     292    constructor Create(const quad: array of TPointF; x1,y1,x2,y2: single); overload;
     293    constructor Create(const srcQuad,destQuad: array of TPointF); overload;
    303294    function MapQuadToQuad(const srcQuad,destQuad: array of TPointF): boolean;
    304295    function MapRectToQuad(x1,y1,x2,y2: single; const quad: array of TPointF): boolean;
     
    386377end;
    387378
     379function AffineMatrix(AU, AV: TPointF; ATranslation: TPointF): TAffineMatrix;
     380begin
     381  result:= AffineMatrix(AU.x, AV.x, ATranslation.x,
     382                        AU.y, AV.y, ATranslation.y);
     383end;
     384
    388385operator *(M, N: TAffineMatrix): TAffineMatrix;
    389386begin
     
    427424    for i := 0 to high(A) do
    428425      result[i] := M*A[i];
     426end;
     427
     428operator*(M: TAffineMatrix; ab: TAffineBox): TAffineBox;
     429begin
     430  result.TopLeft := M*ab.TopLeft;
     431  result.TopRight := M*ab.TopRight;
     432  result.BottomLeft := M*ab.BottomLeft;
    429433end;
    430434
     
    475479end;
    476480
     481function AffineMatrixScaledRotation(ASourceVector, ATargetVector: TPointF): TAffineMatrix;
     482var
     483  prevScale, newScale, scale: Single;
     484  u1,v1,u2,v2,w: TPointF;
     485begin
     486  prevScale := VectLen(ASourceVector);
     487  newScale := VectLen(ATargetVector);
     488  if (prevScale = 0) or (newScale = 0) then
     489    result := AffineMatrixIdentity
     490  else
     491  begin
     492    scale := newScale/prevScale;
     493    u1 := ASourceVector*(1/prevScale);
     494    v1 := PointF(-u1.y,u1.x);
     495    w := ATargetVector*(1/newScale);
     496    u2 := PointF(w*u1, w*v1);
     497    v2 := PointF(-u2.y,u2.x);
     498    result := AffineMatrix(scale*u2,scale*v2,PointF(0,0));
     499  end;
     500end;
     501
     502function AffineMatrixScaledRotation(ASourcePoint, ATargetPoint, AOrigin: TPointF): TAffineMatrix;
     503begin
     504  result := AffineMatrixTranslation(AOrigin.x,AOrigin.y)*
     505         AffineMatrixScaledRotation(ASourcePoint-AOrigin, ATargetPoint-AOrigin)*
     506         AffineMatrixTranslation(-AOrigin.x,-AOrigin.y);
     507end;
     508
    477509function AffineMatrixSkewXDeg(AngleCW: single): TAffineMatrix;
    478510begin
     
    506538end;
    507539
     540function AffineMatrixLinear(const AMatrix: TAffineMatrix): TAffineMatrix;
     541begin
     542  result := AffineMatrix(AMatrix[1,1],AMatrix[1,2],0,
     543                         AMatrix[2,1],AMatrix[2,2],0);
     544end;
     545
    508546function AffineMatrixRotationRad(AngleCCW: Single): TAffineMatrix;
    509547begin
     
    527565begin
    528566  result := PointF(M[1,1],M[2,1])*PointF(M[1,2],M[2,2]) = 0;
     567end;
     568
     569function IsAffineMatrixScaledRotation(M: TAffineMatrix): boolean;
     570begin
     571  result := IsAffineMatrixOrthogonal(M) and
     572           (VectLen(PointF(M[1,1],M[2,1]))=VectLen(PointF(M[1,2],M[2,2])));
    529573end;
    530574
     
    608652  if y > FBounds.Bottom-1 then y := FBounds.Bottom-1;
    609653  result := FSource.ScanAt(X,Y);
    610 end;
    611 
    612 { TAffineBox }
    613 
    614 function TAffineBox.GetAsPolygon: ArrayOfTPointF;
    615 begin
    616   result := PointsF([TopLeft,TopRight,BottomRight,BottomLeft]);
    617 end;
    618 
    619 function TAffineBox.GetBottomRight: TPointF;
    620 begin
    621   if IsEmpty then
    622     result := EmptyPointF
    623   else
    624     result := TopRight + (BottomLeft-TopLeft);
    625 end;
    626 
    627 function TAffineBox.GetIsEmpty: boolean;
    628 begin
    629   result := isEmptyPointF(TopRight) or isEmptyPointF(BottomLeft) or isEmptyPointF(TopLeft);
    630 end;
    631 
    632 class function TAffineBox.EmptyBox: TAffineBox;
    633 begin
    634   result.TopLeft := EmptyPointF;
    635   result.TopRight := EmptyPointF;
    636   result.BottomLeft := EmptyPointF;
    637 end;
    638 
    639 class function TAffineBox.AffineBox(ATopLeft, ATopRight, ABottomLeft: TPointF): TAffineBox;
    640 begin
    641   result.TopLeft := ATopLeft;
    642   result.TopRight := ATopRight;
    643   result.BottomLeft := ABottomLeft;
    644654end;
    645655
Note: See TracChangeset for help on using the changeset viewer.