[mapguide-commits] r1316 - trunk/MgDev/Common/Stylization

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Mar 21 12:30:13 EDT 2007


Author: traianstanev
Date: 2007-03-21 12:30:13 -0400 (Wed, 21 Mar 2007)
New Revision: 1316

Modified:
   trunk/MgDev/Common/Stylization/SE_ConvexHull.h
   trunk/MgDev/Common/Stylization/SE_LineBuffer.cpp
   trunk/MgDev/Common/Stylization/SE_LineBuffer.h
Log:
Computation of convex hulls of Path elements was a slug due to repeated calls to std::set::insert. I replaced the use of std::set by an std::vector and updated the remaining code to reflect that. Also had an issue with the post-decrement operator not working correctly on vector iterators, so I worked around that in the convex hull code by moving the decrement to a statement of its own in two of the loops.

Modified: trunk/MgDev/Common/Stylization/SE_ConvexHull.h
===================================================================
--- trunk/MgDev/Common/Stylization/SE_ConvexHull.h	2007-03-21 16:27:25 UTC (rev 1315)
+++ trunk/MgDev/Common/Stylization/SE_ConvexHull.h	2007-03-21 16:30:13 UTC (rev 1316)
@@ -97,8 +97,10 @@
     *stack++ = pnt.y(minxmaxy);
     iter = minxmaxy;
 
-    while (iter++ != maxxminy)
+    while (iter != maxxminy)
     {
+        iter++;
+
         if (PointLeft(pnt.x(minxminy), pnt.y(minxminy), pnt.x(maxxminy), pnt.y(maxxminy), pnt.x(iter), pnt.y(iter)) && iter != maxxminy)
         /* this point is trivially above the lower bounding line, and cannot be in the lower hull */
             continue;
@@ -124,8 +126,10 @@
     }
     iter = maxxminy;
 
-    while (iter-- != minxmaxy)
+    while (iter != minxmaxy)
     {
+        iter --;
+
         if (PointLeft(pnt.x(maxxmaxy), pnt.y(maxxmaxy), pnt.x(minxmaxy), pnt.y(minxmaxy), pnt.x(iter), pnt.y(iter)) && iter != minxmaxy)
         /* this point is trivially below the upper bounding line, and cannot be in the upper hull */
             continue;

Modified: trunk/MgDev/Common/Stylization/SE_LineBuffer.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/SE_LineBuffer.cpp	2007-03-21 16:27:25 UTC (rev 1315)
+++ trunk/MgDev/Common/Stylization/SE_LineBuffer.cpp	2007-03-21 16:30:13 UTC (rev 1316)
@@ -20,6 +20,7 @@
 #include "SE_LineBuffer.h"
 #include "SE_ConvexHull.h"
 #include "SE_Bounds.h"
+#include <algorithm>
 
 #define GROWTH_FACTOR 1.5
 
@@ -268,29 +269,32 @@
 
 struct PointUtil
 {
-    SE_INLINE double x(std::set<std::pair<double,double>, PointLess>::iterator iter)
+    SE_INLINE double x(PointList::iterator iter)
     {
         return (*iter).first;
     }
 
-    SE_INLINE double y(std::set<std::pair<double,double>, PointLess>::iterator iter)
+    SE_INLINE double y(PointList::iterator iter)
     {
         return (*iter).second;
     }
 
-    SE_INLINE bool equal(std::set<std::pair<double,double>, PointLess>::iterator a,
-                         std::set<std::pair<double,double>, PointLess>::iterator b)
+    SE_INLINE bool equal(PointList::iterator a, PointList::iterator b)
     {
         return ((*a).first == (*b).first) && ((*a).second == (*b).second);
     }
 };
 
-SE_Bounds* SE_LineBuffer::ComputeConvexHull(double* pnts, int* cntrs, int ncntrs, double weight)
+SE_Bounds* SE_LineBuffer::ComputeConvexHull(double* pnts, int npts, int* cntrs, int ncntrs, double weight)
 {
     if (ncntrs == 0)
         return NULL;
     // Monotone Chain Convex Hull Algorithm (Andrew, 1979)
     m_ch_ptbuf.clear();
+    if (weight == 0)
+        m_ch_ptbuf.reserve(npts);    
+    else
+        m_ch_ptbuf.reserve(npts*4);
 
     double hweight = weight/2.0;
     double* cur = pnts;
@@ -310,20 +314,20 @@
             /* For each segment, add the bounding box of the rectangle formed by applying line weight */
             /* TODO: this result will be correct if the line is drawn with bevel joins...Map and MG,
                however, appear to be using round joins at the moment. */
-            m_ch_ptbuf.insert(std::pair<double,double>(x + vx, y + vy));
-            m_ch_ptbuf.insert(std::pair<double,double>(x - vx, y - vy));
-            m_ch_ptbuf.insert(std::pair<double,double>(lx + vx, ly + vy));
-            m_ch_ptbuf.insert(std::pair<double,double>(lx - vx, ly - vy));
+            m_ch_ptbuf.push_back(std::pair<double,double>(x + vx, y + vy));
+            m_ch_ptbuf.push_back(std::pair<double,double>(x - vx, y - vy));
+            m_ch_ptbuf.push_back(std::pair<double,double>(lx + vx, ly + vy));
+            m_ch_ptbuf.push_back(std::pair<double,double>(lx - vx, ly - vy));
 
             while(cur < last)
             {
                 x = *cur++;
                 y = *cur++;
                 LineExt(x-lx, y-ly, hweight, vx, vy);
-                m_ch_ptbuf.insert(std::pair<double,double>(x + vx, y + vy));
-                m_ch_ptbuf.insert(std::pair<double,double>(x - vx, y - vy));
-                m_ch_ptbuf.insert(std::pair<double,double>(lx + vx, ly + vy));
-                m_ch_ptbuf.insert(std::pair<double,double>(lx - vx, ly - vy));
+                m_ch_ptbuf.push_back(std::pair<double,double>(x + vx, y + vy));
+                m_ch_ptbuf.push_back(std::pair<double,double>(x - vx, y - vy));
+                m_ch_ptbuf.push_back(std::pair<double,double>(lx + vx, ly + vy));
+                m_ch_ptbuf.push_back(std::pair<double,double>(lx - vx, ly - vy));
                 lx = x;
                 ly = y;
             }
@@ -335,18 +339,19 @@
             {
                 x = *cur++;
                 y = *cur++;
-                m_ch_ptbuf.insert(std::pair<double,double>(x, y));
+                m_ch_ptbuf.push_back(std::pair<double,double>(x, y));
             }
         }
     }
 
