Объединив ответ от Жюльена Виллемюра-Фрешетта со ссылкой, опубликованной @alterigel, я заставил свою функцию сравнения работать:
struct Vector3DComparator
{
bool operator() (const Vector3D& lhsIn, const Vector3D& rhsIn) const
{
int p = 100000; // precision factor
Vector3D lhs = lhsIn.absolute(); // make all members positive
Vector3D rhs = rhsIn.absolute();
auto lhsTied = std::tie((int)(lhs.x * p), (int)(lhs.y * p), (int)(lhs.z * p));
auto rhsTied = std::tie((int)(rhs.x * p), (int)(rhs.y * p), (int)(rhs.z * p));
return lhsTied < rhsTied;
}
};
Обратите внимание: этот код содержит плохой стиль, такой как приведения в стиле c, плохое именованиеи больше.Мои функции и классы отличаются от тех, которые размещены здесь.Я просто убрал все, чтобы было легче понять.
РЕДАКТИРОВАТЬ:
Я заметил еще две ошибки:
Первое: это не всегда работало для почти идентичных векторов.Основываясь на последнем комментарии @tetorea к моему вопросу, я изменил функцию, чтобы всегда получать очень похожие значения по сравнению.Я использую скалярное произведение для этого, поскольку оно равно ± 1 (или, по крайней мере, близко к) для параллельных векторов.
Второе: .absolute () не работал, потому что с этой функцией два вектора (-1,1,0) и (1,1,0) считались параллельными, что они явно не являются.
В приведенном ниже коде вы можете найти исправленную версию:
struct Vector3DComparator
{
bool operator() (const Vector3D& lhs, const Vector3D& rhs) const
{
if (isEqualEnough(fabs(lhs * rhs), 1.0)) // dot product
return false;
int p = 100000; // precision factor
auto lhsTied = std::tie((int)(lhs.x * p), (int)(lhs.y * p), (int)(lhs.z * p));
auto rhsTied = std::tie((int)(rhs.x * p), (int)(rhs.y * p), (int)(rhs.z * p));
return lhsTied < rhsTied;
}
};