7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-19 23:21:41 +00:00

Change zorder to use unsigned

Edge cases can happen where point + clearance is larger than the bbox.
This can cause the zOrder min and max to get switched as max get a high
bit and is negative.  Clamping to limit the input values and using
uint32 for the output solves the corner case
This commit is contained in:
Seth Hillbrand 2024-10-24 17:17:57 -07:00
parent 64ff47c594
commit 8dda9b37fa
4 changed files with 14 additions and 11 deletions

View File

@ -241,7 +241,7 @@ class VERTEX
VERTEX* next = nullptr;
// z-order curve value
int32_t z = 0;
uint32_t z = 0;
// previous and next nodes in z-order
VERTEX* prevZ = nullptr;
@ -332,7 +332,7 @@ protected:
* by the size of the bounding box to fit into a 32-bit Morton code
* @return the Morton code for the point (aX, aY)
*/
int32_t zOrder( const double aX, const double aY ) const;
uint32_t zOrder( const double aX, const double aY ) const;
/**
* @return the area of the triangle defined by the three vertices

View File

@ -58,10 +58,13 @@ VERTEX* VERTEX_SET::createList( const SHAPE_LINE_CHAIN& points, VERTEX* aTail, v
* http://www.graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN
*
*/
int32_t VERTEX_SET::zOrder( const double aX, const double aY ) const
uint32_t VERTEX_SET::zOrder( const double aX, const double aY ) const
{
int32_t x = static_cast<int32_t>( 32767.0 * ( aX - m_bbox.GetX() ) / m_bbox.GetWidth() );
int32_t y = static_cast<int32_t>( 32767.0 * ( aY - m_bbox.GetY() ) / m_bbox.GetHeight() );
double limit_x = std::clamp( ( aX - m_bbox.GetX() ) / m_bbox.GetWidth(), 0.0, 1.0 );
double limit_y = std::clamp( ( aY - m_bbox.GetY() ) / m_bbox.GetHeight(), 0.0, 1.0 );
uint32_t x = static_cast<uint32_t>( limit_x * 32767.0 );
uint32_t y = static_cast<uint32_t>( limit_y * 32767.0 );
x = ( x | ( x << 8 ) ) & 0x00FF00FF;
x = ( x | ( x << 4 ) ) & 0x0F0F0F0F;
@ -265,8 +268,8 @@ bool VERTEX::isEar( bool aMatchUserData ) const
const double maxTY = std::max( a->y, std::max( b->y, c->y ) );
// z-order range for the current triangle bounding box
const int32_t minZ = parent->zOrder( minTX, minTY );
const int32_t maxZ = parent->zOrder( maxTX, maxTY );
const uint32_t minZ = parent->zOrder( minTX, minTY );
const uint32_t maxZ = parent->zOrder( maxTX, maxTY );
// first look for points inside the triangle in increasing z-order
VERTEX* p = nextZ;

View File

@ -252,8 +252,8 @@ public:
return nullptr;
// z-order range for the current point ± limit bounding box
const int32_t maxZ = zOrder( aPt->x + m_limit, aPt->y + m_limit );
const int32_t minZ = zOrder( aPt->x - m_limit, aPt->y - m_limit );
const uint32_t maxZ = zOrder( aPt->x + m_limit, aPt->y + m_limit );
const uint32_t minZ = zOrder( aPt->x - m_limit, aPt->y - m_limit );
const SEG::ecoord limit2 = SEG::Square( m_limit );
// first look for points in increasing z-order

View File

@ -96,8 +96,8 @@ public:
VERTEX* getPoint( VERTEX* aPt ) const
{
// z-order range for the current point ± limit bounding box
const int32_t maxZ = zOrder( aPt->x + m_dist, aPt->y + m_dist );
const int32_t minZ = zOrder( aPt->x - m_dist, aPt->y - m_dist );
const uint32_t maxZ = zOrder( aPt->x + m_dist, aPt->y + m_dist );
const uint32_t minZ = zOrder( aPt->x - m_dist, aPt->y - m_dist );
const SEG::ecoord limit2 = SEG::Square( m_dist );
// first look for points in increasing z-order