From: <ef...@us...> - 2008-10-09 01:20:07
|
Revision: 6174 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6174&view=rev Author: efiring Date: 2008-10-09 01:19:54 +0000 (Thu, 09 Oct 2008) Log Message: ----------- path simplification for paths with gaps Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/examples/pylab_examples/clippedline.py trunk/matplotlib/lib/matplotlib/path.py trunk/matplotlib/src/agg_py_path_iterator.h Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2008-10-08 19:53:57 UTC (rev 6173) +++ trunk/matplotlib/CHANGELOG 2008-10-09 01:19:54 UTC (rev 6174) @@ -1,3 +1,5 @@ +2008-10-08 Add path simplification support to paths with gaps. - EF + 2008-10-05 Fix problem with AFM files that don't specify the font's full name or family name. - JKS Modified: trunk/matplotlib/examples/pylab_examples/clippedline.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/clippedline.py 2008-10-08 19:53:57 UTC (rev 6173) +++ trunk/matplotlib/examples/pylab_examples/clippedline.py 2008-10-09 01:19:54 UTC (rev 6174) @@ -19,7 +19,7 @@ def set_data(self, *args, **kwargs): Line2D.set_data(self, *args, **kwargs) - if self._invalid: + if self._invalid: self.recache() self.xorig = np.array(self._x) self.yorig = np.array(self._y) Modified: trunk/matplotlib/lib/matplotlib/path.py =================================================================== --- trunk/matplotlib/lib/matplotlib/path.py 2008-10-08 19:53:57 UTC (rev 6173) +++ trunk/matplotlib/lib/matplotlib/path.py 2008-10-09 01:19:54 UTC (rev 6174) @@ -109,9 +109,8 @@ assert vertices.ndim == 2 assert vertices.shape[1] == 2 - self.should_simplify = (codes is None and - np.all(np.isfinite(vertices)) and - len(vertices) >= 128) + self.should_simplify = (len(vertices) >= 128 and + (codes is None or np.all(codes <= Path.LINETO))) self.codes = codes self.vertices = vertices Modified: trunk/matplotlib/src/agg_py_path_iterator.h =================================================================== --- trunk/matplotlib/src/agg_py_path_iterator.h 2008-10-08 19:53:57 UTC (rev 6173) +++ trunk/matplotlib/src/agg_py_path_iterator.h 2008-10-09 01:19:54 UTC (rev 6174) @@ -137,7 +137,8 @@ double width = 0.0, double height = 0.0) : m_source(&source), m_quantize(quantize), m_simplify(simplify), m_width(width + 1.0), m_height(height + 1.0), m_queue_read(0), m_queue_write(0), - m_moveto(true), m_lastx(0.0), m_lasty(0.0), m_clipped(false), + m_moveto(true), m_after_moveto(false), + m_lastx(0.0), m_lasty(0.0), m_clipped(false), m_do_clipping(width > 0.0 && height > 0.0), m_origdx(0.0), m_origdy(0.0), m_origdNorm2(0.0), m_dnorm2Max(0.0), m_dnorm2Min(0.0), @@ -205,6 +206,7 @@ *y = front.y; #if DEBUG_SIMPLIFY printf((cmd == agg::path_cmd_move_to) ? "|" : "-"); + printf(" 1 %f %f\n", *x, *y); #endif return cmd; } @@ -239,18 +241,40 @@ //if we are starting a new path segment, move to the first point // + init - if (m_moveto) + +#if DEBUG_SIMPLIFY + printf("x, y, code: %f, %f, %d\n", *x, *y, cmd); +#endif + if (m_moveto || cmd == agg::path_cmd_move_to) { + // m_moveto check is not generally needed because + // m_source generates an initial moveto; but it + // is retained for safety in case circumstances + // arise where this is not true. + if (m_origdNorm2 && !m_after_moveto) + { + // m_origdNorm2 is nonzero only if we have a vector; + // the m_after_moveto check ensures we push this + // vector to the queue only once. + _push(x,y); + } + m_after_moveto = true; m_lastx = *x; m_lasty = *y; m_moveto = false; m_origdNorm2 = 0.0; -#if DEBUG_SIMPLIFY - m_pushed++; - printf("|"); -#endif - return agg::path_cmd_move_to; + // A moveto resulting from a nan yields a missing + // line segment, hence a break in the line, just + // like clipping, so we treat it the same way. + m_clipped = true; + if (m_queue_read < m_queue_write) + { + // If we did a push, empty the queue now. + break; + } + continue; } + m_after_moveto = false; // Don't render line segments less than one pixel long if (fabs(*x - m_lastx) < 1.0 && fabs(*y - m_lasty) < 1.0) @@ -295,7 +319,7 @@ m_origdy = *y - m_lasty; m_origdNorm2 = m_origdx*m_origdx + m_origdy*m_origdy; - //set all the variables to reflect this new orig vecor + //set all the variables to reflect this new orig vector m_dnorm2Max = m_origdNorm2; m_dnorm2Min = 0.0; m_haveMin = false; @@ -376,7 +400,6 @@ #endif continue; } - //if we get here, then this vector was not similar enough to the //line we are building, so we need to draw that line and start the //next one. @@ -384,46 +407,9 @@ //if the line needs to extend in the opposite direction from the //direction we are drawing in, move back to we start drawing from //back there. - if (m_haveMin) - { - m_queue[m_queue_write++].set(agg::path_cmd_line_to, m_minX, m_minY); - } - m_queue[m_queue_write++].set(agg::path_cmd_line_to, m_maxX, m_maxY); - //if we clipped some segments between this line and the next line - //we are starting, we also need to move to the last point. - if (m_clipped) { - m_queue[m_queue_write++].set(agg::path_cmd_move_to, m_lastx, m_lasty); - } - else if (!m_lastMax) - { - //if the last line was not the longest line, then move back to - //the end point of the last line in the sequence. Only do this - //if not clipped, since in that case lastx,lasty is not part of - //the line just drawn. + _push(x, y); - //Would be move_to if not for the artifacts - m_queue[m_queue_write++].set(agg::path_cmd_line_to, m_lastx, m_lasty); - } - - //now reset all the variables to get ready for the next line - m_origdx = *x - m_lastx; - m_origdy = *y - m_lasty; - m_origdNorm2 = m_origdx*m_origdx + m_origdy*m_origdy; - - m_dnorm2Max = m_origdNorm2; - m_dnorm2Min = 0.0; - m_haveMin = false; - m_lastMax = true; - m_lastx = m_maxX = *x; - m_lasty = m_maxY = *y; - m_lastWrittenX = m_minX = m_lastx; - m_lastWrittenY = m_minY = m_lasty; - - m_clipped = false; -#if DEBUG_SIMPLIFY - m_pushed += m_queue_write - m_queue_read; -#endif break; } @@ -453,6 +439,8 @@ *y = front.y; #if DEBUG_SIMPLIFY printf((cmd == agg::path_cmd_move_to) ? "|" : "-"); + printf(" 3 %f %f\n", *x, *y); + #endif return cmd; } @@ -489,6 +477,7 @@ item m_queue[6]; bool m_moveto; + bool m_after_moveto; double m_lastx, m_lasty; bool m_clipped; bool m_do_clipping; @@ -512,6 +501,52 @@ unsigned m_pushed; unsigned m_skipped; #endif + + void _push(double* x, double* y) + { + if (m_haveMin) + { + m_queue[m_queue_write++].set(agg::path_cmd_line_to, m_minX, m_minY); + } + m_queue[m_queue_write++].set(agg::path_cmd_line_to, m_maxX, m_maxY); + + //if we clipped some segments between this line and the next line + //we are starting, we also need to move to the last point. + if (m_clipped) { + m_queue[m_queue_write++].set(agg::path_cmd_move_to, m_lastx, m_lasty); + } + else if (!m_lastMax) + { + //if the last line was not the longest line, then move back to + //the end point of the last line in the sequence. Only do this + //if not clipped, since in that case lastx,lasty is not part of + //the line just drawn. + + //Would be move_to if not for the artifacts + m_queue[m_queue_write++].set(agg::path_cmd_line_to, m_lastx, m_lasty); + } + + //now reset all the variables to get ready for the next line + m_origdx = *x - m_lastx; + m_origdy = *y - m_lasty; + m_origdNorm2 = m_origdx*m_origdx + m_origdy*m_origdy; + + m_dnorm2Max = m_origdNorm2; + m_dnorm2Min = 0.0; + m_haveMin = false; + m_lastMax = true; + m_lastx = m_maxX = *x; + m_lasty = m_maxY = *y; + m_lastWrittenX = m_minX = m_lastx; + m_lastWrittenY = m_minY = m_lasty; + + m_clipped = false; +#if DEBUG_SIMPLIFY + m_pushed += m_queue_write - m_queue_read; +#endif + + } + }; #endif // __AGG_PY_PATH_ITERATOR_H__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |