[chronojump] CairoXY calculatPaintX/Y with fast? method. Implemented on encoder signal.



commit d15ed8e793d85610cb45103cb419fc7cea462006
Author: Xavier de Blas <xaviblas gmail com>
Date:   Wed Mar 16 11:35:31 2022 +0100

    CairoXY calculatPaintX/Y with fast? method. Implemented on encoder signal.

 src/gui/cairo/encoder.cs      | 17 ++++++++-
 src/gui/cairo/raceAnalyzer.cs |  2 +-
 src/gui/cairo/xy.cs           | 85 +++++++++++++++++++++++++++++++++++++++----
 3 files changed, 94 insertions(+), 10 deletions(-)
---
diff --git a/src/gui/cairo/encoder.cs b/src/gui/cairo/encoder.cs
index 8ab105f3f..a804b1ecd 100644
--- a/src/gui/cairo/encoder.cs
+++ b/src/gui/cairo/encoder.cs
@@ -120,7 +120,20 @@ public class CairoGraphEncoderSignal : CairoXY
                        if(isInertial)
                                g.LineWidth = 2;
 
-                       plotRealPoints(plotType, points_list, startAt);
+                       /*
+                       ChronoDebug cDebug = new ChronoDebug("ChronoDebug plotRealPoints for n points: " + 
(points_list.Count - startAt).ToString());
+                       cDebug.Start();
+                       cDebug.Add("calling fast op");
+                       */
+
+                       plotRealPoints(plotType, points_list, startAt, true); //fast (but the difference is 
very low)
+
+                       /*
+                       cDebug.Add("calling slow op");
+                       plotRealPoints(plotType, points_list, startAt, false); //slow?
+                       cDebug.StopAndPrint();
+                       */
+
                        points_list_painted = points_list.Count;
                }
 
@@ -128,7 +141,7 @@ public class CairoGraphEncoderSignal : CairoXY
                                (maxValuesChanged || forceRedraw || points_list_inertial.Count != 
points_list_inertial_painted) )
                {
                        g.LineWidth = 1;
-                       plotRealPoints(plotType, points_list_inertial, startAt);
+                       plotRealPoints(plotType, points_list_inertial, startAt, true); //fast
                        points_list_inertial_painted = points_list_inertial.Count;
                }
 
diff --git a/src/gui/cairo/raceAnalyzer.cs b/src/gui/cairo/raceAnalyzer.cs
index 3ff1a369b..bf5f955ca 100644
--- a/src/gui/cairo/raceAnalyzer.cs
+++ b/src/gui/cairo/raceAnalyzer.cs
@@ -161,7 +161,7 @@ public class CairoGraphRaceAnalyzer : CairoXY
                if( points_list != null &&
                                (maxValuesChanged || forceRedraw || points_list.Count != points_list_painted) 
)
                {
-                       plotRealPoints(plotType, points_list, points_list_painted);
+                       plotRealPoints(plotType, points_list, points_list_painted, false); //not fast. TODO: 
maybe use fast if is really faster
                        points_list_painted = points_list.Count;
 
                        if(plotMaxMark && points_list.Count > 1)
diff --git a/src/gui/cairo/xy.cs b/src/gui/cairo/xy.cs
index b49a70a5f..988720a37 100644
--- a/src/gui/cairo/xy.cs
+++ b/src/gui/cairo/xy.cs
@@ -417,22 +417,40 @@ public abstract class CairoXY : CairoGeneric
        //called from almost all methods
        protected void plotRealPoints (PlotTypes plotType)
        {
-               plotRealPoints (plotType, point_l, 0);
+               plotRealPoints (plotType, point_l, 0, false);
        }
 
-       //called from raceAnalyzer (sending it own list of points)
-       protected void plotRealPoints (PlotTypes plotType, List<PointF> points_list, int startAt)
+       //called from raceAnalyzer and encoder (sending it own list of points)
+       //fast: calculated first calculatePaintX/Y for most of the formula. foreach value does short 
operation.
+       protected void plotRealPoints (PlotTypes plotType, List<PointF> points_list, int startAt, bool fast)
        {
                if(plotType == PlotTypes.LINES || plotType == PlotTypes.POINTSLINES) //draw line first to not 
overlap the points
                {
                        bool firstDone = false;
-                       //foreach(PointF p in points_list)
+                       double xgraph;
+                       double ygraph;
+                       double paintXfastA = 0;
+                       double paintXfastB = 0;
+                       double paintYfastA = 0;
+                       double paintYfastB = 0;
+
+                       if(fast)
+                       {
+                               calculatePaintXFastPre (out paintXfastA, out paintXfastB);
+                               calculatePaintYFastPre (out paintYfastA, out paintYfastB);
+                       }
                        for(int i = startAt; i < points_list.Count; i ++)
                        {
                                PointF p = points_list[i];
 
-                               double xgraph = calculatePaintX(p.X);
-                               double ygraph = calculatePaintY(p.Y);
+                               if(fast)
+                               {
+                                       xgraph = calculatePaintXFastDo (p.X, paintXfastA, paintXfastB);
+                                       ygraph = calculatePaintYFastDo (p.Y, paintYfastA, paintYfastB);
+                               } else {
+                                       xgraph = calculatePaintX(p.X);
+                                       ygraph = calculatePaintY(p.Y);
+                               }
 
                                if(! firstDone)
                                {
@@ -441,7 +459,7 @@ public abstract class CairoXY : CairoGeneric
                                } else
                                        g.LineTo(xgraph, ygraph);
                        }
-                       g.Stroke ();
+                       //g.Stroke (); TODO: reactivate after benchmark
                }
 
 //             lock (point_l) {
@@ -650,6 +668,59 @@ public abstract class CairoXY : CairoGeneric
                                absoluteMaxY - minY));
         }
 
