2 টি কোণে ক্ষুদ্রতম পার্থক্য


137

রেফারেন্সের মধ্যে দুটি কোণ -PI -> পিআইকে একটি স্থানাঙ্কের চারপাশে দেওয়া হয়, এর মধ্যে 2 টি কোণগুলির মধ্যে ক্ষুদ্রের মান কত?

পিআই এবং পিপি-র মধ্যে পার্থক্য 2 পিআই নয়, শূন্য বিবেচনায় নেওয়া হয়।

উদাহরণ:

একটি বৃত্তটি কল্পনা করুন, 2 রেখাটি কেন্দ্র থেকে বেরিয়ে আসে, সেই রেখাগুলির মধ্যে 2 টি কোণ থাকে, তারা কোণটি ভিতরের দিকে ছোট কোণ এবং যে কোণটি তারা বাইরের দিকে তৈরি করে থাকে, তার চেয়ে বড় কোণ থাকে। উভয় কোণ যুক্ত হয়ে গেলে একটি সম্পূর্ণ বৃত্ত তৈরি করে। দেওয়া হয়েছে যে প্রতিটি কোণ একটি নির্দিষ্ট পরিসরের মধ্যে ফিট করতে পারে, রোলওভারকে বিবেচনায় নিয়ে ছোট কোণগুলির মানটি কী


2
আপনার বক্তব্যটি বোঝার আগে আমি 3 বার পড়েছি। দয়া করে একটি উদাহরণ যুক্ত করুন, বা আরও ভাল ব্যাখ্যা করুন ...
কোবি

একটি বৃত্তটি কল্পনা করুন, 2 লাইনটি কেন্দ্র থেকে সরেজমিনের মধ্য দিয়ে those লাইনগুলির মধ্যে 2 টি কোণ রয়েছে, তারা কোণটি ভিতরের দিকে ছোট কোণ এবং যে কোণটি তারা বাইরের দিকে তৈরি করে থাকে, বড়ো বড়ো কোণ aka উভয় কোণ যুক্ত হয়ে গেলে একটি সম্পূর্ণ বৃত্ত তৈরি করে। প্রদত্ত যে প্রতিটি কোণ একটি নির্দিষ্ট সীমার মধ্যে ফিট করতে পারে, রোলওভারকে বিবেচনায় নিয়ে ছোট কোণগুলির মানটি কী
টম জে নওয়েল


2
@JimG। এটি একই প্রশ্ন নয়, এই প্রশ্নে অন্য প্রশ্নে ব্যবহৃত কোণ P1 এর ভুল উত্তর হবে, এটি অন্য, ছোট কোণ হবে। এছাড়াও, কোনও অনুমান নেই যে কোণটি অনুভূমিক অক্ষের সাথে রয়েছে
টম জে নওয়েল

উত্তর:


193

এটি যে কোনও কোণগুলির জন্য একটি স্বাক্ষরিত কোণ দেয়:

a = targetA - sourceA
a = (a + 180) % 360 - 180

অনেক ভাষায় সাবধান থাকুন moduloঅপারেশনটি লভ্যাংশের মতো একই চিহ্ন সহ একটি মান দেয় (যেমন সি, সি ++, সি #, জাভাস্ক্রিপ্ট, পুরো তালিকা এখানে )। এটির modমতো একটি কাস্টম ফাংশন প্রয়োজন :

mod = (a, n) -> a - floor(a/n) * n

অথবা তাই:

mod = (a, n) -> (a % n + n) % n

যদি কোণগুলি [-180, 180] এর মধ্যে থাকে তবে এটিও কাজ করে:

a = targetA - sourceA
a += (a>180) ? -360 : (a<-180) ? 360 : 0

আরও ভার্জিক পদ্ধতিতে:

a = targetA - sourceA
a -= 360 if a > 180
a += 360 if a < -180

সরল এবং আরও জ্ঞান করে জোরে জোরে পড়ুন, যদিও কার্যকরভাবে একই জিনিসটি, প্রথম বিটিটি কোণটি নির্ধারণ করে, দ্বিতীয় অংশটি নিশ্চিত করে যে এটি সর্বদা 2 সম্ভাব্য কোণগুলির চেয়ে ছোট
টম জে নওয়েল

1
যদিও কেউ% 360 করতে চায়, উদাহরণস্বরূপ আমার যদি কোণ 0 এবং লক্ষ্য কোণ 721 থাকে তবে সঠিক উত্তরটি 1 হবে, উপরের উত্তরটি হবে 361
টম জে নোয়েল

1
আরও সংক্ষিপ্ত, যদিও সম্ভাব্য আরও ব্যয়বহুল, উত্তরোত্তর পদ্ধতির দ্বিতীয় বিবরণের সমতুল্য a -= 360*sgn(a)*(abs(a) > 180)। (এটা মনে করার যদি branchless বাস্তবায়নের করেছি এস, sgnএবং absযে চরিত্রগত শক্তি আসলে দুটি multiplications প্রয়োজন ক্ষতিপূরণের জন্য শুরু, তারপর।)
mmirate

1
"যে কোনও কোণে স্বাক্ষরিত কোণ" উদাহরণটি এক ব্যতিক্রম ছাড়া বেশিরভাগ পরিস্থিতিতে কাজ করে বলে মনে হচ্ছে। দৃশ্যকল্প ইন double targetA = 2; double sourceA = 359;'একটি' -357,0 পরিবর্তে 3.0 সমান হবে
Stevoisiak

3
সি ++ তে আপনি ভাসমান পয়েন্ট মডুলো ব্যবহার করতে std :: fmod (a, 360), বা fmod (a, 360) ব্যবহার করতে পারেন।
জোপ্পি

145

x লক্ষ্য কোণ। y হল উত্স বা সূচনা কোণ:

atan2(sin(x-y), cos(x-y))

এটি স্বাক্ষরিত বদ্বীপ কোণটি প্রদান করে। নোট করুন যে আপনার API এর উপর নির্ভর করে atan2 () ফাংশনের জন্য পরামিতিগুলির ক্রম আলাদা হতে পারে।


13
x-yআপনাকে কোণে পার্থক্য দেয় তবে এটি পছন্দসই সীমা ছাড়িয়ে যেতে পারে। ইউনিট বৃত্তের একটি বিন্দু সংজ্ঞায়িত করা এই কোণটি সম্পর্কে ভাবুন। সেই পয়েন্টের স্থানাঙ্কগুলি হ'ল (cos(x-y), sin(x-y))। এর পরিসীমা [-PI, PI] ব্যতীত atan2সেই বিন্দুটির জন্য কোণটি দেয় (যা সমান x-y) returns
সর্বোচ্চ


2
আমার জন্য এক লাইনের সহজ সমাধান এবং সমাধান করা (নির্বাচিত উত্তর নয়;))। তবে ট্যান ইনভার্স একটি ব্যয়বহুল প্রক্রিয়া।
মোহন কুমার

