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.

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-checkins mailing list
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to