Commit 7b55a3f0 authored by Kenneth Moreland's avatar Kenneth Moreland
Browse files

Normal of zero vectors

The normal of a vector is the vector divided by the vector's magnitude.
However, if the vector is the 0 vector, you get 0/0, which results in
non-finite numbers.

There might be legitimate situations where you (unintentionally) try to
normalize a 0 vector. For example, you might be using the derivative of
a field to compute the normal to a contour of the field. If the field is
in a static region or critical point, then the gradient goes to 0.

In these cases, we want the `Normal` and `Normalize` functions to return
something reasonable. These functions now return the 0 vector back. This
is no more "correct" than producing NaN values, but it is less likely to
cause problems later.
parent 4cb94e7f
Pipeline #176336 passed with stages
in 160 minutes and 43 seconds
# Normal of zero vectors
The normal of a vector is the vector divided by the vector's magnitude.
However, if the vector is the 0 vector, you get 0/0, which results in
non-finite numbers.
There might be legitimate situations where you (unintentionally) try to
normalize a 0 vector. For example, you might be using the derivative of a
field to compute the normal to a contour of the field. If the field is in a
static region or critical point, then the gradient goes to 0.
In these cases, we want the `Normal` and `Normalize` functions to return
something reasonable. These functions now return the 0 vector back. This is
no more "correct" than producing NaN values, but it is less likely to cause
problems later.
......@@ -156,7 +156,15 @@ VTKM_EXEC_CONT T NormalTemplate(const T& x, vtkm::TypeTraitsVectorTag)
template <typename T>
VTKM_EXEC_CONT T Normal(const T& x)
{
return detail::NormalTemplate(x, typename vtkm::TypeTraits<T>::DimensionalityTag());
if (x != vtkm::TypeTraits<T>::ZeroInitialization())
{
return detail::NormalTemplate(x, typename vtkm::TypeTraits<T>::DimensionalityTag());
}
else
{
// Trying to take the normal of a 0 vector. Just return the vector.
return x;
}
}
// ----------------------------------------------------------------------------
......
......@@ -90,6 +90,16 @@ void TestVector(const VectorType& vector)
VTKM_TEST_ASSERT(test_equal(normalizedVector, internal::MyNormal(vector)),
"Inplace Normalized vector failed test.");
}
else
{
// If the magnitude is 0, then we expect the Normal functions to return 0 vectors.
std::cout << " Normal" << std::endl;
VTKM_TEST_ASSERT(test_equal(vtkm::Normal(vector), VectorType(0)), "Normal of 0 vector failed.");
std::cout << " Normalize" << std::endl;
VectorType normalizedVector = vector;
vtkm::Normalize(normalizedVector);
VTKM_TEST_ASSERT(test_equal(normalizedVector, VectorType(0)), "Normalized 0 vector failed.");
}
}
template <typename VectorType>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment