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:
parent
64ff47c594
commit
8dda9b37fa
libs/kimath
pcbnew
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user