Delphi XE2 のどこかでInc()
、現在の度数から度数を加算/減算して新しい度数を得ることができる関数を探しています。たとえば、現在円の周りに 5 度のポイントがあり、10 を減算したい場合、-5 度ではなく、355 (360 - 5) になるはずです。360 を超えて追加するのと同じ - 360 に達すると 0 に戻るはずです。
このようなものはすでに Delphi にあるので、書き直す必要はありませんか? もしかしてMath
ユニット内?
Delphi XE2 のどこかでInc()
、現在の度数から度数を加算/減算して新しい度数を得ることができる関数を探しています。たとえば、現在円の周りに 5 度のポイントがあり、10 を減算したい場合、-5 度ではなく、355 (360 - 5) になるはずです。360 を超えて追加するのと同じ - 360 に達すると 0 に戻るはずです。
このようなものはすでに Delphi にあるので、書き直す必要はありませんか? もしかしてMath
ユニット内?
uses
System.SysUtils,Math;
Function WrapAngle( angle : Double) : Double;
Const
modAngle : Double = 360.0;
begin
Result := angle - modAngle*Floor(angle/modAngle);
end;
begin
WriteLn(FloatToStr(WrapAngle(-5)));
WriteLn(FloatToStr(WrapAngle(5-720)));
WriteLn(FloatToStr(WrapAngle(360)));
ReadLn;
end.
結果を生成します:
355
5
0
アップデート:
@Gielが見つけたように、XE3にはDegNormalize()
その仕事をする新しい関数があります。約25%高速です。秘訣は、Floor()
呼び出しをInt()
代わりに置き換えることです。結果が負の場合は、結果に追加modAngle
します。
function WrapAngle(Value: Integer): Integer;
begin
Result := Value mod 360;
if Result < 0 then
Inc(Result, 360);
end;
このタスクを実行するために使用するコードは次のとおりです。
function PosFrac(x: Double): Double;
(* PosFrac(1.2)=0.2 and PosFrac(-1.2)=0.8. *)
begin
Result := Frac(x); (* Frac(x)=x-Int(x) *)
if Result<0.0 then begin
Result := 1.0+Result;
end;
end;
function ModR(const x, y: Double): Double;
(* ModR(1.2,1)=0.2 and ModR(-1.2,1)=0.8 *)
var
absy: Double;
begin
if y=0.0 then begin
Result := 0.0;
end else begin
absy := abs(y);
Result := PosFrac(x/absy)*absy;
end;
end;
function Mod360(const x: Double): Double;
begin
Result := ModR(x, 360.0);
end;
このコードは、すべての角度をからの範囲0
にし360
ます。例えば:
Writeln(Round(Mod360(5-10)));
Writeln(Round(Mod360(5-360)));
Writeln(Round(Mod360(5-720)));
Writeln(Round(Mod360(5+720)));
出力:
355 5 5 5
私は何も知りませんが、とにかくより一般的な解決策を使用したいと思います...
Procedure IncOverFlow(var Value:Double;Difference:Double;Limit:Double=360);
begin
Value := Value + Difference;
While Value < 0 do Value := Value + Limit;
While Value >= Limit do Value := Value -Limit;
end;
procedure WrapAngle(var Degs: Integer);
begin
Degs := Degs mod 360;
if Degs < 0 then
Inc(Degs, 360);
end;