`GfPlane::_distance` appears to have the wrong sign or docs could use some more clarification
Opened this issue · 3 comments
Description of Issue
According to this comment block, the equation of a plane in GfPlane
is in standard form :
Lines 66 to 70 in 9b0c13b
Since all constructors normalize the incoming normal
vector, we can further assume that GfPlane
is in Hessian Normal Form. We can derive that form here.
For brevity, we can map the code to the variables above : eqn[0]
= eqn[1]
= eqn[2]
= eqn[3]
=
The following block expands the vector of coefficients eqn
but sets _distance = -eqn[3]
=
Lines 44 to 56 in 9b0c13b
We can derive the point
Plugging in
I was curious if this is a bug or an undocumented sign convention. All other "distance" functions use -_distance
so I believe GfPlane
is self consistent. The only one that actually returns GfPlane::GetDistanceFromOrigin
.
Steps to Reproduce
N/A
System Information (OS, Hardware)
N/A
Package Versions
N/A
Build Flags
N/A
If you look at the some of the other Set functions
void
GfPlane::Set(const GfVec3d &normal, const GfVec3d &point)
{
_normal = normal.GetNormalized();
_distance = GfDot(_normal, point);
}
void
GfPlane::Set(const GfVec3d &p0, const GfVec3d &p1, const GfVec3d &p2)
{
_normal = GfCross(p1 - p0, p2 - p0).GetNormalized();
_distance = GfDot(_normal, p0);
}
void
GfPlane::Set(const GfVec4d &eqn)
{
for (size_t i = 0; i < 3; i++) {
_normal[i] = eqn[i];
}
_distance = -eqn[3];
const double l = _normal.Normalize();
if (l != 0.0) {
_distance /= l;
}
}
We can see that _distance follows the convention that a positive distance represents the side of the plane in the direction of the normal vector. As you mentioned, GfPlane is self consistent in this regard.
In the GfVec4 case, the plane equation is given as Ax+By+Cz+D=0. To store the distance in the conventional signed form,
D (aka eqn[3]) is moved to the other side of the equation and negated. So, the signed distance is consistent with the convention used by the other Set functions.
I see your point about clarity, perhaps an additional comment on that Set could mention that the plane is stored as
{ eqn[0], eqn[1],+ eqn[2], distance } and therefore distance is -eqn[3].
Thanks so much for the quick response - I think I understand what the code is doing now.
To rephrase a little : _distance
is always the distance along the normal vector.
In standard form, the distance from the origin of a plane defined by
This is undesirable for graphics applications because it's more intuitive to think about distance along the plane normal to be positive. The standard form considers the distance away from the plane normal to be positive (ie : the plane is running away from the origin).
OpenUSD resolves this with a slight reformulation of the plane equation :
So that now when we try to find the point to plane distance :
Like you said, I think the confusion can be resolved with just a single comment, so that those who are expecting the standard form know not to look for it :
- /// \p eqn[0] * x + \p eqn[1] * y + \p eqn[2] * z + \p eqn[3] = 0.
+ /// \p eqn[0] * x + \p eqn[1] * y + \p eqn[2] * z - \p eqn[3] = 0.
Thanks again for your help!
Filed as internal issue #USD-10460