
On 21-Feb-2013 17:32, Krzysztof KosiĆski wrote:
2013/2/21 mathog <mathog@...1176...>:
Can somebody tell me what is wrong with this code (fragments shown below). It throws some sort of exception which Inkscape catches when it gets down to
(*result).back().append(ls);
This is throwing Geom::ContinuityError, because the initial point of the segment you are appending does not match the final point of the path. If the path is empty and default-constructed, its final point is (0,0). Admittedly this is not good API design - in this case the final point should be undefined until the first append() call. This was probably done to represent degenerate 1-point subpaths which can be constructed in SVG.
This problem can be avoided by a) constructing the path with the initial point of the first segment as a parameter b) using Geom::SVGPathGenerator.
Hmm, that does not quite fit with what I observed. In the end I programmed around the problem, whatever it is, like this:
... Geom::PathVector output; ... Geom::BezierCurve const *curve = dynamic_cast<Geom::BezierCurve const *>(&*cit); Geom::CubicBezier b((*curve)[0], (*curve)[1], (*curve)[2], (*curve)[3]); std::vectorGeom::Point bzrpoints = b.points(); Geom::Point A = bzrpoints[0]; Geom::Point B = bzrpoints[1]; Geom::Point C = bzrpoints[2]; Geom::Point D = bzrpoints[3]; std::vectorGeom::Point pointlist; pointlist.push_back(A); recursive_bezier4( A[X], A[Y], B[X], B[Y], C[X], C[Y], D[X], D[Y], pointlist, 0); pointlist.push_back(D); Geom::Point r0; Geom::Point r1 = pointlist[0]; for (unsigned int i=1; i<pointlist.size();i++){ r0 = r1; r1 = pointlist[i]; Geom::LineSegment ls(r0, r1); output.back().append(ls); } pointlist.clear();
where in recursive_bezier4() points were added like this:
void recursive_bezier4(const double x1, const double y1, const double x2, const double y2, const double x3, const double y3, const double x4, const double y4, std::vectorGeom::Point &m_points, int level) { ... m_points.push_back(Geom::Point(x2, y2)); // various points, not just these two ... }
In the first iteration of this approach the push_back() for points A and D were not present. This resulted in a path consisting of all the new midpoints, but not the original end points. The thing is, the (first) resultant output.back().append(ls) would blow up if called in recursive_bezier4(), but not when called, as above, outside of it. Yet the list of line segments it was being fed were identical in the two cases, so the first line segment was also the same. So the "first line segment does not match" error, if this is what it was (since I could never get by it), only triggered for append() in the recursive_bezier4() function, not in the pathv_to_linear() function which called it. How could object.back().append() distinguish between those two cases?
Anyway, since the current method works the question is somewhat academic - until the next time somebody tries to use output.back().append() in the same way.
Thanks,
David Mathog mathog@...1176... Manager, Sequence Analysis Facility, Biology Division, Caltech