Hi Arjen
I've just copied the code below as I don't just have time at the
moment to sort a git patch (The plot I was making is for a
presentation this afternoon!). The old code has been commented out
with /* */ and my new code is directly above that from the #ifdef
onwards.
Basically I get that the variable factor will be zero for parallel
lines and I get that there is a precision limit on that due to
floating point rounding. However I don't understand how factor_NBCC
works as a test.
For the bug in question the inputs were xA1=20994, yA1=12219,
xA2=4915, yA2=12561 xB1=20979, yB1=12219, xB2=20979, yB2=12221.
Although perhaps the As and Bs were reversed, but the flagging should
be identical.
Phil
Code Below:
int
notcrossed( PLINT * xintersect, PLINT * yintersect,
PLINT xA1, PLINT yA1, PLINT xA2, PLINT yA2,
PLINT xB1, PLINT yB1, PLINT xB2, PLINT yB2 )
{
PLFLT factor, factor_NBCC, fxintersect, fyintersect, limit;
// These variables are PLFLT not for precision, but to
// avoid integer overflows if they were typed as PLINT.
PLFLT xA2A1, yA2A1, xB2B1, yB2B1;
PLFLT xB1A1, yB1A1, xB2A1, yB2A1;
PLINT status = 0;
//
// Two linear equations to be solved for x and y.
// y = ((x - xA1)*yA2 + (xA2 - x)*yA1)/(xA2 - xA1)
// y = ((x - xB1)*yB2 + (xB2 - x)*yB1)/(xB2 - xB1)
//
// Transform those two equations to coordinate system with origin
// at (xA1, yA1).
// y' = x'*yA2A1/xA2A1
// y' = ((x' - xB1A1)*yB2A1 + (xB2A1 - x')*yB1A1)/xB2B1
// ==>
// x' = -(
// (-xB1A1*yB2A1 + xB2A1*yB1A1)/xB2B1)/
// (yB2B1/xB2B1 - yA2A1/xA2A1)
// = (xB1A1*yB2A1 - xB2A1*yB1A1)*xA2A1/
// (xA2A1*yB2B1 - yA2A1*xB2B1)
//
//
xA2A1 = xA2 - xA1;
yA2A1 = yA2 - yA1;
xB2B1 = xB2 - xB1;
yB2B1 = yB2 - yB1;
factor = xA2A1 * yB2B1 - yA2A1 * xB2B1;
#ifdef PL_DOUBLE
limit= sqrt( FLT_MIN );
#else
limit = sqrt( DBL_MIN );
#endif
if( factor == 0 )
status = status | PL_PARALLEL;
else if( fabs( factor ) < limit )
status = status | PL_NEAR_PARALLEL;
/*factor_NBCC = PL_NBCC * ( fabs( xA2A1 ) + fabs( yB2B1 ) + fabs(
yA2A1 ) + fabs( xB2B1 ) );
if ( fabs( factor ) <= factor_NBCC )
{
if ( fabs( factor ) > 0. )
status = status | PL_NEAR_PARALLEL;
else
status = status | PL_PARALLEL;
}*/
else
{
xB1A1 = xB1 - xA1;
yB1A1 = yB1 - yA1;
xB2A1 = xB2 - xA1;
yB2A1 = yB2 - yA1;
factor = ( xB1A1 * yB2A1 - yB1A1 * xB2A1 ) / factor;
fxintersect = factor * xA2A1 + xA1;
fyintersect = factor * yA2A1 + yA1;
// The "redundant" x and y segment range checks (which include near the
// end points) are needed for the vertical and the horizontal cases.
if ( ( BETW_NBCC( fxintersect, xA1, xA2 ) && BETW_NBCC( fyintersect,
yA1, yA2 ) ) &&
( BETW_NBCC( fxintersect, xB1, xB2 ) && BETW_NBCC( fyintersect, yB1, yB2 ) ) )
{
// The intersect is close (within +/- PL_NBCC) to an end point or
// corresponds to a definite crossing of the two line segments.
// Find out which.
if ( fabs( fxintersect - xA1 ) <= PL_NBCC && fabs( fyintersect - yA1 )
<= PL_NBCC )
status = status | PL_NEAR_A1;
else if ( fabs( fxintersect - xA2 ) <= PL_NBCC && fabs( fyintersect -
yA2 ) <= PL_NBCC )
status = status | PL_NEAR_A2;
else if ( fabs( fxintersect - xB1 ) <= PL_NBCC && fabs( fyintersect -
yB1 ) <= PL_NBCC )
status = status | PL_NEAR_B1;
else if ( fabs( fxintersect - xB2 ) <= PL_NBCC && fabs( fyintersect -
yB2 ) <= PL_NBCC )
status = status | PL_NEAR_B2;
// N.B. if none of the above conditions hold then status remains at
// zero to signal we have a definite crossing.
}
else
status = status | PL_NOT_CROSSED;
}
if ( !status )
{
*xintersect = (PLINT) fxintersect;
*yintersect = (PLINT) fyintersect;
}
return status;
}
On 15 June 2015 at 10:46, Arjen Markus <[email protected]> wrote:
> Hi Phil,
>
>
>
> I do not remember who wrote it, I may have made some changes to it in a now
> distant past, but I could have a look at your fix.
>
>
>
> Regards,
>
>
>
> Arjen
>
>
>
>> -----Original Message-----
>> From: Phil Rosenberg [mailto:[email protected]]
>> Sent: Monday, June 15, 2015 11:35 AM
>> To: [email protected]
>> Subject: [Plplot-devel] Bug in notcrossed() function of plfill.c
>>
>> Hi All
>> I have just been dealing with a bug where I was drawing a contour plot and
>> my entire
>> plot was being filled with one contour level. I have fought my way through
>> the code
>> and it turned out to be a perfect storm of a bug which begins with the
>> notcrossed
>> function returning a PL_NEAR_PARALLEL status for two lines which are
>> actually
>> near perpendicular (and cross) which then causes the top left corner of my
>> plot to be
>> incorrectly labelled as inside a fill region. However because the fill
>> region is actually
>> outside the plot plplot sees no intersections with the plot boundaries so
>> checks if the
>> top left corner of the plot is inside the fill region. In this case it
>> sees that it is flagged
>> as inside so assumes the whole plot must be inside and fills the whole
>> plot.
>>
>> I have fixed my code, but I actually don't understand the exixting logic
>> inside
>> notcrossed(). This might be because it is an error or it might be because
>> I just don't
>> get it. So before I push my change I just wanted to check if whoever
>> authored this
>> function is still around?
>>
>> Phil
>>
>>
>> ------------------------------------------------------------------------------
>> _______________________________________________
>> Plplot-devel mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/plplot-devel
>
> DISCLAIMER: This message is intended exclusively for the addressee(s) and
> may contain confidential and privileged information. If you are not the
> intended recipient please notify the sender immediately and destroy this
> message. Unauthorized use, disclosure or copying of this message is strictly
> prohibited. The foundation 'Stichting Deltares', which has its seat at
> Delft, The Netherlands, Commercial Registration Number 41146461, is not
> liable in any way whatsoever for consequences and/or damages resulting from
> the improper, incomplete and untimely dispatch, receipt and/or content of
> this e-mail.
------------------------------------------------------------------------------
_______________________________________________
Plplot-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/plplot-devel