Atan2 () কে 0-360 ডিগ্রি তে ম্যাপ করবেন কীভাবে


108

atan2(y, x) ১৮০ at এ এটি বিচ্ছিন্নতা রয়েছে যেখানে এটি ঘড়ির কাঁটার দিকে যেতে -180 ° ..0 to এ স্যুইচ করে।

আমি মানগুলির পরিসীমা 0 ° ..360 ° এ কীভাবে মানচিত্র করব?

এখানে আমার কোড:

CGSize deltaPoint = CGSizeMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y);
float swipeBearing = atan2f(deltaPoint.height, deltaPoint.width);

আমি startPointএবং endPointউভয় এক্সওয়াই পয়েন্ট স্ট্রাক্ট প্রদত্ত একটি সোয়াইপিং টাচের ইভেন্টের দিক নির্ণয় করছি । কোডটি আইফোনের জন্য তবে যে কোনও ভাষা সমর্থন atan2f()করে।


দ্রষ্টব্য: পোস্ট করা আপডেট পদ্ধতিটি শূন্য ডিগ্রি ফিরিয়ে দেবে না, তবে মান 0 থেকে 360.0 এর উপরে থাকবে।
chux - মনিকা পুনরায় ইনস্টল করুন

2
> [কীভাবে 2 অবস্থানের থেকে কোণটির পেতে] [1] [1]: stackoverflow.com/questions/9457988/...
মনোজ Sarnaik

এই ফাংশনটি দুর্দান্ত কাজ করে তবে "বিয়ারিংডিজারিজ" গণনার কোণটি উল্টে যায়। উদাহরণস্বরূপ, 45 ডিগ্রি সাধারণত 1 ম চতুর্ভুজ দ্বারা করা হবে, তবে এটি চতুর্থ কোয়াড্রেন্টে। ১৩৫ ডিগ্রি সাধারণত ২ য় কোয়াড্রেন্টে থাকে তবে এই ফাংশনটি এটি তৃতীয় কোয়াড্রেন্টে ফিরে আসে। আমি কেবল ফাংশনটি রিটার্ন ভ্যালু এক্স নিতে পারি এবং সঠিক এঙ্গেল মান পেতে 360 থেকে এটিকে উপেক্ষা করতে পারি তবে আমি কেন জানতে আগ্রহী যে কেন এটি প্রথম স্থানে ঘটছে?
goelv

উত্তর:


66
(x > 0 ? x : (2*PI + x)) * 360 / (2*PI)

6
সম্ভবত x = 0 ক্ষেত্রে x> = 0ও চান।
বিপিডব্লিউ 1621

13
এই স্বীকৃতিটিতে স্বাচ্ছন্দ্যবোধকারী এবং অন্তর্নির্মিত ডিগ্রীতে রূপান্তর ছাড়াই: যদি (x> 0) {রেডিয়ান = x;} অন্য {রেডিয়ান = 2 * পিআই + এক্স;} তাই আমরা ফলাফলটিতে কেবল 2PI যুক্ত করছি যদি এটি 0. এর চেয়ে কম
ডেভিড ডোরিয়া

1
বা (x >= 0 ? x : (2*PI + x)) * 180/PIহিসাবে(x < 0 ? 2*PI + x : x) * 180/PI
ব্যবহারকারী3342816

97

Modulo ব্যবহার করে সমাধান

একটি সহজ সমাধান যা সমস্ত কেস ধরে।

degrees = (degrees + 360) % 360;  // +360 for implementations where mod returns negative numbers

ব্যাখ্যা

ইতিবাচক: 1 থেকে 180

আপনি যদি 1 এবং 180 এর মধ্যে 360 দ্বারা কোনও ধনাত্মক সংখ্যাটি পরিবর্তন করেন তবে আপনি ঠিক একই নম্বরটি পাবেন Mod মোড এখানে ঠিক নিশ্চিত করে যে এই ধনাত্মক সংখ্যাগুলি একই মান হিসাবে ফিরে এসেছে।

নেতিবাচক: -180 থেকে -1

এখানে মোড ব্যবহার করে 180 এবং 359 ডিগ্রির মধ্যে মানগুলি ফিরে আসবে।

বিশেষ ক্ষেত্রে: 0 এবং 360

মোড ব্যবহারের অর্থ হল 0 ফিরিয়ে দেওয়া হয়েছে, এটি নিরাপদ 0-359 ডিগ্রি সমাধান করে।


3
দুর্দান্ত সমাধান :)
কাদির হুসেন

5
আমি এটি যোগ করতে 360. -1% 360 এখনও 359 হয় :) প্রয়োজন বিশ্বাস করে না
pleasemorebacon

