summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMaximilian Albert <maximilian.albert@gmail.com>2008-09-08 22:20:36 +0000
committercilix42 <cilix42@users.sourceforge.net>2008-09-08 22:20:36 +0000
commitb7b17f36b9e3d2814dcf0f4db1fb329976c2e85a (patch)
tree7d9c97f8bd561cd70afd0fe44e507a6e4f91dfd3 /src
parentadd missing #include for gtk version check (diff)
downloadinkscape-b7b17f36b9e3d2814dcf0f4db1fb329976c2e85a.tar.gz
inkscape-b7b17f36b9e3d2814dcf0f4db1fb329976c2e85a.zip
2geom update (rev. 1578); fixes node editing of some degenerate paths
(bzr r6784)
Diffstat (limited to 'src')
-rw-r--r--src/2geom/bezier-curve.h4
-rw-r--r--src/2geom/convex-cover.cpp2
-rw-r--r--src/2geom/convex-cover.h2
-rw-r--r--src/2geom/path.cpp5
-rw-r--r--src/2geom/path.h4
-rw-r--r--src/2geom/pathvector.cpp32
-rw-r--r--src/2geom/pathvector.h13
-rw-r--r--src/nodepath.cpp20
-rw-r--r--src/shape-editor.cpp12
9 files changed, 76 insertions, 18 deletions
diff --git a/src/2geom/bezier-curve.h b/src/2geom/bezier-curve.h
index 244328f8a..45d0b61f3 100644
--- a/src/2geom/bezier-curve.h
+++ b/src/2geom/bezier-curve.h
@@ -202,7 +202,9 @@ double LineSegment::nearestPoint(Point const& p, double from, double to) const
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);
diff --git a/src/2geom/convex-cover.cpp b/src/2geom/convex-cover.cpp
index 7dca7f0eb..5b6d36c49 100644
--- a/src/2geom/convex-cover.cpp
+++ b/src/2geom/convex-cover.cpp
@@ -136,6 +136,8 @@ ConvexHull::graham_scan() {
void
ConvexHull::graham() {
+ if(is_degenerate()) // nothing to do
+ return;
find_pivot();
angle_sort();
graham_scan();
diff --git a/src/2geom/convex-cover.h b/src/2geom/convex-cover.h
index 71a47bb98..ea8718c5a 100644
--- a/src/2geom/convex-cover.h
+++ b/src/2geom/convex-cover.h
@@ -152,6 +152,8 @@ template <class T> ConvexHull operator*(ConvexHull const &p, T const &m) {
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 ac45459bd..c04d9d08d 100644
--- 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 04b77862c..1b59ea011 100644
--- a/src/2geom/path.h
+++ b/src/2geom/path.h
@@ -306,7 +306,7 @@ public:
{
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 )
@@ -325,7 +325,7 @@ public:
{
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 )
diff --git a/src/2geom/pathvector.cpp b/src/2geom/pathvector.cpp
index 6d4e24c9f..39a00d8dc 100644
--- a/src/2geom/pathvector.cpp
+++ b/src/2geom/pathvector.cpp
@@ -90,19 +90,19 @@ Rect bounds_exact( PathVector const& pv )
/* 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 cec1c144a..cdc774c55 100644
--- a/src/2geom/pathvector.h
+++ b/src/2geom/pathvector.h
@@ -108,8 +108,19 @@ struct PathVectorPosition {
// 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 e049c40df..5345485e2 100644
--- 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 f7aefdabe..32c20ace6 100644
--- a/src/shape-editor.cpp
+++ b/src/shape-editor.cpp
@@ -366,9 +366,13 @@ bool ShapeEditor::is_over_stroke (NR::Point event_p, bool remember) {
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);
@@ -385,9 +389,9 @@ bool ShapeEditor::is_over_stroke (NR::Point event_p, bool remember) {
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;