+ avoid creating two coincident vertices (needs more testing)

This commit is contained in:
artemp 2013-02-12 15:51:40 +00:00
parent b50330c40e
commit 8b757a1c7e

View file

@ -2,8 +2,8 @@
// Anti-Grain Geometry - Version 2.4 // Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
// //
// Permission to copy, use, modify, sell and distribute this software // Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies. // is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied // This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// //
@ -13,7 +13,7 @@
// http://www.antigrain.com // http://www.antigrain.com
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// //
// Liang-Barsky clipping // Liang-Barsky clipping
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED #ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED
@ -36,7 +36,7 @@ namespace agg
}; };
//----------------------------------------------------------clipping_flags //----------------------------------------------------------clipping_flags
// Determine the clipping code of the vertex according to the // Determine the clipping code of the vertex according to the
// Cyrus-Beck line clipping algorithm // Cyrus-Beck line clipping algorithm
// //
// | | // | |
@ -52,7 +52,7 @@ namespace agg
// | | // | |
// clip_box.x1 clip_box.x2 // clip_box.x1 clip_box.x2
// //
// //
template<class T> template<class T>
inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box) inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
{ {
@ -87,7 +87,7 @@ namespace agg
const double nearzero = 1e-30; const double nearzero = 1e-30;
double deltax = x2 - x1; double deltax = x2 - x1;
double deltay = y2 - y1; double deltay = y2 - y1;
double xin; double xin;
double xout; double xout;
double yin; double yin;
@ -95,52 +95,52 @@ namespace agg
double tinx; double tinx;
double tiny; double tiny;
double toutx; double toutx;
double touty; double touty;
double tin1; double tin1;
double tin2; double tin2;
double tout1; double tout1;
unsigned np = 0; unsigned np = 0;
if(deltax == 0.0) if(deltax == 0.0)
{ {
// bump off of the vertical // bump off of the vertical
deltax = (x1 > clip_box.x1) ? -nearzero : nearzero; deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
} }
if(deltay == 0.0) if(deltay == 0.0)
{ {
// bump off of the horizontal // bump off of the horizontal
deltay = (y1 > clip_box.y1) ? -nearzero : nearzero; deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
} }
if(deltax > 0.0) if(deltax > 0.0)
{ {
// points to right // points to right
xin = clip_box.x1; xin = clip_box.x1;
xout = clip_box.x2; xout = clip_box.x2;
} }
else else
{ {
xin = clip_box.x2; xin = clip_box.x2;
xout = clip_box.x1; xout = clip_box.x1;
} }
if(deltay > 0.0) if(deltay > 0.0)
{ {
// points up // points up
yin = clip_box.y1; yin = clip_box.y1;
yout = clip_box.y2; yout = clip_box.y2;
} }
else else
{ {
yin = clip_box.y2; yin = clip_box.y2;
yout = clip_box.y1; yout = clip_box.y1;
} }
tinx = (xin - x1) / deltax; tinx = (xin - x1) / deltax;
tiny = (yin - y1) / deltay; tiny = (yin - y1) / deltay;
if (tinx < tiny) if (tinx < tiny)
{ {
// hits x first // hits x first
tin1 = tinx; tin1 = tinx;
@ -152,10 +152,10 @@ namespace agg
tin1 = tiny; tin1 = tiny;
tin2 = tinx; tin2 = tinx;
} }
if(tin1 <= 1.0) if(tin1 <= 1.0)
{ {
if(0.0 < tin1) if(0.0 < tin1)
{ {
*x++ = (T)xin; *x++ = (T)xin;
*y++ = (T)yin; *y++ = (T)yin;
@ -166,21 +166,21 @@ namespace agg
{ {
toutx = (xout - x1) / deltax; toutx = (xout - x1) / deltax;
touty = (yout - y1) / deltay; touty = (yout - y1) / deltay;
tout1 = (toutx < touty) ? toutx : touty; tout1 = (toutx < touty) ? toutx : touty;
if(tin2 > 0.0 || tout1 > 0.0) if(tin2 > 0.0 || tout1 > 0.0)
{ {
if(tin2 <= tout1) if(tin2 <= tout1)
{ {
if(tin2 > 0.0) if(tin2 > 0.0)
{ {
if(tinx > tiny) if(tinx > tiny)
{ {
*x++ = (T)xin; *x++ = (T)xin;
*y++ = (T)(y1 + tinx * deltay); *y++ = (T)(y1 + tinx * deltay);
} }
else else
{ {
*x++ = (T)(x1 + tiny * deltax); *x++ = (T)(x1 + tiny * deltax);
*y++ = (T)yin; *y++ = (T)yin;
@ -188,34 +188,35 @@ namespace agg
++np; ++np;
} }
if(tout1 < 1.0) if(tout1 < 1.0)
{ {
if(toutx < touty) if(toutx < touty)
{ {
*x++ = (T)xout; *x++ = (T)xout;
*y++ = (T)(y1 + toutx * deltay); *y++ = (T)(y1 + toutx * deltay);
} }
else else
{ {
*x++ = (T)(x1 + touty * deltax); *x++ = (T)(x1 + touty * deltax);
*y++ = (T)yout; *y++ = (T)yout;
} }
++np;
} }
else else if(*x != x2 && *y != y2)
{ {
*x++ = x2; *x++ = x2;
*y++ = y2; *y++ = y2;
++np;
} }
++np;
} }
else else
{ {
if(tinx > tiny) if(tinx > tiny)
{ {
*x++ = (T)xin; *x++ = (T)xin;
*y++ = (T)yout; *y++ = (T)yout;
} }
else else
{ {
*x++ = (T)xout; *x++ = (T)xout;
*y++ = (T)yin; *y++ = (T)yin;
@ -231,8 +232,8 @@ namespace agg
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
template<class T> template<class T>
bool clip_move_point(T x1, T y1, T x2, T y2, bool clip_move_point(T x1, T y1, T x2, T y2,
const rect_base<T>& clip_box, const rect_base<T>& clip_box,
T* x, T* y, unsigned flags) T* x, T* y, unsigned flags)
{ {
T bound; T bound;
@ -281,14 +282,14 @@ namespace agg
return 0; return 0;
} }
if((f1 & clipping_flags_x_clipped) != 0 && if((f1 & clipping_flags_x_clipped) != 0 &&
(f1 & clipping_flags_x_clipped) == (f2 & clipping_flags_x_clipped)) (f1 & clipping_flags_x_clipped) == (f2 & clipping_flags_x_clipped))
{ {
// Fully clipped // Fully clipped
return 4; return 4;
} }
if((f1 & clipping_flags_y_clipped) != 0 && if((f1 & clipping_flags_y_clipped) != 0 &&
(f1 & clipping_flags_y_clipped) == (f2 & clipping_flags_y_clipped)) (f1 & clipping_flags_y_clipped) == (f2 & clipping_flags_y_clipped))
{ {
// Fully clipped // Fully clipped
@ -299,25 +300,25 @@ namespace agg
T ty1 = *y1; T ty1 = *y1;
T tx2 = *x2; T tx2 = *x2;
T ty2 = *y2; T ty2 = *y2;
if(f1) if(f1)
{ {
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x1, y1, f1)) if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x1, y1, f1))
{ {
return 4; return 4;
} }
if(*x1 == *x2 && *y1 == *y2) if(*x1 == *x2 && *y1 == *y2)
{ {
return 4; return 4;
} }
ret |= 1; ret |= 1;
} }
if(f2) if(f2)
{ {
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x2, y2, f2)) if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x2, y2, f2))
{ {
return 4; return 4;
} }
if(*x1 == *x2 && *y1 == *y2) if(*x1 == *x2 && *y1 == *y2)
{ {
return 4; return 4;
} }