|
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.
|