2
আমার জন্য, সবচেয়ে মার্জিত সমাধান। লজ্জাজনক এটি গণনা ব্যয়বহুল হতে পারে।
ফোকাস করে

আমার জন্য সবচেয়ে মার্জিত সমাধানও! আমার সমস্যাটি পুরোপুরি সমাধান করুন (এমন একটি সূত্র চেয়েছিলেন যা আমাকে স্বাক্ষরিত টার্ন এঙ্গেল দেয় যা দুটি সম্ভাব্য টার্নের দিক / কোণ থেকে ছোট একটি) is
ইয়রগেন ব্রয়ার

41

যদি আপনার দুটি কোণ x এবং y হয় তবে তাদের মধ্যে একটি কোণ অ্যাবস (x - y)। অন্য কোণটি হল (2 * পিআই) - অ্যাবস (এক্স - ওয়াই)। সুতরাং 2 টি কোণগুলির মধ্যে ক্ষুদ্রের মান হ'ল:

min((2 * PI) - abs(x - y), abs(x - y))

এটি আপনাকে কোণটির পরম মান দেয় এবং এটি ধরে নেয় যে ইনপুটগুলি স্বাভাবিক করা হয়েছে (যেমন: সীমার মধ্যে [0, 2π))।

আপনি যদি কোণটির চিহ্ন (যেমন: দিকনির্দেশ) সংরক্ষণ করতে চান এবং সীমার বাইরে কোণগুলিও গ্রহণ [0, 2π)করতে চান তবে আপনি উপরেরটিকে সাধারণীকরণ করতে পারেন। সাধারণ সংস্করণের জন্য পাইথন কোডটি এখানে রয়েছে:

PI = math.pi
TAU = 2*PI
def smallestSignedAngleBetween(x, y):
    a = (x - y) % TAU
    b = (y - x) % TAU
    return -a if a < b else b

নোট করুন যে %অপারেটর সমস্ত ভাষায় একই রকম আচরণ করে না, বিশেষত যখন নেতিবাচক মানগুলি জড়িত থাকে, তাই যদি কিছু সাইন অ্যাডজাস্টমেন্ট পোর্ট করা প্রয়োজন হয়।


1
@ ব্র্যাডগোনেসুরফিং এটি সত্য / সত্য ছিল তবে মূল পরীক্ষায় নির্দিষ্টভাবে নির্দিষ্ট না হওয়া বিষয়গুলির জন্য বিশেষভাবে আপনার পরীক্ষাগুলি পরীক্ষা করা হয়েছে, বিশেষত নরমালাইজড ইনপুট এবং সাইন-সংরক্ষণ। সম্পাদিত উত্তরের দ্বিতীয় সংস্করণে আপনার পরীক্ষাগুলি পাস করা উচিত।
লরেন্স গনসাল্ভেস

দ্বিতীয় সংস্করণটিও আমার পক্ষে কাজ করে না। উদাহরণস্বরূপ 350 এবং 0 চেষ্টা করে দেখুন। এটি -10 ফিরতে হবে তবে ফিরে আসবে
-350

