德尔福单值近

时间:2016-05-29 15:02:08

标签: delphi matrix scaling floating-accuracy

所以我需要将TRectF装入另一个TRectF并获得比例因子,但所有都存储在Single变量中。 问题是我失去了精度,所以我如何得到最接近的值可以存储在单个?

示例:

LToFit := TRectF.Create( 0, 0, 320, 480 );

LRect := TRectF.Create( 0, 0, 841, 613 );

LRatio := Min(
  LRect.Width / LToFit.FWidth,
  LRect.Height / LToFit.FHeight
);

// The value of LRatio is 1.27708327770233

// Now i want that result is Pixel aligned so 

LAdd.X := Floor( LToFit.FWidth * LRatio ) mod 2;
LAdd.Y := Floor( LToFit.FHeight * LRatio ) mod 2;

if LRect.Width > LRect.Height then 
  LRatio := ( Floor( LToFit.FWidth * LRatio ) + LAdd.X  ) / FViewer.FView.FWidth
else
  LRatio := ( Floor( LToFit.FHeight * LRatio ) + LAdd.Y ) / FViewer.FView.FHeight;

// The value of LRatio is 1.27499997615814

Ecc ......结果是可以接受的。但是现在假设LRect在高度上有-3,所以:

LToFit := TRectF.Create( 0, 0, 320, 480 );

LRect := TRectF.Create( 0, 0, 841, 610 );

LRatio := Min(
  LRect.Width / LToFit.FWidth,
  LRect.Height / LToFit.FHeight
);

// The value of LRatio is 1.27083337306976

// Now i want that result is Pixel aligned so 

LAdd.X := Floor( LToFit.FWidth * LRatio ) mod 2;
LAdd.Y := Floor( LToFit.FHeight * LRatio ) mod 2;

if LRect.Width > LRect.Height then 
  LRatio := ( Floor( LToFit.FWidth * LRatio ) + LAdd.X  ) / FViewer.FView.FWidth
else
  LRatio := ( Floor( LToFit.FHeight * LRatio ) + LAdd.Y ) / FViewer.FView.FHeight;

// The value of LRatio is 1.26874995231628

Ecc ...所以在第一种情况下,LRatio为674高度为1.27499997615814,在第二种情况下,对于610 Heigh,LRatio为1.26874995231628。

其他测试:

LRatio Height

A 1.27499997615814 611

B 1.26874995231628 610< - not accettable

C 1.26874995231628 609< - not accettable

D 1.26874995231628 608< - not accettable

E 1.26250004768372 607

问题是如何将B和C的LRatio限制为A和D进入E? 还有其他公式?

所有这一切都是为了设置使用单一类型变量的Matrix Scaling。

感谢。

更新:

我尝试这个:

S1 := 0;
S2 := 1 / Power( 2, 23 );
while S1 < LRatio do
begin
  S1 := S1 + 0.0625 + S2;
end;
LRatio := S1 - S2;

似乎工作但我不知道为什么!计算也比较贵:(

更新2:

好的,不使用LAdd我计算从605到619的LRect高度。你怎么看我只需要黄色值。但我不能喜欢这个公式:

(目的地高度):(比例)(ToFit Scaled Height(Rounded))(圆角结果H:W)

enter image description here

解决方案? :

我找不到更多“数学”的东西,我会满足于这个我认为符合我需要的功能。 我仍然会对建议表示感谢。

function GetRoundedScale( const ARect, AIntoRect: TRectF ): Single;
  var
    LScaled: TPointF;
    LOffSet: Integer;
  begin
    Result := Min(
      AIntoRect.Width / ARect.Width,
      AIntoRect.Height / ARect.Height
    );
    LScaled := TPointF.Create( ARect.Width * Result, ARect.Height * Result );
    LOffSet := 0;
    while Odd( Round( LScaled.X ) ) or Odd( Round( LScaled.Y ) ) do
    begin
      Inc( LOffSet );
      Result := Min(
        ( AIntoRect.Width + LOffSet ) / ARect.Width,
        ( AIntoRect.Height + LOffSet ) / ARect.Height
      );
      LScaled := TPointF.Create( ARect.Width * Result, ARect.Height * Result );
    end;
  end;

0 个答案:

没有答案
相关问题