Loading change_log.txt +14 −0 Original line number Original line Diff line number Diff line Loading @@ -5,6 +5,20 @@ Please add newer entries at the top, list the date and your name with email address. email address. 2007-Aug-08 UPDATE Dick Hollenbeck <dick@softplc.com> ================================================================================ + pcbnew & common * Renamed locate.cpp's distance() to DistanceTest() and moved it to trigo.cpp. Pass more parameters to DistanceTest and removed globals that were used by distance() in locate.cpp. Moved and renamed DistanceTest function proto from protos.h to trigo.h. * Implemented HitTest() for class_cotation, class_mire, and a few other classes by factoring out existing code from locate.cpp. locate.cpp should operate exactly the same as before. * Detected that the suspected class_module hit-testing bug was not real, i.e. no bug found. 2007-aug-08 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> 2007-aug-08 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> ================================================================================ ================================================================================ + eeschema + eeschema Loading common/trigo.cpp +159 −0 Original line number Original line Diff line number Diff line Loading @@ -9,6 +9,163 @@ #include "trigo.h" #include "trigo.h" /*****************************/ bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY ) /*****************************/ /* * Calcul de la distance du curseur souris a un segment de droite : * ( piste, edge, contour module .. * retourne: * false si distance > seuil * true si distance <= seuil * Variables utilisees ( doivent etre initialisees avant appel , et * sont ramenees au repere centre sur l'origine du segment) * dx, dy = coord de l'extremite segment. * spot_cX,spot_cY = coord du curseur souris * la recherche se fait selon 4 cas: * segment horizontal * segment vertical * segment 45 * segment quelconque */ { int cXrot, cYrot, /* coord du point (souris) dans le repere tourne */ segX, segY; /* coord extremite segment tj >= 0 */ int pointX, pointY; /* coord point a tester dans repere modifie dans lequel * segX et segY sont >=0 */ segX = dx; segY = dy; pointX = spot_cX; pointY = spot_cY; /*Recalcul coord pour que le segment soit dans 1er quadrant (coord >= 0)*/ if( segX < 0 ) /* mise en >0 par symetrie par rapport a l'axe Y */ { segX = -segX; pointX = -pointX; } if( segY < 0 ) /* mise en > 0 par symetrie par rapport a l'axe X */ { segY = -segY; pointY = -pointY; } if( segY == 0 ) /* piste Horizontale */ { if( abs( pointY ) <= seuil ) { if( (pointX >= 0) && (pointX <= segX) ) return 1; /* Etude des extremites : cercle de rayon seuil */ if( (pointX < 0) && (pointX >= -seuil) ) { if( ( (pointX * pointX) + (pointY * pointY) ) <= (seuil * seuil) ) return true; } if( (pointX > segX) && ( pointX <= (segX + seuil) ) ) { if( ( ( (pointX - segX) * (pointX - segX) ) + (pointY * pointY) ) <= (seuil * seuil) ) return true; } } } else if( segX == 0 ) /* piste verticale */ { if( abs( pointX ) <= seuil ) { if( (pointY >= 0 ) && (pointY <= segY) ) return true; if( (pointY < 0) && (pointY >= -seuil) ) { if( ( (pointY * pointY) + (pointX * pointX) ) <= (seuil * seuil) ) return true; } if( (pointY > segY) && ( pointY <= (segY + seuil) ) ) { if( ( ( (pointY - segY) * (pointY - segY) ) + (pointX * pointX) ) <= (seuil * seuil) ) return true; } } } else if( segX == segY ) /* piste a 45 degre */ { /* on fait tourner les axes de 45 degre. la souris a alors les * coord : x1 = x*cos45 + y*sin45 * y1 = y*cos45 - x*sin45 * et le segment de piste est alors horizontal. * recalcul des coord de la souris ( sin45 = cos45 = .707 = 7/10 * remarque : sin ou cos45 = .707, et lors du recalcul des coord * dx45 et dy45, lec coeff .707 est neglige, dx et dy sont en fait .707 fois * trop grands. (c.a.d trop petits) * spot_cX,Y doit etre * par .707 * .707 = 0.5 */ cXrot = (pointX + pointY) >> 1; cYrot = (pointY - pointX) >> 1; /* recalcul des coord de l'extremite du segment , qui sera vertical * suite a l'orientation des axes sur l'ecran : dx45 = pointX (ou pointY) * et est en fait 1,414 plus grand , et dy45 = 0 */ // seuil doit etre * .707 pour tenir compte du coeff de reduction sur dx,dy seuil *= 7; seuil /= 10; if( abs( cYrot ) <= seuil ) /* ok sur axe vertical) */ { if( (cXrot >= 0) && (cXrot <= segX) ) return true; /* Etude des extremites : cercle de rayon seuil */ if( (cXrot < 0) && (cXrot >= -seuil) ) { if( ( (cXrot * cXrot) + (cYrot * cYrot) ) <= (seuil * seuil) ) return true; } if( (cXrot > segX) && ( cXrot <= (segX + seuil) ) ) { if( ( ( (cXrot - segX) * (cXrot - segX) ) + (cYrot * cYrot) ) <= (seuil * seuil) ) return true; } } } else /* orientation quelconque */ { /* On fait un changement d'axe (rotation) de facon a ce que le segment * de piste soit horizontal dans le nouveau repere */ int angle; angle = (int) ( atan2( (float) segY, (float) segX ) * 1800 / M_PI); cXrot = pointX; cYrot = pointY; RotatePoint( &cXrot, &cYrot, angle ); /* Rotation du point a tester */ RotatePoint( &segX, &segY, angle ); /* Rotation du segment */ /* la piste est Horizontale , par suite des modifs de coordonnes * et d'axe, donc segX = longueur du segment */ if( abs( cYrot ) <= seuil ) /* ok sur axe vertical) */ { if( (cXrot >= 0) && (cXrot <= segX) ) return true; /* Etude des extremites : cercle de rayon seuil */ if( (cXrot < 0) && (cXrot >= -seuil) ) { if( ( (cXrot * cXrot) + (cYrot * cYrot) ) <= (seuil * seuil) ) return true; } if( (cXrot > segX) && ( cXrot <= (segX + seuil) ) ) { if( ( ( (cXrot - segX) * (cXrot - segX) ) + (cYrot * cYrot) ) <= (seuil * seuil) ) return true; } } } return false; } /***********************************/ /***********************************/ int ArcTangente( int dy, int dx ) int ArcTangente( int dy, int dx ) /***********************************/ /***********************************/ Loading Loading @@ -217,3 +374,5 @@ void RotatePoint( double* pX, double* pY, int angle ) *pY = fpy; *pY = fpy; } } } } include/pcbstruct.h +22 −2 Original line number Original line Diff line number Diff line Loading @@ -235,7 +235,6 @@ public: #if defined(DEBUG) #if defined(DEBUG) /** /** * Function GetClass * Function GetClass * returns the class name. * returns the class name. Loading Loading @@ -264,7 +263,7 @@ public: * @param typeloc * @param typeloc * @return EDA_BaseStruct* - if a direct hit, else NULL. * @return EDA_BaseStruct* - if a direct hit, else NULL. */ */ EDA_BaseStruct* FindPadOrModule( const wxPoint& refPos, int layer, int typeloc ); EDA_BaseStruct* FindPadOrModule( const wxPoint& refPos, int layer ); #endif #endif }; }; Loading Loading @@ -322,6 +321,27 @@ public: void UnLink( void ); void UnLink( void ); void Copy( DRAWSEGMENT* source ); void Copy( DRAWSEGMENT* source ); /** * Function HitTest * tests if the given wxPoint is within the bounds of this object. * @param ref_pos A wxPoint to test * @return bool - true if a hit, else false */ bool HitTest( const wxPoint& ref_pos ); #if defined(DEBUG) /** * Function GetClass * returns the class name. * @return wxString */ wxString GetClass() const { return wxT("pgraphic"); } #endif }; }; Loading include/trigo.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -7,7 +7,7 @@ #define TRIGO_H #define TRIGO_H /* Prototype des fonctions de TRIGO.CC */ /* Prototype des fonctions de trigo.cpp */ void RotatePoint(int *pX, int *pY, int angle); void RotatePoint(int *pX, int *pY, int angle); void RotatePoint(int *pX, int *pY, int cx, int cy, int angle); void RotatePoint(int *pX, int *pY, int cx, int cy, int angle); void RotatePoint(wxPoint *point, const wxPoint & centre, int angle); void RotatePoint(wxPoint *point, const wxPoint & centre, int angle); Loading @@ -19,6 +19,7 @@ int ArcTangente(int dy, int dx); Analogue a atan2 ( mais plus rapide pour les caculs si Analogue a atan2 ( mais plus rapide pour les caculs si l'angle est souvent 0, -1800, ou +- 900 */ l'angle est souvent 0, -1800, ou +- 900 */ bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY ); Loading pcbnew/class_board.cpp +29 −40 Original line number Original line Diff line number Diff line Loading @@ -290,75 +290,64 @@ void BOARD::Show( int nestLevel, std::ostream& os ) // see pcbstruct.h // see pcbstruct.h EDA_BaseStruct* BOARD::FindPadOrModule( const wxPoint& refPos, int layer, int typeloc ) EDA_BaseStruct* BOARD::FindPadOrModule( const wxPoint& refPos, int layer ) { { class PadOrModule : public INSPECTOR class PadOrModule : public INSPECTOR { { public: public: EDA_BaseStruct* found; EDA_BaseStruct* found; int layer; int layer; int typeloc; PadOrModule( int alayer, int atypeloc ) : PadOrModule( int alayer ) : found(0), found(0), // found is NULL layer(alayer), layer(alayer) typeloc(atypeloc) {} SEARCH_RESULT Inspect( EDA_BaseStruct* testItem, const void* testData ) { const wxPoint* refPos = (const wxPoint*) testData; if( testItem->m_StructType == TYPEMODULE ) { { int mlayer = ((MODULE*)testItem)->m_Layer; if( typeloc & MATCH_LAYER ) { if( layer != mlayer ) return SEARCH_CONTINUE; } } if( typeloc & VISIBLE_ONLY ) SEARCH_RESULT Inspect( EDA_BaseStruct* testItem, const void* testData ) { { if( !IsModuleLayerVisible(mlayer) ) const wxPoint& refPos = *(const wxPoint*) testData; return SEARCH_CONTINUE; } if( testItem->HitTest( *refPos ) ) if( testItem->m_StructType == TYPEPAD ) { if( testItem->HitTest( refPos ) ) { { found = testItem; found = testItem; return SEARCH_QUIT; return SEARCH_QUIT; } } } } else if( testItem->m_StructType == TYPEPAD ) else if( testItem->m_StructType == TYPEMODULE ) { int mlayer = ((MODULE*)testItem)->m_Layer; // consider only visible modules if( IsModuleLayerVisible( mlayer ) ) { { if( testItem->HitTest( *refPos ) ) if( testItem->HitTest( refPos ) ) { { // save regardless of layer test, but only quit if // layer matches, otherwise use this item if no future // layer match. found = testItem; found = testItem; if( layer == mlayer ) return SEARCH_QUIT; return SEARCH_QUIT; } } } } else { int debug=1; /* this should not happen, because of scanTypes */ } } return SEARCH_CONTINUE; return SEARCH_CONTINUE; } } }; }; PadOrModule inspector1( layer, MATCH_LAYER ); PadOrModule inspector( layer ); PadOrModule inspector2( layer, VISIBLE_ONLY ); // search only for PADs first, then MODULES, and preferably a layer match static const KICAD_T scanTypes[] = { TYPEPAD, TYPEMODULE, EOT }; static const KICAD_T scanTypes[] = { TYPEPAD, TYPEMODULE, EOT }; // search the current layer first IterateForward( m_Modules, &inspector, &refPos, scanTypes ); if( SEARCH_QUIT == IterateForward( m_Modules, &inspector1, &refPos, scanTypes ) ) return inspector1.found; // if not found, set layer to don't care and search again if( SEARCH_QUIT == IterateForward( m_Modules, &inspector2, &refPos, scanTypes ) ) return inspector2.found; return NULL; return inspector.found; } } #endif #endif Loading
change_log.txt +14 −0 Original line number Original line Diff line number Diff line Loading @@ -5,6 +5,20 @@ Please add newer entries at the top, list the date and your name with email address. email address. 2007-Aug-08 UPDATE Dick Hollenbeck <dick@softplc.com> ================================================================================ + pcbnew & common * Renamed locate.cpp's distance() to DistanceTest() and moved it to trigo.cpp. Pass more parameters to DistanceTest and removed globals that were used by distance() in locate.cpp. Moved and renamed DistanceTest function proto from protos.h to trigo.h. * Implemented HitTest() for class_cotation, class_mire, and a few other classes by factoring out existing code from locate.cpp. locate.cpp should operate exactly the same as before. * Detected that the suspected class_module hit-testing bug was not real, i.e. no bug found. 2007-aug-08 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> 2007-aug-08 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> ================================================================================ ================================================================================ + eeschema + eeschema Loading
common/trigo.cpp +159 −0 Original line number Original line Diff line number Diff line Loading @@ -9,6 +9,163 @@ #include "trigo.h" #include "trigo.h" /*****************************/ bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY ) /*****************************/ /* * Calcul de la distance du curseur souris a un segment de droite : * ( piste, edge, contour module .. * retourne: * false si distance > seuil * true si distance <= seuil * Variables utilisees ( doivent etre initialisees avant appel , et * sont ramenees au repere centre sur l'origine du segment) * dx, dy = coord de l'extremite segment. * spot_cX,spot_cY = coord du curseur souris * la recherche se fait selon 4 cas: * segment horizontal * segment vertical * segment 45 * segment quelconque */ { int cXrot, cYrot, /* coord du point (souris) dans le repere tourne */ segX, segY; /* coord extremite segment tj >= 0 */ int pointX, pointY; /* coord point a tester dans repere modifie dans lequel * segX et segY sont >=0 */ segX = dx; segY = dy; pointX = spot_cX; pointY = spot_cY; /*Recalcul coord pour que le segment soit dans 1er quadrant (coord >= 0)*/ if( segX < 0 ) /* mise en >0 par symetrie par rapport a l'axe Y */ { segX = -segX; pointX = -pointX; } if( segY < 0 ) /* mise en > 0 par symetrie par rapport a l'axe X */ { segY = -segY; pointY = -pointY; } if( segY == 0 ) /* piste Horizontale */ { if( abs( pointY ) <= seuil ) { if( (pointX >= 0) && (pointX <= segX) ) return 1; /* Etude des extremites : cercle de rayon seuil */ if( (pointX < 0) && (pointX >= -seuil) ) { if( ( (pointX * pointX) + (pointY * pointY) ) <= (seuil * seuil) ) return true; } if( (pointX > segX) && ( pointX <= (segX + seuil) ) ) { if( ( ( (pointX - segX) * (pointX - segX) ) + (pointY * pointY) ) <= (seuil * seuil) ) return true; } } } else if( segX == 0 ) /* piste verticale */ { if( abs( pointX ) <= seuil ) { if( (pointY >= 0 ) && (pointY <= segY) ) return true; if( (pointY < 0) && (pointY >= -seuil) ) { if( ( (pointY * pointY) + (pointX * pointX) ) <= (seuil * seuil) ) return true; } if( (pointY > segY) && ( pointY <= (segY + seuil) ) ) { if( ( ( (pointY - segY) * (pointY - segY) ) + (pointX * pointX) ) <= (seuil * seuil) ) return true; } } } else if( segX == segY ) /* piste a 45 degre */ { /* on fait tourner les axes de 45 degre. la souris a alors les * coord : x1 = x*cos45 + y*sin45 * y1 = y*cos45 - x*sin45 * et le segment de piste est alors horizontal. * recalcul des coord de la souris ( sin45 = cos45 = .707 = 7/10 * remarque : sin ou cos45 = .707, et lors du recalcul des coord * dx45 et dy45, lec coeff .707 est neglige, dx et dy sont en fait .707 fois * trop grands. (c.a.d trop petits) * spot_cX,Y doit etre * par .707 * .707 = 0.5 */ cXrot = (pointX + pointY) >> 1; cYrot = (pointY - pointX) >> 1; /* recalcul des coord de l'extremite du segment , qui sera vertical * suite a l'orientation des axes sur l'ecran : dx45 = pointX (ou pointY) * et est en fait 1,414 plus grand , et dy45 = 0 */ // seuil doit etre * .707 pour tenir compte du coeff de reduction sur dx,dy seuil *= 7; seuil /= 10; if( abs( cYrot ) <= seuil ) /* ok sur axe vertical) */ { if( (cXrot >= 0) && (cXrot <= segX) ) return true; /* Etude des extremites : cercle de rayon seuil */ if( (cXrot < 0) && (cXrot >= -seuil) ) { if( ( (cXrot * cXrot) + (cYrot * cYrot) ) <= (seuil * seuil) ) return true; } if( (cXrot > segX) && ( cXrot <= (segX + seuil) ) ) { if( ( ( (cXrot - segX) * (cXrot - segX) ) + (cYrot * cYrot) ) <= (seuil * seuil) ) return true; } } } else /* orientation quelconque */ { /* On fait un changement d'axe (rotation) de facon a ce que le segment * de piste soit horizontal dans le nouveau repere */ int angle; angle = (int) ( atan2( (float) segY, (float) segX ) * 1800 / M_PI); cXrot = pointX; cYrot = pointY; RotatePoint( &cXrot, &cYrot, angle ); /* Rotation du point a tester */ RotatePoint( &segX, &segY, angle ); /* Rotation du segment */ /* la piste est Horizontale , par suite des modifs de coordonnes * et d'axe, donc segX = longueur du segment */ if( abs( cYrot ) <= seuil ) /* ok sur axe vertical) */ { if( (cXrot >= 0) && (cXrot <= segX) ) return true; /* Etude des extremites : cercle de rayon seuil */ if( (cXrot < 0) && (cXrot >= -seuil) ) { if( ( (cXrot * cXrot) + (cYrot * cYrot) ) <= (seuil * seuil) ) return true; } if( (cXrot > segX) && ( cXrot <= (segX + seuil) ) ) { if( ( ( (cXrot - segX) * (cXrot - segX) ) + (cYrot * cYrot) ) <= (seuil * seuil) ) return true; } } } return false; } /***********************************/ /***********************************/ int ArcTangente( int dy, int dx ) int ArcTangente( int dy, int dx ) /***********************************/ /***********************************/ Loading Loading @@ -217,3 +374,5 @@ void RotatePoint( double* pX, double* pY, int angle ) *pY = fpy; *pY = fpy; } } } }
include/pcbstruct.h +22 −2 Original line number Original line Diff line number Diff line Loading @@ -235,7 +235,6 @@ public: #if defined(DEBUG) #if defined(DEBUG) /** /** * Function GetClass * Function GetClass * returns the class name. * returns the class name. Loading Loading @@ -264,7 +263,7 @@ public: * @param typeloc * @param typeloc * @return EDA_BaseStruct* - if a direct hit, else NULL. * @return EDA_BaseStruct* - if a direct hit, else NULL. */ */ EDA_BaseStruct* FindPadOrModule( const wxPoint& refPos, int layer, int typeloc ); EDA_BaseStruct* FindPadOrModule( const wxPoint& refPos, int layer ); #endif #endif }; }; Loading Loading @@ -322,6 +321,27 @@ public: void UnLink( void ); void UnLink( void ); void Copy( DRAWSEGMENT* source ); void Copy( DRAWSEGMENT* source ); /** * Function HitTest * tests if the given wxPoint is within the bounds of this object. * @param ref_pos A wxPoint to test * @return bool - true if a hit, else false */ bool HitTest( const wxPoint& ref_pos ); #if defined(DEBUG) /** * Function GetClass * returns the class name. * @return wxString */ wxString GetClass() const { return wxT("pgraphic"); } #endif }; }; Loading
include/trigo.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -7,7 +7,7 @@ #define TRIGO_H #define TRIGO_H /* Prototype des fonctions de TRIGO.CC */ /* Prototype des fonctions de trigo.cpp */ void RotatePoint(int *pX, int *pY, int angle); void RotatePoint(int *pX, int *pY, int angle); void RotatePoint(int *pX, int *pY, int cx, int cy, int angle); void RotatePoint(int *pX, int *pY, int cx, int cy, int angle); void RotatePoint(wxPoint *point, const wxPoint & centre, int angle); void RotatePoint(wxPoint *point, const wxPoint & centre, int angle); Loading @@ -19,6 +19,7 @@ int ArcTangente(int dy, int dx); Analogue a atan2 ( mais plus rapide pour les caculs si Analogue a atan2 ( mais plus rapide pour les caculs si l'angle est souvent 0, -1800, ou +- 900 */ l'angle est souvent 0, -1800, ou +- 900 */ bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY ); Loading
pcbnew/class_board.cpp +29 −40 Original line number Original line Diff line number Diff line Loading @@ -290,75 +290,64 @@ void BOARD::Show( int nestLevel, std::ostream& os ) // see pcbstruct.h // see pcbstruct.h EDA_BaseStruct* BOARD::FindPadOrModule( const wxPoint& refPos, int layer, int typeloc ) EDA_BaseStruct* BOARD::FindPadOrModule( const wxPoint& refPos, int layer ) { { class PadOrModule : public INSPECTOR class PadOrModule : public INSPECTOR { { public: public: EDA_BaseStruct* found; EDA_BaseStruct* found; int layer; int layer; int typeloc; PadOrModule( int alayer, int atypeloc ) : PadOrModule( int alayer ) : found(0), found(0), // found is NULL layer(alayer), layer(alayer) typeloc(atypeloc) {} SEARCH_RESULT Inspect( EDA_BaseStruct* testItem, const void* testData ) { const wxPoint* refPos = (const wxPoint*) testData; if( testItem->m_StructType == TYPEMODULE ) { { int mlayer = ((MODULE*)testItem)->m_Layer; if( typeloc & MATCH_LAYER ) { if( layer != mlayer ) return SEARCH_CONTINUE; } } if( typeloc & VISIBLE_ONLY ) SEARCH_RESULT Inspect( EDA_BaseStruct* testItem, const void* testData ) { { if( !IsModuleLayerVisible(mlayer) ) const wxPoint& refPos = *(const wxPoint*) testData; return SEARCH_CONTINUE; } if( testItem->HitTest( *refPos ) ) if( testItem->m_StructType == TYPEPAD ) { if( testItem->HitTest( refPos ) ) { { found = testItem; found = testItem; return SEARCH_QUIT; return SEARCH_QUIT; } } } } else if( testItem->m_StructType == TYPEPAD ) else if( testItem->m_StructType == TYPEMODULE ) { int mlayer = ((MODULE*)testItem)->m_Layer; // consider only visible modules if( IsModuleLayerVisible( mlayer ) ) { { if( testItem->HitTest( *refPos ) ) if( testItem->HitTest( refPos ) ) { { // save regardless of layer test, but only quit if // layer matches, otherwise use this item if no future // layer match. found = testItem; found = testItem; if( layer == mlayer ) return SEARCH_QUIT; return SEARCH_QUIT; } } } } else { int debug=1; /* this should not happen, because of scanTypes */ } } return SEARCH_CONTINUE; return SEARCH_CONTINUE; } } }; }; PadOrModule inspector1( layer, MATCH_LAYER ); PadOrModule inspector( layer ); PadOrModule inspector2( layer, VISIBLE_ONLY ); // search only for PADs first, then MODULES, and preferably a layer match static const KICAD_T scanTypes[] = { TYPEPAD, TYPEMODULE, EOT }; static const KICAD_T scanTypes[] = { TYPEPAD, TYPEMODULE, EOT }; // search the current layer first IterateForward( m_Modules, &inspector, &refPos, scanTypes ); if( SEARCH_QUIT == IterateForward( m_Modules, &inspector1, &refPos, scanTypes ) ) return inspector1.found; // if not found, set layer to don't care and search again if( SEARCH_QUIT == IterateForward( m_Modules, &inspector2, &refPos, scanTypes ) ) return inspector2.found; return NULL; return inspector.found; } } #endif #endif