2012-11-10 14 views
5

मैं Inc() के समान डेल्फी XE2 में कहीं भी फ़ंक्शन ढूंढ रहा हूं जो मुझे वर्तमान डिग्री की डिग्री से कई डिग्री जोड़ने/घटाने की अनुमति देता है और परिणामस्वरूप नई डिग्री होती है। उदाहरण के लिए, यदि मेरे पास वर्तमान में एक सर्कल के चारों ओर 5 डिग्री पर एक बिंदु है, और मैं 10 घटाना चाहता हूं, मुझे -5 डिग्री नहीं मिलनी चाहिए, बल्कि 355 (360 - 5)। पिछले 360 को जोड़ने के समान - इसे 360 तक पहुंचने पर 0 पर वापस जाना चाहिए।क्या 0 पिछले सर्कल की डिग्री को स्थानांतरित करने के लिए कोई फ़ंक्शन है?

क्या पहले से ही डेल्फी में ऐसा कुछ है, इसलिए मुझे इसे फिर से लिखना नहीं है? शायद Math इकाई में?

+3

रिकॉर्ड के लिए: डेल्फी XE3 System.Math में एक DegNormalize() फंक्शन होता है। – Giel

+3

मैं यह टिप्पणी करना चाहता हूं कि यह प्रश्न, उत्तर और टिप्पणियां बताती हैं कि मुझे स्टैक ओवरफ़्लो क्यों पसंद है। मैंने एक छोटे से छोटे काम के बारे में बहुत कुछ सीखा है जिसे मैंने सोचा था कि मैंने पहले ही पाला था। अच्छी तरह से सबको खेला! –

+0

यह सब ज्ञान डेवलपर्स के सिर और कोड में बंद हो गया है और हम नहीं जानते कि हम क्या नहीं जानते ... यह हमारी विशेषज्ञता का विस्तार करने की सुंदरता है। –

उत्तर

10
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 जोड़ें।

+0

+1 यह बहुत ही सुरुचिपूर्ण है। –

+0

धन्यवाद, मैं इसे अपने अनुप्रयोगों में बहुत उपयोग करता हूं।ModAngle को 2 * Pi में प्रतिस्थापित करके आपके पास रेडियंस के लिए एक कार्यशील कार्य भी है। वास्तव में –

+0

। या पैरामीटर के रूप में मॉड्यूलस पास करें। मेरा संस्करण अनावश्यक रूप से जटिल लगता है। मुझे लगता है कि हम कुछ दिनचर्या में कुछ सहायकों का उपयोग करते हैं। –

1

मैं किसी भी पता नहीं है, लेकिन मुझे किसी भी एक अधिक सामान्य समाधान का उपयोग पसंद करते हैं ...

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; 
+0

रेडियंस लेते हुए मैंने जो फॉर्मूला समाप्त कर लिया है, उसे ध्यान में रखते हुए, मैं 'डीजीटीओआरएडी' और 'राडतोडेग' का उपयोग करता हूं। – Petesh

+0

@ पेटेश मेरी मदद करते हैं, मैं प्रश्न के संदर्भ को नहीं देख सकता। कुछ एपीआई उपयोग डिग्री, सतह पर यह सामान्य है। – bummi

+0

मैं आपका जवाब खटखटा नहीं रहा हूं; यह एक सामान्य फ्लोट-आधारित वृद्धि समारोह के लिए बहुत अच्छा है। यह सिर्फ 'RadToDeg (DegToRad (Value + वृद्धि)) है,' अधिक, या कम, एक ही उत्तर देगा (+/- सामान्य रूपांतरण त्रुटियां) – Petesh

3

कोड मैं इस कार्य को करने के लिए उपयोग है:

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 
+0

+1: मैं इस में अपनी समुद्री डोमेन पृष्ठभूमि देख सकता हूं :-) –

+0

@ मारजन यह कोड 25 वर्षों तक OrcaFlex में चल रहा है। असामान्य टिप्पणी शैली इसलिए है क्योंकि कोड मॉड्यूल -2 के समय के बाद से कोड नहीं बदला गया है! –

+0

25 साल हुह? अच्छा! और टिप्पणी शैली भी ध्यान नहीं दिया। मैं आमतौर पर सामान्य टिप्पणियों से अलग होने और '{}' टिप्पणियों की गैर-घृणा से बचने के लिए, पेस्ट सामग्री की प्रतिलिपि बनाने के लिए '(* *)' का उपयोग करता हूं। –

4
function WrapAngle(Value: Integer): Integer; 
begin 
    Result := Value mod 360; 
    if Result < 0 then 
    Inc(Result, 360); 
end; 
+0

यह संभवतः सबसे सुरक्षित है जो आप पूर्णांक इनपुट के लिए कर सकते हैं। –

1
procedure WrapAngle(var Degs: Integer); 
begin 
    Degs := Degs mod 360; 
    if Degs < 0 then 
    Inc(Degs, 360); 
end; 
संबंधित मुद्दे