11
আমি মনে করি না এটি সমস্ত ভাষায় সঠিক is জাভাস্ক্রিপ্টে-1 % 360 = -1
স্টারটেক

জাভাতেও কার্যকর ব্যবহারের উপায় নয়
হাল্ক

1
@ প্লিজমোরব্যাকন ভুল। কিছু ভাষায় -1% 360 -1 হয়।
ফারাপ

40

Atan2 থেকে উত্তর 0 than এর চেয়ে কম হলে কেবল 360 add যুক্ত করুন °


6
যদি আপনার সেই দিনগুলির একটি থাকে তবে "কেবল 2 * পিআই যুক্ত করুন" এর সমান ।
ক্রিস ও

33

অথবা আপনি যদি ব্রাঞ্চিং পছন্দ না করেন তবে কেবল দুটি পরামিতি উপেক্ষা করুন এবং উত্তরে 180। যুক্ত করুন।

(রিটার্ন ভ্যালুতে 180 Add যোগ করা এটিকে 0-360 পরিসীমাতে দুর্দান্তভাবে রাখে তবে কোণটি পিছলে।


2
ধন্যবাদ, আমি যা খুঁজছিলাম ঠিক এটিই।
জেরেমি হারম্যান

2
আমি বরং কোডটিকে ডিএনররমালাইজড অ্যাঙ্গেলগুলি ব্যবহার করতে সংশোধন করব (<0,> = 360) তবে সর্বদা মনে হয় যে কেউ সেই নকল "অনুকূলিত" অনুভূতির জন্য লক্ষ্য রেখেছিল; আমি এই যুক্ত করতে চেয়েছিলেন কেন। (বা এটি কি কারণ আমি ব্যবহার করা কিছু অস্থায়ী ডিবাগ কোডের কাছাকাছি দ্রুততর পথ ছিল? এইচএমএম)
আইবি

1
নিশ্চয় কুঁচকে সোজা না, যেহেতু আমি 2+ বছর পরে সম্মতি জানাতে পারি। সুতরাং: রিটার্ন ভ্যালুতে 180 Add যুক্ত করা এটিকে 0-360 রেঞ্জের মধ্যে সুন্দরভাবে রাখে তবে কোণটি উল্টে দেয়। উভয় ইনপুট পরামিতি নেতিবাচকভাবে এটি পিছনে ফ্লিপ হয়।
aib

এটিতে কিছু সমস্যা থাকতে পারে যখন $ x = 0 $ এবং $ y> 0 id আইরিক
ত্রিনিদাদ

22

@ এরিক্কাল্লেন নিকটবর্তী তবে একেবারেই সঠিক নয়।

theta_rad = atan2(y,x);
theta_deg = (theta_rad/M_PI*180) + (theta_rad > 0 ? 0 : 360);

এটি সি ++ এ কাজ করা উচিত: (fmod কীভাবে প্রয়োগ করা হয় তার উপর নির্ভর করে, এটি শর্তাধীন অভিব্যক্তির চেয়ে দ্রুত বা ধীর হতে পারে)

theta_deg = fmod(atan2(y,x)/M_PI*180,360);

বিকল্পভাবে আপনি এটি করতে পারেন:

theta_deg = atan2(-y,-x)/M_PI*180 + 180;

যেহেতু (x, y) এবং (-x, -y) 180 ডিগ্রি দ্বারা কোণে পৃথক হয়।


যদি আমি আপনাকে ফোর্টরানে সঠিকভাবে বুঝতে পারি তবে এটি atan2 (-y, -x) * 180 / PI + 180. এটি কি সঠিক?
গানসুব

দুঃখিত আমি ফোরট্রান জানি না। তবে আপনার গণিতটি ঠিক দেখাচ্ছে।
জেসন এস

11

আমার কাছে 2 টি সমাধান রয়েছে যা ইতিবাচক এবং নেতিবাচক x এবং y এর সমস্ত সংমিশ্রণের জন্য কাজ করে বলে মনে হচ্ছে।

1) অপব্যবহার atan2 ()

ডক্স অনুসারে atan2 এর ক্রমে y এবং x পরামিতি নেয়। তবে আপনি যদি তাদের উল্টো করেন তবে আপনি নিম্নলিখিতটি করতে পারেন:

double radians = std::atan2(x, y);
double degrees = radians * 180 / M_PI;
if (radians < 0)
{
    degrees += 360; 
}

2) atan2 () সঠিকভাবে ব্যবহার করুন এবং পরে রূপান্তর করুন

double degrees = std::atan2(y, x) * 180 / M_PI;
if (degrees > 90)
{
    degrees = 450 - degrees;
}
else
{
    degrees = 90 - degrees;
}

