diff --git a/eeschema/lib_arc.cpp b/eeschema/lib_arc.cpp index d65311144d..96b08450e6 100644 --- a/eeschema/lib_arc.cpp +++ b/eeschema/lib_arc.cpp @@ -35,6 +35,7 @@ #include #include #include +#include // Helper function static inline wxPoint twoPointVector( const wxPoint &startPoint, const wxPoint &endPoint ) @@ -52,10 +53,6 @@ LIB_ARC::LIB_ARC( LIB_PART* aParent ) : LIB_ITEM( LIB_ARC_T, aParent ) m_Fill = NO_FILL; m_isFillable = true; m_editState = 0; - m_lastEditState = 0; - m_editCenterDistance = 0.0; - m_editSelectPoint = ARC_STATUS_START; - m_editDirection = 0; } @@ -426,64 +423,76 @@ BITMAP_DEF LIB_ARC::GetMenuImage() const void LIB_ARC::BeginEdit( const wxPoint aPosition ) { m_ArcStart = m_ArcEnd = aPosition; - m_editState = m_lastEditState = 1; -} - - -bool LIB_ARC::ContinueEdit( const wxPoint aPosition ) -{ - if( m_editState == 1 ) // Second position yields the arc segment length. - { - m_ArcEnd = aPosition; - m_editState = 2; - return true; // Need third position to calculate center point. - } - - return false; -} - - -void LIB_ARC::EndEdit() -{ - m_lastEditState = 0; - m_editState = 0; + m_editState = 1; } void LIB_ARC::CalcEdit( const wxPoint& aPosition ) { - if( m_editState == 1 ) + // Edit state 0: drawing: place ArcStart + // Edit state 1: drawing: place ArcEnd (center calculated for 90-degree subtended angle) + // Edit state 2: point editing: move ArcStart (center calculated for invariant subtended angle) + // Edit state 3: point editing: move ArcEnd (center calculated for invariant subtended angle) + // Edit state 4: point editing: move center + + switch( m_editState ) { + case 0: + m_ArcStart = aPosition; m_ArcEnd = aPosition; + m_Pos = aPosition; + break; + + case 1: + m_ArcEnd = aPosition; + m_Radius = KiROUND( sqrt( pow( GetLineLength( m_ArcStart, m_ArcEnd ), 2 ) / 2.0 ) ); + break; + + case 2: + case 3: + { + wxPoint v = m_ArcStart - m_ArcEnd; + double chordBefore = v.x * v.x + v.y * v.y; + + if( m_editState == 2 ) + m_ArcStart = aPosition; + else + m_ArcEnd = aPosition; + + v = m_ArcStart - m_ArcEnd; + double chordAfter = v.x * v.x + v.y * v.y; + double ratio = chordAfter / chordBefore; + + m_Radius = KiROUND( sqrt( m_Radius * m_Radius * ratio ) ); + break; } - if( m_editState != m_lastEditState ) - m_lastEditState = m_editState; + case 4: + m_Radius = KiROUND( ( GetLineLength( m_ArcStart, aPosition ) + + GetLineLength( m_ArcEnd, aPosition ) ) / 2.0 ); + break; + } - // Keep the arc center point up to date. Otherwise, there will be edit graphic - // artifacts left behind from the initial draw. - int dx, dy; - int cX, cY; - double angle; + // Calculate center based on start, end, and radius + // + // Let 'l' be the length of the chord and 'm' the middle point of the chord + double l = GetLineLength( m_ArcStart, m_ArcEnd ); + wxPoint m = ( m_ArcStart + m_ArcEnd ) / 2; - cX = aPosition.x; - cY = aPosition.y; + // Calculate 'd', the vector from the chord midpoint to the center + wxPoint d; + d.x = KiROUND( sqrt( pow( m_Radius, 2 ) - pow( l/2, 2) ) * ( m_ArcStart.y - m_ArcEnd.y ) / l ); + d.y = KiROUND( sqrt( pow( m_Radius, 2 ) - pow( l/2, 2) ) * ( m_ArcEnd.x - m_ArcStart.x ) / l ); - dx = m_ArcEnd.x - m_ArcStart.x; - dy = m_ArcEnd.y - m_ArcStart.y; - cX -= m_ArcStart.x; - cY -= m_ArcStart.y; - angle = ArcTangente( dy, dx ); - RotatePoint( &dx, &dy, angle ); /* The segment dx, dy is horizontal - * -> Length = dx, dy = 0 */ - RotatePoint( &cX, &cY, angle ); - cX = dx / 2; /* cX, cY is on the median segment 0.0 a dx, 0 */ + if( d.x < 0 || d.y < 0 ) // sqrt() doesn't like really small numbers... + d = { 0, 0 }; + + wxPoint c1 = m + d; + wxPoint c2 = m - d; + wxPoint test = ( m_editState == 4 ) ? aPosition : m_Pos; + + m_Pos = ( GetLineLength( c1, test ) < GetLineLength( c2, test ) ) ? c1 : c2; - RotatePoint( &cX, &cY, -angle ); - cX += m_ArcStart.x; - cY += m_ArcStart.y; - m_Pos.x = cX; - m_Pos.y = cY; CalcRadiusAngles(); } diff --git a/eeschema/lib_arc.h b/eeschema/lib_arc.h index 3ec4aa34d1..f4255bc660 100644 --- a/eeschema/lib_arc.h +++ b/eeschema/lib_arc.h @@ -47,11 +47,7 @@ class LIB_ARC : public LIB_ITEM wxPoint m_ArcEnd; /* Arc end position. */ wxPoint m_Pos; /* Radius center point. */ int m_Width; /* Line width */ - double m_editCenterDistance; - SELECT_T m_editSelectPoint; int m_editState; - int m_editDirection; - int m_lastEditState; void print( wxDC* aDC, const wxPoint& aOffset, void* aData, const TRANSFORM& aTransform ) override; @@ -84,8 +80,7 @@ public: void BeginEdit( const wxPoint aStartPoint ) override; void CalcEdit( const wxPoint& aPosition ) override; - bool ContinueEdit( const wxPoint aNextPoint ) override; - void EndEdit() override; + void SetEditState( int aState ) { m_editState = aState; } void Offset( const wxPoint& aOffset ) override; diff --git a/eeschema/tools/ee_point_editor.cpp b/eeschema/tools/ee_point_editor.cpp index 12f158964e..c21782255e 100644 --- a/eeschema/tools/ee_point_editor.cpp +++ b/eeschema/tools/ee_point_editor.cpp @@ -249,9 +249,6 @@ void EE_POINT_EDITOR::updateEditedPoint( const TOOL_EVENT& aEvent ) if( m_editedPoint != point ) setEditedPoint( point ); - - if( point ) - m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); } @@ -427,10 +424,24 @@ void EE_POINT_EDITOR::updateItem() const case LIB_ARC_T: { LIB_ARC* arc = (LIB_ARC*) item; + int i = getEditedPointIndex(); + + if( i == ARC_CENTER ) + { + arc->SetEditState( 4 ); + arc->CalcEdit( mapCoords( m_editPoints->Point( ARC_CENTER ).GetPosition() ) ); + } + else if( i == ARC_START ) + { + arc->SetEditState( 2 ); + arc->CalcEdit( mapCoords( m_editPoints->Point( ARC_START ).GetPosition() ) ); + } + else if( i == ARC_END ) + { + arc->SetEditState( 3 ); + arc->CalcEdit( mapCoords( m_editPoints->Point( ARC_END ).GetPosition() ) ); + } - arc->SetPosition( mapCoords( m_editPoints->Point( ARC_CENTER ).GetPosition() ) ); - arc->SetStart( mapCoords( m_editPoints->Point( ARC_START ).GetPosition() ) ); - arc->SetEnd( mapCoords( m_editPoints->Point( ARC_END ).GetPosition() ) ); break; } @@ -685,12 +696,15 @@ void EE_POINT_EDITOR::setEditedPoint( EDIT_POINT* aPoint ) if( aPoint ) { + m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); controls->ForceCursorPosition( true, aPoint->GetPosition() ); controls->ShowCursor( true ); } else { - controls->ShowCursor( false ); + if( m_frame->ToolStackIsEmpty() ) + controls->ShowCursor( false ); + controls->ForceCursorPosition( false ); } diff --git a/pagelayout_editor/tools/pl_point_editor.cpp b/pagelayout_editor/tools/pl_point_editor.cpp index 5fc275e63f..9b4f36c080 100644 --- a/pagelayout_editor/tools/pl_point_editor.cpp +++ b/pagelayout_editor/tools/pl_point_editor.cpp @@ -144,9 +144,6 @@ void PL_POINT_EDITOR::updateEditedPoint( const TOOL_EVENT& aEvent ) if( m_editedPoint != point ) setEditedPoint( point ); - - if( point ) - m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); } @@ -396,12 +393,15 @@ void PL_POINT_EDITOR::setEditedPoint( EDIT_POINT* aPoint ) if( aPoint ) { + m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); controls->ForceCursorPosition( true, aPoint->GetPosition() ); controls->ShowCursor( true ); } else { - controls->ShowCursor( false ); + if( m_frame->ToolStackIsEmpty() ) + controls->ShowCursor( false ); + controls->ForceCursorPosition( false ); } diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 2824ebe2ce..117530eb4f 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -287,9 +287,6 @@ void POINT_EDITOR::updateEditedPoint( const TOOL_EVENT& aEvent ) if( m_editedPoint != point ) setEditedPoint( point ); - - if( point ) - frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); } @@ -788,12 +785,15 @@ void POINT_EDITOR::setEditedPoint( EDIT_POINT* aPoint ) if( aPoint ) { + frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); controls->ForceCursorPosition( true, aPoint->GetPosition() ); controls->ShowCursor( true ); } else { - controls->ShowCursor( false ); + if( frame()->ToolStackIsEmpty() ) + controls->ShowCursor( false ); + controls->ForceCursorPosition( false ); }