+       // Fast calculatePaintX/Y, sadly for 10000 points the difference between fast and slow is very low
+
+       /*
+          paintX = totalMargins + (realX - minX) * (graphWidth - totalMargins - totalMargins) / 
(absoluteMaxX - minX);
+          take out realX:
+            paintX = A + realX * B
+            A = totalMargins - minX  *  (graphWidth - totalMargins - totalMargins) / (absoluteMaxX - minX)
+            B = (graphWidth - totalMargins - totalMargins) / (absoluteMaxX - minX)
+          */
+       protected void calculatePaintXFastPre (out double A, out double B)
+       {
+               //A = totalMargins - minX  *  (graphWidth - totalMargins - totalMargins) / (absoluteMaxX - 
minX);
+               A = totalMargins - minX  *  UtilAll.DivideSafe (
+                               graphWidth - totalMargins - totalMargins,
+                               absoluteMaxX - minX);
+
+               //B = (graphWidth - totalMargins - totalMargins) / (absoluteMaxX - minX);
+               B = UtilAll.DivideSafe(graphWidth - totalMargins - totalMargins, absoluteMaxX - minX);
+
+               return;
+       }
+       protected double calculatePaintXFastDo (double realX, double A, double B)
+       {
+                return A + realX * B;
+        }
+
+       /*
+          paintY = graphHeight - totalMargins - ((realY - minY) * (graphHeight - totalMargins - 
totalMargins) / (absoluteMaxY - minY))
+                //x = g - t - ((r - m) * (g - 2*t) / (a - m));
+
+          take out realY:
+            paintY = A + realY * B
+            By = - (graphHeight - 2*totalMargins) / (absoluteMaxY - minY))
+            Ay = graphHeight - totalMargins - minY * B
+          */
+       protected void calculatePaintYFastPre (out double A, out double B)
+       {
+               B = UtilAll.DivideSafe(
+                               - (graphHeight - 2*totalMargins),
+                               absoluteMaxY - minY);
+
+               A = graphHeight - totalMargins - minY * B;
+
+               return;
+       }
+       protected double calculatePaintYFastDo (double realY, double A, double B)
+       {
+                return A + realY * B;
+        }
+
+
+       //calculate real (from graph coordinates)
+
        private double calculateRealX (double graphX)
        {
                 return minX + ( (graphX - totalMargins) * (absoluteMaxX - minX) / (graphWidth - totalMargins 
- totalMargins) );


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]