-    std::set<std::pair<double,double>, PointLess>::iterator end = m_ch_ptbuf.end();
-    std::set<std::pair<double,double>, PointLess>::iterator iter = m_ch_ptbuf.begin();
+    std::sort(m_ch_ptbuf.begin(), m_ch_ptbuf.end(), PointLess());
 
+    PointList::iterator end = m_ch_ptbuf.end();
+    PointList::iterator iter = m_ch_ptbuf.begin();
+
     if (m_ch_ptbuf.size() < 2)
         return NULL;
-    return AndrewHull<std::set<std::pair<double,double>, PointLess>::iterator, PointUtil>
-        (iter, --end, (int)m_ch_ptbuf.size(), m_pool);
+    return AndrewHull<PointList::iterator, PointUtil>(iter, --end, (int)m_ch_ptbuf.size(), m_pool);
 }
 
 SE_LineBuffer::SE_LineBuffer(int size) :
@@ -621,7 +626,7 @@
     }
 
     if (m_compute_bounds)
-        m_xf_bounds = ComputeConvexHull(m_xf_buf->points(), m_xf_buf->cntrs(), m_xf_buf->cntr_count(), m_xf_weight);
+        m_xf_bounds = ComputeConvexHull(m_xf_buf->points(), m_xf_buf->point_count(), m_xf_buf->cntrs(), m_xf_buf->cntr_count(), m_xf_weight);
     if (m_xf_bounds)
         m_xf_buf->SetBounds(m_xf_bounds);
 

Modified: trunk/MgDev/Common/Stylization/SE_LineBuffer.h
===================================================================
--- trunk/MgDev/Common/Stylization/SE_LineBuffer.h	2007-03-21 16:27:25 UTC (rev 1315)
+++ trunk/MgDev/Common/Stylization/SE_LineBuffer.h	2007-03-21 16:30:13 UTC (rev 1316)
@@ -35,6 +35,7 @@
     }
 };
 
+typedef std::vector<std::pair<double, double> > PointList;
 //---------------------------------------------
 //---------------------------------------------
 
@@ -72,7 +73,7 @@
     void Reset();
     void ResizeBuffer(void** buffer, int unitsize, int mininc, int cur_pts, int& max_pts);
     void TessellateCubicTo(SE_LineStorage* pts, double px2, double py2, double px3, double py3, double px4, double py4, int steps);
-    SE_Bounds* ComputeConvexHull(double* pnts, int* cntrs, int ncntrs, double weight);
+    SE_Bounds* ComputeConvexHull(double* pnts, int npts, int* cntrs, int ncntrs, double weight);
 
     SE_LineBufferPool* m_pool;
 
@@ -95,7 +96,7 @@
     SE_LineStorage* m_xf_buf;
 
     /* TODO: write a stack based allocator for this, or replace it */
-    std::set<std::pair<double, double>, PointLess> m_ch_ptbuf;
+    PointList m_ch_ptbuf;
 };
 
 //---------------------------------------------



More information about the mapguide-commits mailing list