मुझे पता है कि यह प्रश्न काफी पुराना है, और स्वीकार्य उत्तर ने मुझे यह करने में मदद की, फिर भी मुझे लगता है कि मेरे पास एक और अधिक सुरुचिपूर्ण समाधान है जो समानता को कवर करता है (इसलिए लोअरहान के लिए रिटर्न -1, बराबर के लिए 0, और 1 के लिए से अधिक)।
यह विमान के विभाजन पर 2 हिस्सों तक, सकारात्मक रेफ अक्ष (समावेशी) से नकारात्मक रेफ अक्ष (अनन्य) तक आधारित है, और दूसरा इसका पूरक है।
प्रत्येक आधे के अंदर, तुलना दाएं हाथ के नियम (क्रॉस उत्पाद चिह्न), या दूसरे शब्दों में - 2 वैक्टरों के बीच कोण के साइन के द्वारा किया जा सकता है। यदि 2 अंक अलग-अलग हिस्सों से आते हैं, तो तुलना तुच्छ होती है और खुद को हिस्सों के बीच किया जाता है।
पर्याप्त रूप से समान वितरण के लिए, यह परीक्षण औसत 4 तुलना, 1 घटाव, और 1 गुणा पर प्रदर्शन करना चाहिए, इसके अलावा रेफरी के साथ किए गए 4 घटाव के अलावा, मेरी राय में पूर्व निर्धारित किया जाना चाहिए।
int compareAngles(Point const & A, Point const & B, Point const & ref = Point(0,0)) {
typedef decltype(Point::x) T; // for generality. this would not appear in real code.
const T sinA = A.y - ref.y; // |A-ref|.sin(angle between A and positive ref-axis)
const T sinB = B.y - ref.y; // |B-ref|.sin(angle between B and positive ref-axis)
const T cosA = A.x - ref.x; // |A-ref|.cos(angle between A and positive ref-axis)
const T cosB = B.x - ref.x; // |B-ref|.cos(angle between B and positive ref-axis)
bool hA = ((sinA < 0) || ((sinA == 0) && (cosA < 0))); // 0 for [0,180). 1 for [180,360).
bool hB = ((sinB < 0) || ((sinB == 0) && (cosB < 0))); // 0 for [0,180). 1 for [180,360).
if (hA == hB) {
// |A-ref|.|B-ref|.sin(angle going from (B-ref) to (A-ref))
T sinBA = sinA * cosB - sinB * cosA;
// if T is int, or return value is changed to T, it can be just "return sinBA;"
return ((sinBA > 0) ? 1 : ((sinBA < 0) ? (-1) : 0));
}
return (hA - hB);
}
बस उत्सुक, जिसमें आपने छवि बनाई? – TMS
मुझे लगता है कि आपका मतलब डॉट उत्पाद है? यह मुझे 2 डी लगता है। यद्यपि कहना मुश्किल है। –
मुझे नहीं लगता कि आप कम से कम डॉट उत्पाद का उपयोग कर सकते हैं, वैक्टर सभी को एक ही लंबाई होना चाहिए, और फिर भी आपको कोण के कोसाइन मिलते हैं। –