]> git.tdb.fi Git - ext/subsurface.git/commitdiff
Merge branch 'sacplot' of git://git.hohndel.org/subsurface
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 19 Nov 2011 20:25:35 +0000 (12:25 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 19 Nov 2011 20:25:35 +0000 (12:25 -0800)
* 'sacplot' of git://git.hohndel.org/subsurface:
  Make pressure plot shading by sac rate consistent
  Improve tank pressure sac coloring
  Be more consistent in our handling of rgb value tables
  Remove redundant linear sample tank pressure data

dive.c
profile.c

diff --git a/dive.c b/dive.c
index cd797d27663f6578ea32ea4cc2ae31a63037bde6..31be3291d76c13647b4dec8607b51636a26eec81 100644 (file)
--- a/dive.c
+++ b/dive.c
@@ -236,7 +236,7 @@ static int same_rounded_pressure(pressure_t a, pressure_t b)
 
 struct dive *fixup_dive(struct dive *dive)
 {
-       int i;
+       int i,j;
        double depthtime = 0;
        int lasttime = 0;
        int lastindex = -1;
@@ -244,6 +244,7 @@ struct dive *fixup_dive(struct dive *dive)
        int maxdepth = 0, mintemp = 0;
        int lastdepth = 0;
        int lasttemp = 0, lastpressure = 0;
+       int pressure_delta[MAX_CYLINDERS] = {INT_MAX, };
 
        for (i = 0; i < dive->samples; i++) {
                struct sample *sample = dive->sample + i;
@@ -253,10 +254,25 @@ struct dive *fixup_dive(struct dive *dive)
                int pressure = sample->cylinderpressure.mbar;
                int index = sample->cylinderindex;
 
-               /* Remove duplicate redundant pressure information */
-               if (pressure == lastpressure && index == lastindex)
-                       sample->cylinderpressure.mbar = 0;
-
+               if (index == lastindex) {
+                       /* Remove duplicate redundant pressure information */
+                       if (pressure == lastpressure)
+                               sample->cylinderpressure.mbar = 0;
+                       /* check for simply linear data in the samples
+                          +INT_MAX means uninitialized, -INT_MAX means not linear */
+                       if (pressure_delta[index] != -INT_MAX && lastpressure) {
+                               if (pressure_delta[index] == INT_MAX) {
+                                       pressure_delta[index] = abs(pressure - lastpressure);
+                               } else {
+                                       int cur_delta = abs(pressure - lastpressure);
+                                       if (cur_delta && abs(cur_delta - pressure_delta[index]) > 150) {
+                                               /* ok the samples aren't just a linearisation
+                                                * between start and end */
+                                               pressure_delta[index] = -INT_MAX;
+                                       }
+                               }
+                       }
+               }
                lastindex = index;
                lastpressure = pressure;
 
@@ -290,6 +306,33 @@ struct dive *fixup_dive(struct dive *dive)
                lastdepth = depth;
                lasttime = time;
        }
+       /* if all the samples for a cylinder have pressure data that
+        * is basically equidistant throw out the sample cylinder pressure
+        * information but make sure we still have a valid start and end
+        * pressure
+        * this happens when DivingLog decides to linearalize the
+        * pressure between beginning and end and for strange reasons
+        * decides to put that in the sample data as if it came from
+        * the dive computer; we don't want that (we'll visualize with
+        * constant SAC rate instead)
+        * WARNING WARNING - I have only seen this in single tank dives
+        * --- maybe I should try to create a multi tank dive and see what
+        * --- divinglog does there - but the code right now is only tested
+        * --- for the single tank case */
+       for (j = 0; j < MAX_CYLINDERS; j++) {
+               if (abs(pressure_delta[j]) != INT_MAX) {
+                       cylinder_t *cyl = dive->cylinder + j;
+                       for (i = 0; i < dive->samples; i++)
+                               if (dive->sample[i].cylinderindex == j)
+                                       dive->sample[i].cylinderpressure.mbar = 0;
+                       if (! cyl->start.mbar)
+                               cyl->start.mbar = cyl->sample_start.mbar;
+                       if (! cyl->end.mbar)
+                               cyl->end.mbar = cyl->sample_end.mbar;
+                       cyl->sample_start.mbar = 0;
+                       cyl->sample_end.mbar = 0;
+               }
+       }
        if (end < 0)
                return dive;
 
index 1b1546c0f7f83614b3b16aa3ce7c07895b082b94..9fab8b2e89f5ae72cf4732f91e48d4a3cb73de00 100644 (file)
--- a/profile.c
+++ b/profile.c
@@ -48,7 +48,7 @@ struct plot_info {
 
 /* convert velocity to colors */
 typedef struct { double r, g, b; } rgb_t;
-static const rgb_t rgb[] = {
+static const rgb_t velocity_color[] = {
        [STABLE]   = {0.0, 0.4, 0.0},
        [SLOW]     = {0.4, 0.8, 0.0},
        [MODERATE] = {0.8, 0.8, 0.0},
@@ -89,6 +89,11 @@ static void set_source_rgba(struct graphics_context *gc, double r, double g, dou
        cairo_set_source_rgba(gc->cr, r, g, b, a);
 }
 
+static void set_source_rgb_struct(struct graphics_context *gc, const rgb_t *rgb)
+{
+       set_source_rgba(gc, rgb->r, rgb->g, rgb->b, 1);
+}
+
 void set_source_rgb(struct graphics_context *gc, double r, double g, double b)
 {
        set_source_rgba(gc, r, g, b, 1);
@@ -476,9 +481,8 @@ static void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi
                /* we want to draw the segments in different colors
                 * representing the vertical velocity, so we need to
                 * chop this into short segments */
-               rgb_t color = rgb[entry->velocity];
                depth = entry->depth;
-               set_source_rgb(gc, color.r, color.g, color.b);
+               set_source_rgb_struct(gc, &velocity_color[entry->velocity]);
                move_to(gc, entry[-1].sec, entry[-1].depth);
                line_to(gc, sec, depth);
                cairo_stroke(cr);
@@ -595,29 +599,35 @@ static int get_cylinder_pressure_range(struct graphics_context *gc, struct plot_
        return pi->maxpressure != 0;
 }
 
+#define SAC_COLORS 9
+static const rgb_t sac_color[SAC_COLORS] = {
+       { 0.0, 0.4, 0.2},
+       { 0.2, 0.6, 0.2},
+       { 0.4, 0.8, 0.2},
+       { 0.6, 0.8, 0.2},
+       { 0.8, 0.8, 0.2},
+       { 0.8, 0.6, 0.2},
+       { 0.8, 0.4, 0.2},
+       { 0.9, 0.3, 0.2},
+       { 1.0, 0.2, 0.2},
+};
+
 /* set the color for the pressure plot according to temporary sac rate
- * as compared to avg_sac */
+ * as compared to avg_sac; the calculation simply maps the delta between
+ * sac and avg_sac to indexes 0 .. (SAC_COLORS - 1) with everything
+ * more than 6000 ml/min below avg_sac mapped to 0 */
+
 static void set_sac_color(struct graphics_context *gc, int sac, int avg_sac)
 {
-       int delta = sac - avg_sac;
-       if (delta < -6000)
-               set_source_rgb(gc, 0.0, 0.4, 0.2);
-       else if (delta < -4000)
-               set_source_rgb(gc, 0.2, 0.6, 0.2);
-       else if (delta < -2000)
-               set_source_rgb(gc, 0.4, 0.8, 0.2);
-       else if (delta < 0)
-               set_source_rgb(gc, 0.6, 0.8, 0.2);
-       else if (delta < 2000)
-               set_source_rgb(gc, 0.8, 0.8, 0.2);
-       else if (delta < 4000)
-               set_source_rgb(gc, 0.8, 0.6, 0.2);
-       else if (delta < 6000)
-               set_source_rgb(gc, 0.8, 0.4, 0.2);
-       else if (delta < 8000)
-               set_source_rgb(gc, 0.9, 0.3, 0.2);
-       else
-               set_source_rgb(gc, 1.0, 0.2, 0.2);
+       int sac_index = 0;
+       int delta = sac - avg_sac + 7000;
+
+       sac_index = delta / 2000;
+       if (sac_index < 0)
+               sac_index = 0;
+       if (sac_index > SAC_COLORS - 1)
+               sac_index = SAC_COLORS - 1;
+       set_source_rgb_struct(gc, &sac_color[sac_index]);
 }
 
 /* calculate the current SAC in ml/min and convert to int */
@@ -660,19 +670,19 @@ static void plot_cylinder_pressure(struct graphics_context *gc, struct plot_info
                        last = i;
                        last_entry = entry;
                        if (first_plot) {
-                               /* don't start with a sac of 0 */
-                               int fe = i + 1;
-                               struct plot_data *future_entry = pi->entry + fe;
-                               while (fe < pi->nr && future_entry->sec - entry->sec < SAC_WINDOW) {
-                                       fe++;
-                                       future_entry = pi->entry + fe;
-                               }
-                               sac = GET_LOCAL_SAC(entry, future_entry, dive);
+                               /* don't start with a sac of 0, so just calculate the first one */
+                               sac = GET_LOCAL_SAC(entry, pi->entry + i + 1, dive);
+                       }
+               } else {
+                       int j;
+                       sac = 0;
+                       for (j = last; j < i; j++)
+                               sac += GET_LOCAL_SAC(pi->entry + j, pi->entry + j + 1, dive);
+                       sac /= (i - last);
+                       if (entry->sec - last_entry->sec >= SAC_WINDOW) {
+                               last++;
+                               last_entry = pi->entry + last;
                        }
-               } else if (entry->sec - last_entry->sec >= SAC_WINDOW) {
-                       sac = GET_LOCAL_SAC(last_entry, entry, dive);
-                       last++;
-                       last_entry = pi->entry + last;
                }
                set_sac_color(gc, sac, dive->sac);
                if (lift_pen) {
@@ -988,10 +998,11 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
                                        list = NULL;
                                        continue;
                                }
-                               magic = (nlist->end - cur_pr[entry->cylinderindex]) / pt;                               }
+                               magic = (nlist->end - cur_pr[entry->cylinderindex]) / pt;
+                       }
                        if (pt != 0.0) {
                                double cur_pt = (entry->sec - (entry-1)->sec) *
-                                       (1 + entry->depth / 10000.0);
+                                       (1 + (entry->depth + (entry-1)->depth) / 20000.0);
                                INTERPOLATED_PRESSURE(entry) =
                                        cur_pr[entry->cylinderindex] + cur_pt * magic;
                                cur_pr[entry->cylinderindex] = INTERPOLATED_PRESSURE(entry);
@@ -1207,7 +1218,7 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
                }
                /* finally, do the discrete integration to get the SAC rate equivalent */
                current->pressure_time += (entry->sec - (entry-1)->sec) *
-                                               (1 + entry->depth / 10000.0);
+                       (1 + (entry->depth + (entry-1)->depth) / 20000.0);
                missing_pr |= !SENSOR_PRESSURE(entry);
        }
 
@@ -1301,13 +1312,13 @@ void plot(struct graphics_context *gc, cairo_rectangle_int_t *drawing_area, stru
        /* Temperature profile */
        plot_temperature_profile(gc, pi);
 
-       /* Cylinder pressure plot */
-       plot_cylinder_pressure(gc, pi, dive);
-
        /* Depth profile */
        plot_depth_profile(gc, pi);
        plot_events(gc, pi, dive);
 
+       /* Cylinder pressure plot */
+       plot_cylinder_pressure(gc, pi, dive);
+
        /* Text on top of all graphs.. */
        plot_temperature_text(gc, pi);
        plot_depth_text(gc, pi);