আপনি স্যার, একটি জীবন রক্ষাকারী। স্রেফ approachক্যতে এই পদ্ধতির ব্যবহার এবং কবজির মতো কাজ করে।
পোরিফিরোপার্টিদা

7

@ জেসন এস: আপনার "fmod" বৈকল্পিক একটি মান-সম্মতি কার্যকরকরণে কাজ করবে না। সি স্ট্যান্ডার্ডটি স্পষ্ট এবং স্পষ্ট (7.12.10.1, "fmod ফাংশন"):

যদি y ননজারো হয় তবে ফলাফলটির এক্স এর সমান চিহ্ন রয়েছে

এভাবে

fmod(atan2(y,x)/M_PI*180,360)

আসলে এটি কেবল একটি শব্দচক্রের পুনর্লিখন:

atan2(y,x)/M_PI*180

আপনার তৃতীয় পরামর্শটি তবে তা স্পষ্ট।


5

আমি সাধারণত এটি করি:

float rads = atan2(y, x);
if (y < 0) rads = M_PI*2.f + rads;
float degrees = rads*180.f/M_PI;

2
angle = Math.atan2(x,y)*180/Math.PI;

আমি 0 থেকে 360 এ কোণটি ওরিয়েন্টিং করার জন্য একটি সূত্র তৈরি করেছি

angle + Math.ceil( -angle / 360 ) * 360;

2

বিকল্প সমাধান হ'ল মোড () ফাংশনটি হিসাবে বর্ণিত:

function mod(a, b) {return a - Math.floor (a / b) * b;}

তারপরে, নিম্নলিখিত ফাংশনটির সাথে, ini (x, y) এবং শেষ (x, y) পয়েন্টগুলির মধ্যে কোণ পাওয়া যাবে। কোণটি [0, 360] ডিগ্রি স্বাভাবিক করা ডিগ্রিতে প্রকাশ করা হয়। এবং উত্তর রেফারেন্সিং 360 ডিগ্রি।

    function angleInDegrees(ini, end) {
        var radian = Math.atan2((end.y - ini.y), (end.x - ini.x));//radian [-PI,PI]
        return mod(radian * 180 / Math.PI + 90, 360);
    }

1

আর প্যাকেজ জিওফিয়ারটি বেয়ারিংহম্ব গণনা করবে, যা একটি উত্স পয়েন্ট এবং ইস্টিং / নোর্থিংয়ের সাথে দেওয়া ধ্রুবক ভারবহন রেখা। পূর্ব এবং নোরিং অবশ্যই ম্যাট্রিক্স বা ভেক্টরে থাকতে হবে। বায়ু গোলাপের জন্য মূল পয়েন্ট 0,0। নিম্নলিখিত কোডটি সহজেই সমস্যার সমাধান করছে বলে মনে হচ্ছে:

windE<-wind$uasE
windN<-wind$vasN
wind_matrix<-cbind(windE, windN)
wind$wind_dir<-bearingRhumb(c(0,0), wind_matrix)
wind$wind_dir<-round(wind$wind_dir, 0)

1
theta_rad = Math.Atan2(y,x);
if(theta_rad < 0)
  theta_rad = theta_rad + 2 * Math.PI;    //if neg., add 2 PI to it
theta_deg = (theta_rad/M_PI*180) ;        //convert from radian to degree

//or
theta_rad = Math.Atan2(y,x);
theta_rad = (theta_rad < 0) ? theta_rad + 2 * Math.PI : theta_rad;
theta_deg = (theta_rad/M_PI*180) ;

-1 ডিগ্রি হয়ে যায় (-1 + 360) = 359 ডিগ্রি
-179 ডিগ্রি হয়ে যায় (-179 + 360) = 181 ডিগ্রি


কি Math.PI? এটি কি হিসাবে একই M_PI?
পাং

1
double degree = fmodf((atan2(x, y) * (180.0 / M_PI)) + 360, 360);

এটি 0 ° -360 ° থেকে ঘড়ির কাঁটার বিপরীতে 0 ডিগ্রি ফিরে আসবে, 0 o'clock বাজে।


1

0 থেকে 360 ডিগ্রি পর্যন্ত মানের সীমা থাকা একটি সূত্র।

f (x, y) = 180-90 * (1 + চিহ্ন (x)) * (1-চিহ্ন (y ^ 2)) - 45 * (2 + চিহ্ন (x)) * চিহ্ন (y)

     -(180/pi())*sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))

এটি দয়া করে ব্যাখ্যা করতে পারেন যে এটি প্রশ্নের সাথে কীভাবে সম্পর্কিত?
ক্লাউস গ্যাটার

1

এখানে কিছু জাভাস্ক্রিপ্ট। শুধু x এবং y মান ইনপুট করুন।

var angle = (Math.atan2(x,y) * (180/Math.PI) + 360) % 360;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.