summaryrefslogtreecommitdiffstats
path: root/src/2geom/basic-intersection.cpp
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2008-10-28 04:45:31 +0000
committerTed Gould <ted@canonical.com>2008-10-28 04:45:31 +0000
commitdc743aafd8b8c2d9c4e081fc937a94a26c055203 (patch)
tree98748c7465ac4ce06d1cbc359f767bcf0422cc85 /src/2geom/basic-intersection.cpp
parentFrom trunk (diff)
downloadinkscape-dc743aafd8b8c2d9c4e081fc937a94a26c055203.tar.gz
inkscape-dc743aafd8b8c2d9c4e081fc937a94a26c055203.zip
Merge from trunk
(bzr r6886)
Diffstat (limited to 'src/2geom/basic-intersection.cpp')
-rw-r--r--src/2geom/basic-intersection.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/2geom/basic-intersection.cpp b/src/2geom/basic-intersection.cpp
index 334c23fea..2a40e7f45 100644
--- a/src/2geom/basic-intersection.cpp
+++ b/src/2geom/basic-intersection.cpp
@@ -517,6 +517,86 @@ std::vector<std::pair<double, double> > find_intersections( OldBezier a, OldBezi
std::sort(parameters.begin(), parameters.end());
return parameters;
}
+
+
+/**
+ * Compute the Hausdorf distance from A to B only.
+ */
+double hausdorfl(D2<SBasis>& A, D2<SBasis> const& B,
+ double m_precision,
+ double *a_t, double* b_t) {
+ std::vector< std::pair<double, double> > xs;
+ std::vector<Point> Az, Bz;
+ sbasis_to_bezier (Az, A);
+ sbasis_to_bezier (Bz, B);
+ find_collinear_normal(xs, Az, Bz, m_precision);
+ double h_dist = 0, h_a_t = 0, h_b_t = 0;
+ double dist = 0;
+ Point Ax = A.at0();
+ double t = Geom::nearest_point(Ax, B);
+ dist = Geom::distance(Ax, B(t));
+ if (dist > h_dist) {
+ h_a_t = 0;
+ h_b_t = t;
+ h_dist = dist;
+ }
+ Ax = A.at1();
+ t = Geom::nearest_point(Ax, B);
+ dist = Geom::distance(Ax, B(t));
+ if (dist > h_dist) {
+ h_a_t = 1;
+ h_b_t = t;
+ h_dist = dist;
+ }
+ for (size_t i = 0; i < xs.size(); ++i)
+ {
+ Point At = A(xs[i].first);
+ Point Bu = B(xs[i].second);
+ double distAtBu = Geom::distance(At, Bu);
+ t = Geom::nearest_point(At, B);
+ dist = Geom::distance(At, B(t));
+ //FIXME: we might miss it due to floating point precision...
+ if (dist >= distAtBu-.1 && distAtBu > h_dist) {
+ h_a_t = xs[i].first;
+ h_b_t = xs[i].second;
+ h_dist = distAtBu;
+ }
+
+ }
+ if(a_t) *a_t = h_a_t;
+ if(b_t) *b_t = h_b_t;
+
+ return h_dist;
+}
+
+/**
+ * Compute the symmetric Hausdorf distance.
+ */
+double hausdorf(D2<SBasis>& A, D2<SBasis> const& B,
+ double m_precision,
+ double *a_t, double* b_t) {
+ double h_dist = hausdorfl(A, B, m_precision, a_t, b_t);
+
+ double dist = 0;
+ Point Bx = B.at0();
+ double t = Geom::nearest_point(Bx, A);
+ dist = Geom::distance(Bx, A(t));
+ if (dist > h_dist) {
+ if(a_t) *a_t = t;
+ if(b_t) *b_t = 0;
+ h_dist = dist;
+ }
+ Bx = B.at1();
+ t = Geom::nearest_point(Bx, A);
+ dist = Geom::distance(Bx, A(t));
+ if (dist > h_dist) {
+ if(a_t) *a_t = t;
+ if(b_t) *b_t = 1;
+ h_dist = dist;
+ }
+
+ return h_dist;
+}
};
/*