bool DRAWSEGMENT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { wxPoint p1, p2; int radius; float theta; EDA_RECT arect = aRect; arect.Inflate( aAccuracy ); switch( m_Shape ) { case S_CIRCLE: // Test if area intersects or contains the circle: if( aContained ) return arect.Contains( GetBoundingBox() ); else return arect.Intersects( GetBoundingBox() ); break; case S_ARC: radius = hypot( (double)( GetEnd().x - GetStart().x ), (double)( GetEnd().y - GetStart().y ) ); theta = std::atan2( GetEnd().y - GetStart().y , GetEnd().x - GetStart().x ); //Approximate the arc with two lines. This should be accurate enough for selection. p1.x = radius * std::cos( theta + M_PI/4 ) + GetStart().x; p1.y = radius * std::sin( theta + M_PI/4 ) + GetStart().y; p2.x = radius * std::cos( theta + M_PI/2 ) + GetStart().x; p2.y = radius * std::sin( theta + M_PI/2 ) + GetStart().y; if( aContained ) return arect.Contains( GetEnd() ) && aRect.Contains( p1 ) && aRect.Contains( p2 ); else return arect.Intersects( GetEnd(), p1 ) || aRect.Intersects( p1, p2 ); break; case S_SEGMENT: if( aContained ) return arect.Contains( GetStart() ) && aRect.Contains( GetEnd() ); else return arect.Intersects( GetStart(), GetEnd() ); break; default: ; } return false; }
bool ZONE_CONTAINER::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { EDA_RECT arect = aRect; arect.Inflate( aAccuracy ); CRect rect = m_Poly->GetBoundingBox(); EDA_RECT bbox; bbox.SetOrigin( rect.left, rect.bottom ); bbox.SetEnd( rect.right, rect.top ); if( aContained ) return arect.Contains( bbox ); else // Test for intersection between aRect and the polygon // For a polygon, using its bounding box has no sense here { // Fast test: if aRect is outside the polygon bounding box, // rectangles cannot intersect if( ! bbox.Intersects( arect ) ) return false; // aRect is inside the polygon bounding box, // and can intersect the polygon: use a fine test. // aRect intersects the polygon if at least one aRect corner // is inside the polygon wxPoint corner = arect.GetOrigin(); if( HitTestInsideZone( corner ) ) return true; corner.x = arect.GetEnd().x; if( HitTestInsideZone( corner ) ) return true; corner = arect.GetEnd(); if( HitTestInsideZone( corner ) ) return true; corner.x = arect.GetOrigin().x; if( HitTestInsideZone( corner ) ) return true; // No corner inside arect, but outlines can intersect arect // if one of outline corners is inside arect int count = m_Poly->GetCornersCount(); for( int ii =0; ii < count; ii++ ) { if( arect.Contains( m_Poly->GetPos( ii ) ) ) return true; } return false; } }
bool SCH_TEXT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { EDA_RECT bBox = GetBoundingBox(); bBox.Inflate( aAccuracy ); if( aContained ) return aRect.Contains( bBox ); return aRect.Intersects( bBox ); }
bool EDA_TEXT::TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccuracy ) const { EDA_RECT rect = aRect; rect.Inflate( aAccuracy ); if( aContains ) return rect.Contains( GetTextBox( -1 ) ); return rect.Intersects( GetTextBox( -1 ) ); }
bool SCH_BUS_ENTRY_BASE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { EDA_RECT rect = aRect; rect.Inflate( aAccuracy ); if( aContained ) return rect.Contains( GetBoundingBox() ); return rect.Intersects( GetBoundingBox() ); }
bool TRACK::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { EDA_RECT arect = aRect; arect.Inflate( aAccuracy ); if( aContained ) /* Tracks are a special case: * they are considered inside the rect if one end is inside the rect */ return arect.Contains( GetStart() ) || arect.Contains( GetEnd() ); else return arect.Intersects( GetStart(), GetEnd() ); }
bool DIMENSION::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { EDA_RECT arect = aRect; arect.Inflate( aAccuracy ); EDA_RECT rect = GetBoundingBox(); if( aAccuracy ) rect.Inflate( aAccuracy ); if( aContained ) return arect.Contains( rect ); return arect.Intersects( rect ); }
bool SCH_JUNCTION::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { if( m_Flags & STRUCT_DELETED || m_Flags & SKIP_STRUCT ) return false; EDA_RECT rect = aRect; rect.Inflate( aAccuracy ); if( aContained ) return rect.Contains( GetBoundingBox() ); return rect.Intersects( GetBoundingBox() ); }
bool VIA::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { EDA_RECT box; EDA_RECT arect = aRect; arect.Inflate( aAccuracy ); box.SetOrigin( GetStart() ); box.Inflate( GetWidth() / 2 ); if( aContained ) return arect.Contains( box ); else return arect.Intersects( box ); }
bool SCH_FIELD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { // Do not hit test hidden fields. if( !IsVisible() || IsVoid() ) return false; EDA_RECT rect = aRect; rect.Inflate( aAccuracy ); if( aContained ) return rect.Contains( GetBoundingBox() ); return rect.Intersects( GetBoundingBox() ); }
bool TEXTE_MODULE::TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccuracy ) const { EDA_RECT rect = aRect; rect.Inflate( aAccuracy ); if( aContains ) { return rect.Contains( GetBoundingBox() ); } else { return rect.Intersects( GetTextBox( -1 ), GetDrawRotation() ); } }
bool D_PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { EDA_RECT arect = aRect; arect.Normalize(); arect.Inflate( aAccuracy ); wxPoint shapePos = ShapePos(); EDA_RECT shapeRect; int r; EDA_RECT bb = GetBoundingBox(); wxPoint endCenter; int radius; if( !arect.Intersects( bb ) ) return false; // This covers total containment for all test cases if( arect.Contains( bb ) ) return true; switch( GetShape() ) { case PAD_SHAPE_CIRCLE: return arect.IntersectsCircle( GetPosition(), GetBoundingRadius() ); case PAD_SHAPE_RECT: shapeRect.SetOrigin( shapePos ); shapeRect.Inflate( m_Size.x / 2, m_Size.y / 2 ); return arect.Intersects( shapeRect, m_Orient ); case PAD_SHAPE_OVAL: // Circlular test if dimensions are equal if( m_Size.x == m_Size.y ) return arect.IntersectsCircle( shapePos, GetBoundingRadius() ); shapeRect.SetOrigin( shapePos ); // Horizontal dimension is greater if( m_Size.x > m_Size.y ) { radius = m_Size.y / 2; shapeRect.Inflate( m_Size.x / 2 - radius, radius ); endCenter = wxPoint( m_Size.x / 2 - radius, 0 ); RotatePoint( &endCenter, m_Orient ); // Test circular ends if( arect.IntersectsCircle( shapePos + endCenter, radius ) || arect.IntersectsCircle( shapePos - endCenter, radius ) ) { return true; } } else { radius = m_Size.x / 2; shapeRect.Inflate( radius, m_Size.y / 2 - radius ); endCenter = wxPoint( 0, m_Size.y / 2 - radius ); RotatePoint( &endCenter, m_Orient ); // Test circular ends if( arect.IntersectsCircle( shapePos + endCenter, radius ) || arect.IntersectsCircle( shapePos - endCenter, radius ) ) { return true; } } // Test rectangular portion between rounded ends if( arect.Intersects( shapeRect, m_Orient ) ) { return true; } break; case PAD_SHAPE_TRAPEZOID: /* Trapezoid intersection tests: * A) Any points of rect inside trapezoid * B) Any points of trapezoid inside rect * C) Any sides of trapezoid cross rect */ { wxPoint poly[4]; BuildPadPolygon( poly, wxSize( 0, 0 ), 0 ); wxPoint corners[4]; corners[0] = wxPoint( arect.GetLeft(), arect.GetTop() ); corners[1] = wxPoint( arect.GetRight(), arect.GetTop() ); corners[2] = wxPoint( arect.GetRight(), arect.GetBottom() ); corners[3] = wxPoint( arect.GetLeft(), arect.GetBottom() ); for( int i=0; i<4; i++ ) { RotatePoint( &poly[i], m_Orient ); poly[i] += shapePos; } for( int ii=0; ii<4; ii++ ) { if( TestPointInsidePolygon( poly, 4, corners[ii] ) ) { return true; } if( arect.Contains( poly[ii] ) ) { return true; } if( arect.Intersects( poly[ii], poly[(ii+1) % 4] ) ) { return true; } } return false; } case PAD_SHAPE_ROUNDRECT: /* RoundRect intersection can be broken up into simple tests: * a) Test intersection of horizontal rect * b) Test intersection of vertical rect * c) Test intersection of each corner */ r = GetRoundRectCornerRadius(); /* Test A - intersection of horizontal rect */ shapeRect.SetSize( 0, 0 ); shapeRect.SetOrigin( shapePos ); shapeRect.Inflate( m_Size.x / 2, m_Size.y / 2 - r ); // Short-circuit test for zero width or height if( shapeRect.GetWidth() > 0 && shapeRect.GetHeight() > 0 && arect.Intersects( shapeRect, m_Orient ) ) { return true; } /* Test B - intersection of vertical rect */ shapeRect.SetSize( 0, 0 ); shapeRect.SetOrigin( shapePos ); shapeRect.Inflate( m_Size.x / 2 - r, m_Size.y / 2 ); // Short-circuit test for zero width or height if( shapeRect.GetWidth() > 0 && shapeRect.GetHeight() > 0 && arect.Intersects( shapeRect, m_Orient ) ) { return true; } /* Test C - intersection of each corner */ endCenter = wxPoint( m_Size.x / 2 - r, m_Size.y / 2 - r ); RotatePoint( &endCenter, m_Orient ); if( arect.IntersectsCircle( shapePos + endCenter, r ) || arect.IntersectsCircle( shapePos - endCenter, r ) ) { return true; } endCenter = wxPoint( m_Size.x / 2 - r, -m_Size.y / 2 + r ); RotatePoint( &endCenter, m_Orient ); if( arect.IntersectsCircle( shapePos + endCenter, r ) || arect.IntersectsCircle( shapePos - endCenter, r ) ) { return true; } break; default: break; } return false; }
bool LIB_TEXT::Inside( EDA_RECT& rect ) const { return rect.Intersects( GetBoundingBox() ); }