c# - How can I get "thinner" graph for my coordinate system? -


following this, have bunch of coordinates , draw them on bitmap image coordinate system. now, rid of noise, , filter coordinates give "clearer" or "cleaner" path , "less" or "better" data work on. explain more, need expose awesome painting skills follows:

current:

enter image description here

desired:

enter image description here

notice:

  • i need delete coordinates

  • i might need add coordinates

  • i might need ignore shortest neighbor in cases

the thing can think of, use shortest path algorithm such a* , dijkstra. , populate data in sort of data structure contain neighbors , costs every node , execute algorithm. don't want start might wrong or waste. love see pseudo code if possible on how solve such problem?

p.s on wpf c# open use c# or c++ task. thanks

what you're after path finding application. there several ways approach this, 1 of simpler ways to:

pick starting point, add list while true:     each border_pt bordering last point on list:         count number of points bordering border_pt         if count > best_count:             mark border_pt best      if border_pt empty:         break      add border_pt list 

here's c# code that, generates simple list based on cloud:

final path

using system; using system.collections.generic; using system.diagnostics; using system.drawing; using system.linq; using system.threading.tasks; using system.windows.forms;  namespace windowsformsapplication1 {     class exampleprogram : form     {         const int gridwidth = 24;         const int gridheight = 15;          list<point> m_points = new list<point>();         list<point> m_trail = new list<point>();          [stathread]         static void main()         {             application.enablevisualstyles();             application.setcompatibletextrenderingdefault(false);             application.run(new exampleprogram());         }          exampleprogram()         {             // simple little tool add bunch of points             addpoints(                 0, 4, 1, 3, 1, 4, 1, 5, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 4, 5, 4, 6, 5, 5, 6, 5,                 6, 4, 5, 4, 7, 4, 7, 3, 8, 3, 8, 4, 8, 5, 8, 6, 9, 6, 9, 5, 9, 4, 9, 3, 10, 2,                 10, 3, 10, 4, 10, 5, 10, 6, 11, 5, 11, 4, 11, 3, 11, 2, 12, 4, 12, 5, 13, 5,                 13, 6, 13, 8, 14, 8, 14, 7, 14, 6, 15, 7, 15, 8, 15, 9, 14, 9, 14, 10, 13, 10,                 12, 10, 11, 10, 13, 11, 14, 11, 15, 11, 15, 12, 16, 12, 17, 12, 18, 12, 19,                 12, 18, 11, 17, 11, 17, 10, 18, 10, 19, 10, 19, 9, 19, 8, 20, 8, 21, 8, 18,                 7, 19, 7, 20, 7, 21, 7, 21, 6, 22, 6, 23, 6, 21, 5, 20, 5, 19, 5, 19, 4, 18,                 4, 17, 4, 20, 3, 21, 3, 22, 3, 20, 2, 19, 2, 18, 2, 19, 1, 20, 1, 21, 1, 19,                 0, 18, 0, 10, 0, 4, 1);              // basic form logic             clientsize = new system.drawing.size(gridwidth * 20, gridheight * 20);             doublebuffered = true;             paint += exampleprogram_paint;              // add new point form (commented out)             // mouseup += exampleprogram_mouseup_addpoint;              // draw trail find             mouseup += exampleprogram_mouseup_addtrail;              // pick starting point start finding trail             // todo: left excersize reader decide how pick             // starting point programatically             m_trail.add(new point(0, 4));          }          ienumerable<point> border(point pt)         {             // return points border give point              if (pt.x > 0)             {                 if (pt.y > 0)                 {                     yield return new point(pt.x - 1, pt.y - 1);                 }                 yield return new point(pt.x - 1, pt.y);                 if (pt.y < gridheight - 1)                 {                     yield return new point(pt.x - 1, pt.y + 1);                 }             }             if (pt.y > 0)             {                 yield return new point(pt.x, pt.y - 1);             }             if (pt.y < gridheight - 1)             {                 yield return new point(pt.x, pt.y + 1);             }              if (pt.x < gridwidth - 1)             {                 if (pt.y > 0)                 {                     yield return new point(pt.x + 1, pt.y - 1);                 }                 yield return new point(pt.x + 1, pt.y);                 if (pt.y < gridheight - 1)                 {                     yield return new point(pt.x + 1, pt.y + 1);                 }             }         }          void addpoints(params int[] points)         {             // helper add bunch of points our list of points             (int = 0; < points.length; += 2)             {                 m_points.add(new point(points[i], points[i + 1]));             }         }          void exampleprogram_mouseup_addtrail(object sender, mouseeventargs e)         {             // calculate trail             while (true)             {                 // find best point next point                 int bestcount = 0;                 point best = new point();                  // @ current end point, test points around                 foreach (var pt in border(m_trail[m_trail.count - 1]))                 {                     // , each point, see how many points point borders                     int count = 0;                     if (m_points.contains(pt) && !m_trail.contains(pt))                     {                         foreach (var test in border(pt))                         {                             if (m_points.contains(test))                             {                                 if (m_trail.contains(test))                                 {                                     // point both in original cloud, , current                                     // trail, give negative weight                                     count--;                                 }                                 else                                 {                                     // haven't visited point, give positive weight                                     count++;                                 }                             }                         }                     }                      if (count > bestcount)                     {                         // point looks better we've found,                          // it's best 1 far                         bestcount = count;                         best = pt;                     }                 }                  if (bestcount <= 0)                 {                     // either didn't find anything, or did find bad,                     // break out of loop, we're done                     break;                 }                  m_trail.add(best);             }              invalidate();         }          void exampleprogram_mouseup_addpoint(object sender, mouseeventargs e)         {             // add point, , dump out             int x = (int)math.round((((double)e.x) - 10.0) / 20.0, 0);             int y = (int)math.round((((double)e.y) - 10.0) / 20.0, 0);             m_points.add(new point(x, y));             debug.writeline("m_points.add(new point(" + x + ", " + y + "));");             invalidate();         }          void exampleprogram_paint(object sender, painteventargs e)         {             // simple drawing, draw grid, , points             e.graphics.clear(color.white);              (int x = 0; x < gridwidth; x++)             {                 e.graphics.drawline(pens.black, x * 20 + 10, 0, x * 20 + 10, clientsize.height);             }              (int y = 0; y < gridheight; y++)             {                 e.graphics.drawline(pens.black, 0, y * 20 + 10, clientsize.width, y * 20 + 10);             }              foreach (var pt in m_points)             {                 e.graphics.fillellipse(brushes.black, (pt.x * 20 + 10) - 5, (pt.y * 20 + 10) - 5, 10, 10);             }              foreach (var pt in m_trail)             {                 e.graphics.fillellipse(brushes.red, (pt.x * 20 + 10) - 6, (pt.y * 20 + 10) - 6, 12, 12);             }         }     } } 

Comments