Pcbnew: fix 45-degree snapping of ruler and dimension tools
This introduces a new util function in geometry_utils which snaps a vector to axes or 45 degree lines. This can be used whenever you want to snap a vector to these angles, but still want it to stay on a grid. This snapping is used for the dimension tool and the ruler tool. This is substantially simpler for two-point tools that the method used by the line tool, which uses DIRECTION_45. Fixes: lp:1780826 https://bugs.launchpad.net/kicad/+bug/1780826
This commit is contained in:
parent
9d15e58462
commit
7acc0b89f9
|
@ -30,6 +30,8 @@
|
||||||
#ifndef GEOMETRY_UTILS_H
|
#ifndef GEOMETRY_UTILS_H
|
||||||
#define GEOMETRY_UTILS_H
|
#define GEOMETRY_UTILS_H
|
||||||
|
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of segments to approximate a arc by segments
|
* @return the number of segments to approximate a arc by segments
|
||||||
* with a given max error (this number is >= 1)
|
* with a given max error (this number is >= 1)
|
||||||
|
@ -53,6 +55,45 @@ int GetArcToSegmentCount( int aRadius, int aErrorMax, double aArcAngleDegree );
|
||||||
*/
|
*/
|
||||||
double GetCircletoPolyCorrectionFactor( int aSegCountforCircle );
|
double GetCircletoPolyCorrectionFactor( int aSegCountforCircle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Snap a vector onto the nearest 0, 45 or 90 degree line.
|
||||||
|
*
|
||||||
|
* The magnitude of the vector is NOT kept, instead the co-ordinates are
|
||||||
|
* set equal (and/or opposite) or to zero as needed. The effect of this is
|
||||||
|
* that if the starting vector is on a square grid, the resulting snapped
|
||||||
|
* vector will still be on the same grid.
|
||||||
|
|
||||||
|
* @param a vector to be snapped
|
||||||
|
* @return the snapped vector
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
VECTOR2<T> GetVectorSnapped45( const VECTOR2<T>& aVec )
|
||||||
|
{
|
||||||
|
auto newVec = aVec;
|
||||||
|
const VECTOR2<T> absVec { std::abs( aVec.x ), std::abs( aVec.y ) };
|
||||||
|
|
||||||
|
if ( absVec.x > absVec.y * 2 )
|
||||||
|
{
|
||||||
|
// snap along x-axis
|
||||||
|
newVec.y = 0;
|
||||||
|
}
|
||||||
|
else if ( absVec.y > absVec.x * 2 )
|
||||||
|
{
|
||||||
|
// snap onto y-axis
|
||||||
|
newVec.x = 0;
|
||||||
|
}
|
||||||
|
else if ( absVec.x > absVec.y )
|
||||||
|
{
|
||||||
|
// snap away from x-axis towards 45
|
||||||
|
newVec.y = std::copysign( aVec.x, aVec.y );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// snap away from y-axis towards 45
|
||||||
|
newVec.x = std::copysign( aVec.y, aVec.x );
|
||||||
|
}
|
||||||
|
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // #ifndef GEOMETRY_UTILS_H
|
#endif // #ifndef GEOMETRY_UTILS_H
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#define PREVIEW_ITEMS_TWO_POINT_GEOMETRY_MANAGER_H
|
#define PREVIEW_ITEMS_TWO_POINT_GEOMETRY_MANAGER_H
|
||||||
|
|
||||||
#include <math/vector2d.h>
|
#include <math/vector2d.h>
|
||||||
#include <common.h>
|
#include <geometry/geometry_utils.h>
|
||||||
|
|
||||||
namespace KIGFX
|
namespace KIGFX
|
||||||
{
|
{
|
||||||
|
@ -63,11 +63,7 @@ public:
|
||||||
{
|
{
|
||||||
if( m_angleSnap )
|
if( m_angleSnap )
|
||||||
{
|
{
|
||||||
const auto vec = aEnd - m_origin;
|
m_end = GetVectorSnapped45( aEnd - m_origin ) + m_origin;
|
||||||
const auto len = vec.EuclideanNorm();
|
|
||||||
const auto angle = KiROUND( vec.Angle() / M_PI_4 ) * M_PI_4;
|
|
||||||
|
|
||||||
m_end = m_origin + VECTOR2I( len, 0 ).Rotate( angle );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <gal/graphics_abstraction_layer.h>
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <geometry/direction45.h>
|
#include <geometry/direction45.h>
|
||||||
|
#include <geometry/geometry_utils.h>
|
||||||
#include <ratsnest_data.h>
|
#include <ratsnest_data.h>
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
#include <scoped_set_reset.h>
|
#include <scoped_set_reset.h>
|
||||||
|
@ -478,12 +479,10 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
void DRAWING_TOOL::constrainDimension( DIMENSION* dimension )
|
void DRAWING_TOOL::constrainDimension( DIMENSION* dimension )
|
||||||
{
|
{
|
||||||
VECTOR2I lineVector( dimension->GetEnd() - dimension->GetOrigin() );
|
const VECTOR2I lineVector{ dimension->GetEnd() - dimension->GetOrigin() };
|
||||||
double angle = lineVector.Angle();
|
|
||||||
double newAngle = KiROUND( angle / M_PI_4 ) * M_PI_4;
|
|
||||||
VECTOR2I newLineVector = lineVector.Rotate( newAngle - angle );
|
|
||||||
|
|
||||||
dimension->SetEnd( dimension->GetOrigin() + static_cast<wxPoint>( newLineVector ) );
|
dimension->SetEnd( wxPoint(
|
||||||
|
VECTOR2I( dimension->GetOrigin() ) + GetVectorSnapped45( lineVector ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue