Hi All
It's been a while. Sorry for my lack of activity over the summer.

I've just picked up some Plplot items again on my to do list, starting
with the fill problem that I reported a rather long time ago.

I have sorted a minimal example to reproduce the bug - see attached.
it turns out that a number of things need to come together to cause
this problem. The example is based on example 12 and draws a very
small trapezium just off the bottom left corner of the plot. however
what happens instead is that the whole plot is filled. The way this
works is that a test point is selected to the right of the fill shape
and Plplot examines if a line between this point and the bottom left
corner intersects the polygon segments to test if the bottom left
corner is in the polygon. When the test is performed segments that are
close to parallel (based on a ~2 pixel fuzziness) are flagged and in
the end treat as a non-intersection. Also if the intersection is close
to the end of a line (again 2 pixels is the limit) then the
intersection is flagged as too close.

In this special case the three short sides are all approximately 2
Plplot internal units long which fools the intersection test into
thinking they are close to parallel to the test line. See
notpointinpolygon() and notcrossed() functions. These three lines are
therefore treated as non-intersectionctions even though the test line
does intersect one of them. Finally the fourth section is just long
enough and the location is just correct that the test line intersects
it more than 2 pixels from each end. The result is that the point in
polygon test sees 1 intersection instead of two and incorrectly
concludes that the bottom left corner is inside the polygon.

The final item that causes the bug to manifest is that the polygon is
entirely outside of the plot area so no segments are drawable. The
test that Plplot performs to see if the whole plot needs filling is
that the bottom left corner is inside the fill polygon and all
segments are outside the plot area. Hence the incorrect full fill.

I'm still of the opinion that the notcrossed function should not use
the 2 pixel fuzziness. At this point in the drawing we are dealing in
integer pixels and we need only an epsilon test I think. I think the
best fix is to change this. There are some sticking plaster solutions
that would hide the problem but not really fix it in my opinion. I
would really like to change the notcrossed function unless anyone has
some really strong objections?

Phil



On 18 January 2016 at 20:08, Alan W. Irwin <ir...@beluga.phys.uvic.ca> wrote:
> On 2016-01-18 16:57-0000 Phil Rosenberg wrote:
>
>> Hi
>> Can we reopen this again please. I have just hit another case where
>> when plotting a contour plot something goes wrong and the whole plot
>> gets filled.
>>
>> Alan, you said you were going to see if you could work out why the
>> fuzzy logic was needed and I said I would try to generate a test case.
>> I know I haven't held up my side of the bargain, but I will try to
>> sort one asap.
>
>
> Hi Phil:
>
> The status here is I guessed at the cause of the issue you originally
> reported and got pretty far with a fix for that on a private topic
> branch but did not finish that off because some higher priorities
> intervened such as the new Fortran binding.  But if you have found a
> complicated case demonstrating an issue with the fill logic on master
> branch, that would be like gold because such cases are quite rare.
>
> So your absolutely first priority should be to preserve the exact
> complicated conditions where you found the bug.  Then please send me
> _that exact case_ to make sure I can replicate it here.  After that,
> we can attempt to simplify the issue down to a much more managable
> simple test case, fix that simple case, then go back to the
> complicated case to make sure that fix works for it as well. Or other
> possibilities exist such as fixing some fuzzy issues with the present
> logic (for example, how nearly parallel intersections are treated by
> the logic) to see if those fixes make any difference to your complex
> case.  But essential to all of this bug-fixing process is a case (no
> matter how complicated) that can be replicated elsewhere.
>
>
> Alan
> __________________________
> Alan W. Irwin
>
> Astronomical research affiliation with Department of Physics and Astronomy,
> University of Victoria (astrowww.phys.uvic.ca).
>
> Programming affiliations with the FreeEOS equation-of-state
> implementation for stellar interiors (freeeos.sf.net); the Time
> Ephemerides project (timeephem.sf.net); PLplot scientific plotting
> software package (plplot.sf.net); the libLASi project
> (unifont.org/lasi); the Loads of Linux Links project (loll.sf.net);
> and the Linux Brochure Project (lbproject.sf.net).
> __________________________
>
> Linux-powered Science
> __________________________
//      Bar chart demo.
//

#include "plcdemos.h"

void
plfbox( );

//--------------------------------------------------------------------------
// main
//
// Does a simple bar chart, using color fill.  If color fill is
// unavailable, pattern fill is used instead (automatic).
//--------------------------------------------------------------------------

int
main( int argc, char *argv[] )
{
    int          i;
    char         string[20];
    PLFLT        y0[10];

    static PLFLT pos[]   = { 0.0, 0.25, 0.5, 0.75, 1.0 };
    static PLFLT red[]   = { 0.0, 0.25, 0.5, 1.0, 1.0 };
    static PLFLT green[] = { 1.0, 0.5, 0.5, 0.5, 1.0 };
    static PLFLT blue[]  = { 1.0, 1.0, 0.5, 0.25, 0.0 };

// Parse and process command line arguments

    (void) plparseopts( &argc, argv, PL_PARSE_FULL );

// Initialize plplot

    plinit();

    pladv( 0 );
    plvsta();
    plwind( 1980.0, 1990.0, 0.0, 35.0 );
    plbox( "bc", 1.0, 0, "bcnv", 10.0, 0 );
    plcol0( 2 );
    pllab( "Year", "Widget Sales (millions)", "#frPLplot Example 12" );

    y0[0] = 35-0.002818376; //this value makes max for this polygon y 2 plplot internal units less than the max y for the window

    plscmap1l( 1, 5, pos, red, green, blue, NULL );

        plcol1( 0.0 );
        plpsty( 0 );
        plfbox( );

// Don't forget to call plend() to finish off!

    plend();
    exit( 0 );
}

void
plfbox( )
{
    PLFLT x[4], y[4];

    x[0] = 1980. + 14.0 * 3.9204924e-4;
    y[0] = -6.0 * 0.0014091879; 
    x[1] = 1980. + 15.0 * 3.9204924e-4;
    y[1] = -4.0 * 0.0014091879; // makes one edge less than 2 in y direction
	x[2] = 1980. + 15.0 * 3.9204924e-4; //put the edge 12 plplot units from the max x
	//x[2] = 1981.0; //put the edge 12 plplot units from the max x
    y[2] = -2.0 * 0.0014091879;
	x[3] = 1980. + 14.0 * 3.9204924e-4; //put the edge 12 plplot units from the max x;
	//x[3] = 1981.0; //put the edge 12 plplot units from the max x;
    y[3] = -1.0 * 0.0014091879;
    plfill( 4, x, y );
    plcol0( 1 );
    pllsty( 1 );
    plline( 4, x, y );
}
------------------------------------------------------------------------------
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel

Reply via email to