@kjyv আপনি যে আচরণটি বর্ণনা করেছেন তা আমি পুনরুত্পাদন করতে পারি না। আপনি সঠিক কোড পোস্ট করতে পারেন?
লরেন্স গনসাল্ভেস

আহ, আমি দুঃখিত। আমি আবার অজগরে রেড এবং ডিগ্রি সহ আপনার সংস্করণটি পরীক্ষা করেছি এবং এটি দুর্দান্ত কাজ করেছে। সুতরাং সি অনুবাদে আমার অনুবাদে অবশ্যই ভুল হয়েছে (এটি আর নেই)।
kjyv

2
দ্রষ্টব্য, পাইথন 3 হিসাবে, আপনি প্রকৃতপক্ষে স্থানীয়ভাবে তাউ ব্যবহার করতে পারেন! শুধু লিখুন from math import tau
মহরতল

8

আমি স্বাক্ষরিত উত্তর প্রদানের চ্যালেঞ্জের কাছে উঠি:

def f(x,y):
  import math
  return min(y-x, y-x+2*math.pi, y-x-2*math.pi, key=abs)

1
আহ ... উত্তরটি উপায় দ্বারা একটি পাইথন ফাংশন। দুঃখিত, আমি এক মুহুর্তের জন্য পাইথন মোডে ছিলাম। আশা করি ঠিক আছে।
ডেভিড জোনস

আমি আমার কোডটিতে নতুন সূত্রটি উপরের দিকে প্লাগ করব এবং দেখতে এটি কী হবে! (থ্যানকিউ ^ _ ^)
টম জে নওয়েল

1
আমি বেশ নিশ্চিত যে পিটারবির উত্তরও সঠিক correct এবং অশুভভাবে হ্যাকিশ। :)
ডেভিড জোনস

4
তবে এটিতে কোনও
ট্রিিগ

জাভার সমতুল্য সূত্র কী? কোণ যদি ডিগ্রীতে থাকে?
সোলে

6

UnityEngine ব্যবহারকারীদের জন্য, সহজ উপায় ব্যবহার করতে ঠিক হয় Mathf.DeltaAngle


1
কোনও স্বাক্ষরিত আউটপুট নেই
kjyv

5

পাটিগণিত (অ্যালগোরিদমিকের বিপরীতে) সমাধান:

angle = Pi - abs(abs(a1 - a2) - Pi);

4
এটি পরীক্ষার স্যুটে ব্যর্থ হয়েছে gist.github.com/bradphelan/7fe21ad8ebfcb43696b8
ব্র্যাডগোনসার্ফিং

অ্যাবস (a1-a2) >>> 360 ব্যর্থ হয়। পরিবর্তে এটি ব্যবহার করুন: stackoverflow.com/a/52432897/6050364
অ্যাড্রিয়েল জুনিয়র

2

সি ++ এ একটি কার্যকর কোড যা কোনও কোণ এবং উভয় ক্ষেত্রেই কাজ করে: রেডিয়ান এবং ডিগ্রি হ'ল:

inline double getAbsoluteDiff2Angles(const double x, const double y, const double c)
{
    // c can be PI (for radians) or 180.0 (for degrees);
    return c - fabs(fmod(fabs(x - y), 2*c) - c);
}

-1

ত্রিকোণমিতিক ফাংশন গণনা করার প্রয়োজন নেই। সি ভাষায় সহজ কোডটি হ'ল:

#include <math.h>
#define PIV2 M_PI+M_PI
#define C360 360.0000000000000000000
double difangrad(double x, double y)
{
double arg;

arg = fmod(y-x, PIV2);
if (arg < 0 )  arg  = arg + PIV2;
if (arg > M_PI) arg  = arg - PIV2;

return (-arg);
}
double difangdeg(double x, double y)
{
double arg;
arg = fmod(y-x, C360);
if (arg < 0 )  arg  = arg + C360;
if (arg > 180) arg  = arg - C360;
return (-arg);
}

রেডিয়ানদের মধ্যে পৃথক্ = এ - বি, চলুন

dif = difangrad(a,b);

চলুন ডিফের মধ্যে পৃথক্ = ক - বি,

dif = difangdeg(a,b);

difangdeg(180.000000 , -180.000000) = 0.000000
difangdeg(-180.000000 , 180.000000) = -0.000000
difangdeg(359.000000 , 1.000000) = -2.000000
difangdeg(1.000000 , 359.000000) = 2.000000

কোন পাপ, কোন মহাকাশ, কোন তন, .... শুধু জ্যামিতি !!!!


7
বাগ! যেহেতু আপনি পিআইভি 2 কে "এমপিআই + এমপিআই" হিসাবে সংজ্ঞায়িত করেছেন, "(এমপিআই + এমপিআই)" নয়, লাইনটি arg = arg - PIV2;প্রসারিত হয় arg = arg - M_PI + M_PIএবং তাই কিছুই করে না does
ক্যান্টন 7
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.