From: Linus Torvalds Date: Sat, 19 Nov 2011 20:25:35 +0000 (-0800) Subject: Merge branch 'sacplot' of git://git.hohndel.org/subsurface X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=25e18211ec99ff15c26315eff87fc31816ce8f33;hp=9f500ec8dc29187a95dd6e363bae160ed68a8f40;p=ext%2Fsubsurface.git Merge branch 'sacplot' of git://git.hohndel.org/subsurface * '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 --- diff --git a/dive.c b/dive.c index cd797d2..31be329 100644 --- 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; diff --git a/profile.c b/profile.c index 1b1546c..9fab8b2 100644 --- 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);