-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong calculation of pldist #13
Comments
anton-petrov
added a commit
to anton-petrov/rdp
that referenced
this issue
Mar 5, 2022
Source: fhirschmann#13. The current pldist function returns the distance between a point and the infinte line generated by two other points (i.e the distance to the orthogonal projection), which is incorrect. It should return the distance between a point and a line-segment. Here is a fix coming from this answer https://stackoverflow.com/a/54442561.
pybind11-rdp handles this pretty well: https://github.com/cubao/pybind11-rdp/blob/master/src/main.cpp#L26-L37 struct LineSegment
{
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
const Eigen::Vector3d A, B, AB;
const double len2, inv_len2;
LineSegment(const Eigen::Vector3d &a, const Eigen::Vector3d &b)
: A(a), B(b), AB(b - a), //
len2((b - a).squaredNorm()), inv_len2(1.0 / len2)
{
}
double distance2(const Eigen::Vector3d &P) const
{
double dot = (P - A).dot(AB);
if (dot <= 0) {
return (P - A).squaredNorm();
} else if (dot >= len2) {
return (P - B).squaredNorm();
}
// P' = A + dot/length * normed(AB)
// = A + dot * AB / (length^2)
return (A + (dot * inv_len2 * AB) - P).squaredNorm();
}
double distance(const Eigen::Vector3d &P) const
{
return std::sqrt(distance2(P));
}
}; Some tests: TEST(RdpTest, Distance)
{
auto seg = LineSegment({0.0, 0.0, 0.0}, {10.0, 0.0, 0.0});
ASSERT_EQ(4.0, dbg(seg.distance({5.0, 4.0, 0.0})));
ASSERT_EQ(5.0, dbg(seg.distance({-4.0, 3.0, 0.0})));
ASSERT_EQ(5.0, dbg(seg.distance({14.0, 3.0, 0.0})));
}
TEST(RdpTest, Distance_dup)
{
auto seg = LineSegment({0.0, 0.0, 0.0}, {0.0, 0.0, 0.0});
ASSERT_EQ(5.0, dbg(seg.distance({3.0, 4.0, 0.0})));
ASSERT_EQ(5.0, dbg(seg.distance({-4.0, 3.0, 0.0})));
ASSERT_EQ(13.0, dbg(seg.distance({5.0, 12.0, 0.0})));
} |
这是来自QQ邮箱的假期自动回复邮件。你好,我最近正在休假中,无法亲自回复你的邮件。我将在假期结束后,尽快给你回复。
|
As #13 points out, pdist in rdp is WRONGLY Point-to-Line distance. We (pybind11_rdp) use Point-to-LineSegment distance. from rdp import rdp
print(rdp([[0, 0], [10, 0.1], [1, 0]], epsilon=1.0)) # wrong
# [[0.0, 0.0],
# [1.0, 0.0]]
from pybind11_rdp import rdp
print(rdp([[0, 0], [10, 0.1], [1, 0]], epsilon=1.0)) # correct
# [[ 0. 0. ]
# [10. 0.1]
# [ 1. 0. ]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The current
pldist
function returns the distance between a point and the infinte line generated by two other points (i.e the distance to the orthogonal projection), which is incorrect. It should return the distance between a point and a line-segment.Here is a fix coming from this answer https://stackoverflow.com/a/54442561:
The text was updated successfully, but these errors were encountered: