summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e4b4843)
raw | patch | inline | side by side (parent: e4b4843)
author | cilix42 <cilix42@users.sourceforge.net> | |
Mon, 8 Sep 2008 22:20:36 +0000 (22:20 +0000) | ||
committer | cilix42 <cilix42@users.sourceforge.net> | |
Mon, 8 Sep 2008 22:20:36 +0000 (22:20 +0000) |
index 244328f8af7a8ec80b5592021063d709e5fed590..45d0b61f30b27aeaefc6e38506e866a28bb96dc4 100644 (file)
--- a/src/2geom/bezier-curve.h
+++ b/src/2geom/bezier-curve.h
Point ip = pointAt(from);
Point fp = pointAt(to);
Point v = fp - ip;
- double t = dot( p - ip, v ) / L2sq(v);
+ double l2v = L2sq(v);
+ if(l2v == 0) return 0;
+ double t = dot( p - ip, v ) / l2v;
if ( t <= 0 ) return from;
else if ( t >= 1 ) return to;
else return from + t*(to-from);
index 7dca7f0ebb8180c01f2c240fd7b80a3fe7643782..5b6d36c493776fbbec4e4231dd592a29c45433e8 100644 (file)
void
ConvexHull::graham() {
+ if(is_degenerate()) // nothing to do
+ return;
find_pivot();
angle_sort();
graham_scan();
index 71a47bb98eda11a6e70242b4094e186477e7d0f9..ea8718c5af5269acd8c4af1f0b56e2865c3f84b2 100644 (file)
--- a/src/2geom/convex-cover.h
+++ b/src/2geom/convex-cover.h
return pr;
}
+ConvexHull clip(ConvexHull const & ch, Point n, double d);
+
//TODO: reinstate
/*class ConvexCover{
public:
diff --git a/src/2geom/path.cpp b/src/2geom/path.cpp
index ac45459bd419779d07b6037ad5eac3ee40f76989..c04d9d08d4c7d3ddf134ffce434f6d0fd61602f5 100644 (file)
--- a/src/2geom/path.cpp
+++ b/src/2geom/path.cpp
@@ -226,6 +226,11 @@ double Path::nearestPoint(Point const &_point, double from, double to, double *d
double eif, et = modf(to, &eif);
unsigned int si = static_cast<unsigned int>(sif);
unsigned int ei = static_cast<unsigned int>(eif);
+ if(sz == 0) {// naked moveto
+ if (distance_squared != NULL)
+ *distance_squared = distanceSq(_point, _path.initialPoint());
+ return 0;
+ }
if ( si == sz )
{
--si;
diff --git a/src/2geom/path.h b/src/2geom/path.h
index 04b77862c25c715327b8e214cff6ec93964f1cfa..1b59ea011d4a566a31662ca0c128ac6826ea8f8d 100644 (file)
--- a/src/2geom/path.h
+++ b/src/2geom/path.h
{
THROW_RANGEERROR("parameter t out of bounds");
}
- if ( empty() ) return Point(0,0);
+ if ( empty() ) return initialPoint(); // naked moveto
double k, lt = modf(t, &k);
unsigned int i = static_cast<unsigned int>(k);
if ( i == sz )
{
THROW_RANGEERROR("parameter t out of bounds");
}
- if ( empty() ) return 0;
+ if ( empty() ) return initialPoint()[d]; // naked moveto
double k, lt = modf(t, &k);
unsigned int i = static_cast<unsigned int>(k);
if ( i == sz )
index 6d4e24c9fee595b6729d814e4e659832888037ca..39a00d8dc44f3803de14679a64233615a3a0e0b1 100644 (file)
--- a/src/2geom/pathvector.cpp
+++ b/src/2geom/pathvector.cpp
/* Note: undefined for empty pathvectors or pathvectors with empty paths.
* */
-PathVectorPosition nearestPoint(PathVector const & path_in, Point const& _point, double *distance_squared)
+boost::optional<PathVectorPosition> nearestPoint(PathVector const & path_in, Point const& _point, double *distance_squared)
{
- PathVectorPosition retval;
+ boost::optional<PathVectorPosition> retval;
double mindsq = infinity();
unsigned int i = 0;
for (Geom::PathVector::const_iterator pit = path_in.begin(); pit != path_in.end(); ++pit) {
double dsq;
double t = pit->nearestPoint(_point, &dsq);
+ //std::cout << t << "," << dsq << std::endl;
if (dsq < mindsq) {
mindsq = dsq;
- retval.path_nr = i;
- retval.t = t;
+ retval = PathVectorPosition(i, t);
}
++i;
@@ -114,6 +114,30 @@ PathVectorPosition nearestPoint(PathVector const & path_in, Point const& _point,
return retval;
}
+std::vector<PathVectorPosition> allNearestPoints(PathVector const & path_in, Point const& _point, double *distance_squared)
+{
+ std::vector<PathVectorPosition> retval;
+
+ double mindsq = infinity();
+ unsigned int i = 0;
+ for (Geom::PathVector::const_iterator pit = path_in.begin(); pit != path_in.end(); ++pit) {
+ double dsq;
+ double t = pit->nearestPoint(_point, &dsq);
+ if (dsq < mindsq) {
+ mindsq = dsq;
+ retval.push_back(PathVectorPosition(i, t));
+ }
+
+ ++i;
+ }
+
+ if (distance_squared) {
+ *distance_squared = mindsq;
+ }
+ return retval;
+
+}
+
} // namespace Geom
#endif // SEEN_GEOM_PATHVECTOR_CPP
diff --git a/src/2geom/pathvector.h b/src/2geom/pathvector.h
index cec1c144a0ebcff0e3f1e3b6e162b6ebc0dbfd13..cdc774c557bb39540b93c8d8d2f6254c7ec6aa62 100644 (file)
--- a/src/2geom/pathvector.h
+++ b/src/2geom/pathvector.h
// pathvector[path_nr].pointAt(t) is the position
unsigned int path_nr;
double t;
+ PathVectorPosition() {}
+ PathVectorPosition(unsigned int path_nr,
+ double t) : path_nr(path_nr), t(t) {}
};
-PathVectorPosition nearestPoint(PathVector const & path_in, Point const& _point, double *distance_squared = NULL);
+boost::optional<PathVectorPosition> nearestPoint(PathVector const & path_in, Point const& _point, double *distance_squared = NULL);
+
+std::vector<PathVectorPosition> allNearestPoints(PathVector const & path_in, Point const& _point, double *distance_squared = NULL);
+
+inline
+Point pointAt(PathVector const & path_in, PathVectorPosition const pvp) {
+ return path_in[pvp.path_nr].pointAt(pvp.t);
+}
+
} // end namespace Geom
diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index e049c40df15bd025f9beee813879d1732726a820..5345485e2fb682a86d0bced868765de0618649da 100644 (file)
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
@@ -1960,11 +1960,15 @@ sp_nodepath_select_segment_near_point(Inkscape::NodePath::Path *nodepath, NR::Po
SPCurve *curve = create_curve(nodepath); // perhaps we can use nodepath->curve here instead?
Geom::PathVector const &pathv = curve->get_pathvector();
- Geom::PathVectorPosition pvpos = Geom::nearestPoint(pathv, p);
+ boost::optional<Geom::PathVectorPosition> pvpos = Geom::nearestPoint(pathv, p);
+ if (!pvpos) {
+ g_print ("Possible error?\n");
+ return;
+ }
// calculate index for nodepath's representation.
- unsigned int segment_index = floor(pvpos.t) + 1;
- for (unsigned int i = 0; i < pvpos.path_nr; ++i) {
+ unsigned int segment_index = floor(pvpos->t) + 1;
+ for (unsigned int i = 0; i < pvpos->path_nr; ++i) {
segment_index += pathv[i].size() + 1;
if (pathv[i].closed()) {
segment_index += 1;
@@ -2004,13 +2008,17 @@ sp_nodepath_add_node_near_point(Inkscape::NodePath::Path *nodepath, NR::Point p)
SPCurve *curve = create_curve(nodepath); // perhaps we can use nodepath->curve here instead?
Geom::PathVector const &pathv = curve->get_pathvector();
- Geom::PathVectorPosition pvpos = Geom::nearestPoint(pathv, p);
+ boost::optional<Geom::PathVectorPosition> pvpos = Geom::nearestPoint(pathv, p);
+ if (!pvpos) {
+ g_print ("Possible error?\n");
+ return;
+ }
// calculate index for nodepath's representation.
double int_part;
- double t = std::modf(pvpos.t, &int_part);
+ double t = std::modf(pvpos->t, &int_part);
unsigned int segment_index = (unsigned int)int_part + 1;
- for (unsigned int i = 0; i < pvpos.path_nr; ++i) {
+ for (unsigned int i = 0; i < pvpos->path_nr; ++i) {
segment_index += pathv[i].size() + 1;
if (pathv[i].closed()) {
segment_index += 1;
diff --git a/src/shape-editor.cpp b/src/shape-editor.cpp
index f7aefdabec85566f038a04c5738b3bb03910fe4b..32c20ace698a6fd1f751b71207563ed266b5f5d7 100644 (file)
--- a/src/shape-editor.cpp
+++ b/src/shape-editor.cpp
SPCurve *curve = this->nodepath->curve; // not sure if np->curve is always up to date...
Geom::PathVector const &pathv = curve->get_pathvector();
- Geom::PathVectorPosition pvpos = Geom::nearestPoint(pathv, this->curvepoint_doc);
+ boost::optional<Geom::PathVectorPosition> pvpos = Geom::nearestPoint(pathv, this->curvepoint_doc);
+ if (!pvpos) {
+ g_print("Warning! Possible error?\n");
+ return false;
+ }
- NR::Point nearest = pathv[pvpos.path_nr].pointAt(pvpos.t);
+ NR::Point nearest = pathv[pvpos->path_nr].pointAt(pvpos->t);
NR::Point delta = nearest - this->curvepoint_doc;
delta = desktop->d2w(delta);
if (remember && close) {
// calculate index for nodepath's representation.
double int_part;
- double t = std::modf(pvpos.t, &int_part);
+ double t = std::modf(pvpos->t, &int_part);
unsigned int segment_index = (unsigned int)int_part + 1;
- for (unsigned int i = 0; i < pvpos.path_nr; ++i) {
+ for (unsigned int i = 0; i < pvpos->path_nr; ++i) {
segment_index += pathv[i].size() + 1;
if (pathv[i].closed())
segment_index += 1;