|
From: Ethan M. <merritt@u.washington.edu> - 2010-09-23 18:12:30
|
On Thursday 23 September 2010 10:52:33 am Manfred Schwarb wrote: > Am 22.09.2010 17:32, schrieb sfeam (Ethan Merritt): > > > On Wednesday 22 September 2010, Manfred Schwarb wrote: > >> > >>> That's the right idea. You're aiming for the resolution to match the > >>> number of pixels? > >>> > >> > >> The color transition from one color to the next in discrete palettes > >> should be at the exact pixel location. > > > > I do not recall seeing the original problem report. > > Can you give us a pointer to it? > > > http://sourceforge.net/mailarchive/forum.php?thread_name=201009220832.37418.sfeam%40users.sourceforge.net&forum_name=gnuplot-beta OK, thanks. I think the underlying problem is that the code that draws the color box was written to handle continuous color palettes. The comment "I think no one can distinguish more than 128 colors" refers to the minimal step within a continuous spectrum. I don't have any code to offer, but I think the best solution to the problem is to write a different routine for drawing discrete palettes. As Dan suggested, if there are only 5 colors in the palette then we need only draw 5 rectangles in the color box. Unlike the current code, however, they shouldn't be evenly spaced. The endpoints of each rectangle should be taken from the palette definition so that they will indeed be placed with perfact accuracy. Ethan > > It is perhaps in your SPAM folder. Sorry for this, I used a wrong > outgoing mail server to send the email. > > Probably my hack is wrong indeed, but it works for my use case. > > Thanks for looking at it, cheers, > > Manfred > > > > > > >> There is some obvious cleanup possibility in this function, as > >> > >> (xy_to - xy_from) == (color_box.rotation == 'h' ? color_box.bounds.xright - color_box.bounds.xleft : color_box.bounds.ytop - color_box.bounds.ybot) > >> > >> so one can drop the redundant if-condition. > >> > >> > >> And when xy_step === 1, one can eliminate this variable completely, > >> which would make the loop less heavyweight. > > > > One step in coordinate space is not the same as one pixel. > > Many terminals track coordinates at higher resolution. > > x11 axis coordinates run from [0:4096], but the pixel resolution is > > typically smaller by a factor of 5-10. The cairo terminals, > > including wxt, oversample by a factor of 20. The canvas terminal > > by a factor of 10. And so on. > > > > There is currently no way that I know of for the gnuplot core > > code to know the pixel resolution of the output device. > > > > Ethan > > > >> > >> > >> Which would lead to some thing like: > >> --- color.c.orig 2010-09-21 14:09:41.000000000 +0200 > >> +++ color.c 2010-09-22 09:16:05.000000000 +0200 > >> @@ -361,9 +361,8 @@ > >> static void > >> draw_inside_color_smooth_box_bitmap(FILE * out) > >> { > >> - int steps = 128; /* I think that nobody can distinguish more colours drawn in the palette */ > >> - int i, xy, xy2, xy_from, xy_to; > >> - double xy_step, gray; > >> + int i, xy, xy2, xy_from, xy_to, steps; > >> + double gray; > >> gpiPoint corners[4]; > >> > >> (void) out; /* to avoid "unused parameter" warning */ > >> @@ -378,7 +377,7 @@ > >> xy_from = color_box.bounds.xleft; > >> xy_to = color_box.bounds.xright; > >> } > >> - xy_step = (color_box.rotation == 'h' ? color_box.bounds.xright - color_box.bounds.xleft : color_box.bounds.ytop - color_box.bounds.ybot) / (double) steps; > >> + steps = xy_to - xy_from; > >> > >> for (i = 0; i < steps; i++) { > >> gray = (double) i / steps; /* colours equidistantly from [0,1] */ > >> @@ -386,14 +385,14 @@ > >> gray = 1 - gray; > >> /* Set the colour (also for terminals which support extended specs). */ > >> set_color(gray); > >> - xy = xy_from + (int) (xy_step * i); > >> - xy2 = xy_from + (int) (xy_step * (i + 1)); > >> + xy = xy_from + i; > >> + xy2 = xy + 1; > >> if (color_box.rotation == 'v') { > >> corners[0].y = corners[1].y = xy; > >> - corners[2].y = corners[3].y = (i == steps - 1) ? xy_to : xy2; > >> + corners[2].y = corners[3].y = xy2; > >> } else { > >> corners[0].x = corners[3].x = xy; > >> - corners[1].x = corners[2].x = (i == steps - 1) ? xy_to : xy2; > >> + corners[1].x = corners[2].x = xy2; > >> } > >> #ifdef EXTENDED_COLOR_SPECS > >> if (supply_extended_color_specs) { > >> > >> > >> Cheers, Manfred > >> > >> > >> > >>> See what the rest of the list thinks. > >>> > >>> Dan > >>> > >>> > >>> Manfred Schwarb wrote: > >>>> Am 21.09.2010 17:24, schrieb Daniel J Sebald: > >>>> > >>>> > >>>>> Something certainly doesn't look right with the original. However, > >>> putting the resolution so high doesn't seem like the best solution. At the > >>> same time, limiting to 128 steps seems restrictive. I would think it all > >>> depends on how the user sets up the color axis. For example, if only five > >>> colors are used, perhaps only five levels are needed, so long as the color > >>> ticks align with the color box representation. > >>>>> > >>>> > >>>> > >>>> > >>>> Hmm, no I think it does not depend on the number of used colors. > >>>> As soon as one wants a discrete palette, placing has to be accurate to > >>>> pixel resolution. > >>>> Which means, if one does not want to calculate each color transition > >>>> separately somehow, one has to draw in pixel resolution, i.e. > >>>> each pixel line separately. > >>>> > >>>> The following gives good results for me: > >>>> > >>>> --- color.c.orig 2010-09-21 14:09:41.000000000 +0200 > >>>> +++ color.c 2010-09-21 22:42:01.000000000 +0200 > >>>> @@ -361,7 +361,7 @@ > >>>> static void > >>>> draw_inside_color_smooth_box_bitmap(FILE * out) > >>>> { > >>>> - int steps = 128; /* I think that nobody can distinguish more > >>> colours drawn in the palette */ > >>>> + int steps; > >>>> int i, xy, xy2, xy_from, xy_to; > >>>> double xy_step, gray; > >>>> gpiPoint corners[4]; > >>>> @@ -378,6 +378,8 @@ > >>>> xy_from = color_box.bounds.xleft; > >>>> xy_to = color_box.bounds.xright; > >>>> } > >>>> + steps=xy_to-xy_from; > >>>> + > >>>> xy_step = (color_box.rotation == 'h' ? color_box.bounds.xright - > >>> color_box.bounds.xleft : color_box.bounds.ytop - color_box.bounds.ybot) / > >>> (double) steps; > >>>> > >>>> for (i = 0; i < steps; i++) { > >>>> > >>>> > >>>> In my example, steps becomes 499, which is much smaller > >>>> than my insane 12800. > >>>> What do you think? > >>>> > >>>> Cheers, > >>>> Manfred > >>>> > >>>> > >>>> > >>>> > >>>>> Dan > >>>>> > >>>>> > >>>>> Manfred Schwarb wrote: > >>>>> > >>>>>> Hi, > >>>>>> > >>>>>> when doing 2d plots ("splot") with discrete colors > >>>>>> [i.e. 'set palette defined ( 0 "yellow", 0.5 "yellow", 0.5 "red", 1 > >>> "red" )'], > >>>>>> I get some distorted color distribution in the color box. > >>>>>> > >>>>>> I then discovered that the reason is the coarse stepping > >>>>>> in calculating the color values. > >>>>>> The following cures it for me: > >>>>>> > >>>>>> --- color.c.orig 2010-09-21 14:09:41.000000000 +0200 > >>>>>> +++ color.c 2010-09-21 14:09:48.000000000 +0200 > >>>>>> @@ -361,7 +361,7 @@ > >>>>>> static void > >>>>>> draw_inside_color_smooth_box_bitmap(FILE * out) > >>>>>> { > >>>>>> - int steps = 128; /* I think that nobody can distinguish more > >>> colours drawn in the palette */ > >>>>>> + int steps = 12800; /* I think that nobody can distinguish more > >>> colours drawn in the palette */ > >>>>>> int i, xy, xy2, xy_from, xy_to; > >>>>>> double xy_step, gray; > >>>>>> gpiPoint corners[4]; > >>>>>> > >>>>>> > >>>>>> I figured that "steps" has to be in the range of 10000 to get > >>>>>> completely accurate color value calculation. > >>>>>> > >>>>>> Good and bad examples as attachments. > >>>>>> > >>>>>> > >>>>>> Cheers, > >>>>>> Manfred > >>>>>> -- Ethan A Merritt Biomolecular Structure Center, K-428 Health Sciences Bldg University of Washington, Seattle 98195-7742 |