diff --git a/common/base_screen.cpp b/common/base_screen.cpp index 7c92d64dbe..7f65548a7e 100644 --- a/common/base_screen.cpp +++ b/common/base_screen.cpp @@ -70,17 +70,19 @@ void BASE_SCREEN::InitDataPoints( const wxSize& aPageSizeIU ) { if( m_Center ) { - m_crossHairPosition.x = m_crossHairPosition.y = 0; + m_crossHairPosition.x = 0; + m_crossHairPosition.y = 0; m_DrawOrg.x = -aPageSizeIU.x / 2; m_DrawOrg.y = -aPageSizeIU.y / 2; } else { - m_DrawOrg.x = m_DrawOrg.y = 0; - m_crossHairPosition.x = aPageSizeIU.x / 2; m_crossHairPosition.y = aPageSizeIU.y / 2; + + m_DrawOrg.x = 0; + m_DrawOrg.y = 0; } m_O_Curseur.x = m_O_Curseur.y = 0; @@ -142,6 +144,8 @@ bool BASE_SCREEN::SetZoom( double coeff ) if( coeff == m_Zoom ) return false; + wxLogDebug( "Zoom:%16g 1/Zoom:%16g", coeff, 1/coeff ); + m_Zoom = coeff; return true; @@ -168,12 +172,10 @@ bool BASE_SCREEN::SetNextZoom() bool BASE_SCREEN::SetPreviousZoom() { - size_t i; - if( m_ZoomList.IsEmpty() || m_Zoom <= m_ZoomList[0] ) return false; - for( i = m_ZoomList.GetCount(); i != 0; i-- ) + for( unsigned i = m_ZoomList.GetCount(); i != 0; i-- ) { if( m_Zoom > m_ZoomList[i - 1] ) { @@ -191,8 +193,7 @@ bool BASE_SCREEN::SetLastZoom() if( m_ZoomList.IsEmpty() || m_Zoom == m_ZoomList.Last() ) return false; - SetZoom( m_ZoomList.Last() ); - return true; + return SetZoom( m_ZoomList.Last() ); } @@ -216,11 +217,9 @@ void BASE_SCREEN::SetGrid( const wxRealPoint& size ) { wxASSERT( !m_grids.empty() ); - size_t i; - GRID_TYPE nearest_grid = m_grids[0]; - for( i = 0; i < m_grids.size(); i++ ) + for( unsigned i = 0; i < m_grids.size(); i++ ) { if( m_grids[i].m_Size == size ) { @@ -228,7 +227,7 @@ void BASE_SCREEN::SetGrid( const wxRealPoint& size ) return; } - // keep trace of the nearest grill size, if the exact size is not found + // keep track of the nearest larger grid size, if the exact size is not found if ( size.x < m_grids[i].m_Size.x ) nearest_grid = m_grids[i]; } @@ -245,9 +244,7 @@ void BASE_SCREEN::SetGrid( int id ) { wxASSERT( !m_grids.empty() ); - size_t i; - - for( i = 0; i < m_grids.size(); i++ ) + for( unsigned i = 0; i < m_grids.size(); i++ ) { if( m_grids[i].m_Id == id ) { @@ -266,9 +263,7 @@ void BASE_SCREEN::SetGrid( int id ) void BASE_SCREEN::AddGrid( const GRID_TYPE& grid ) { - size_t i; - - for( i = 0; i < m_grids.size(); i++ ) + for( unsigned i = 0; i < m_grids.size(); i++ ) { if( m_grids[i].m_Size == grid.m_Size && grid.m_Id != ID_POPUP_GRID_USER ) { diff --git a/common/drawframe.cpp b/common/drawframe.cpp index 7bd1f1441b..fa2f27173d 100644 --- a/common/drawframe.cpp +++ b/common/drawframe.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -495,211 +496,6 @@ bool EDA_DRAW_FRAME::HandleBlockEnd( wxDC* DC ) } -void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPosition ) -{ - int unitsX, unitsY, posX, posY; - wxSize clientSize, logicalClientSize, virtualSize; - BASE_SCREEN* screen = GetScreen(); - bool noRefresh = true; - - if( screen == NULL || m_canvas == NULL ) - return; - - double scalar = screen->GetScalingFactor(); - - wxLogTrace( traceScrollSettings, wxT( "Center Position = ( %d, %d ), scalar = %0.5f." ), - aCenterPosition.x, aCenterPosition.y, scalar ); - - // Calculate the portion of the drawing that can be displayed in the - // client area at the current zoom level. - clientSize = m_canvas->GetClientSize(); - - // The logical size of the client window. - logicalClientSize.x = KiROUND( (double) clientSize.x / scalar ); - logicalClientSize.y = KiROUND( (double) clientSize.y / scalar ); - - // A corner of the drawing in internal units. - wxSize corner = GetPageSizeIU(); - - // The drawing rectangle logical units - wxRect drawingRect( wxPoint( 0, 0 ), corner ); - - wxLogTrace( traceScrollSettings, wxT( "Logical drawing rect = ( %d, %d, %d, %d )." ), - drawingRect.x, drawingRect.y, drawingRect.width, drawingRect.height ); - wxLogTrace( traceScrollSettings, wxT( " left %d, right %d, top %d, bottome %d" ), - drawingRect.GetLeft(), drawingRect.GetRight(), - drawingRect.GetTop(), drawingRect.GetBottom() ); - - // The size of the client rectangle in logical units. - int x = KiROUND( (double) aCenterPosition.x - ( (double) logicalClientSize.x / 2.0 ) ); - int y = KiROUND( (double) aCenterPosition.y - ( (double) logicalClientSize.y / 2.0 ) ); - - // If drawn around the center, adjust the client rectangle accordingly. - if( screen->m_Center ) - { - x += KiROUND( (double) drawingRect.width / 2.0 ); - y += KiROUND( (double) drawingRect.height / 2.0 ); - } - - wxRect logicalClientRect( wxPoint( x, y ), logicalClientSize ); - - wxLogTrace( traceScrollSettings, wxT( "Logical client rect = ( %d, %d, %d, %d )." ), - logicalClientRect.x, logicalClientRect.y, - logicalClientRect.width, logicalClientRect.height ); - wxLogTrace( traceScrollSettings, wxT( " left %d, right %d, top %d, bottome %d" ), - logicalClientRect.GetLeft(), logicalClientRect.GetRight(), - logicalClientRect.GetTop(), logicalClientRect.GetBottom() ); - - if( drawingRect == logicalClientRect ) - { - virtualSize = drawingRect.GetSize(); - } - else - { - if( drawingRect.GetLeft() < logicalClientRect.GetLeft() && drawingRect.GetRight() > logicalClientRect.GetRight() ) - { - virtualSize.x = drawingRect.GetSize().x; - } - else - { - int drawingCenterX = drawingRect.x + ( drawingRect.width / 2 ); - int clientCenterX = logicalClientRect.x + ( logicalClientRect.width / 2 ); - - if( logicalClientRect.width > drawingRect.width ) - { - if( drawingCenterX > clientCenterX ) - virtualSize.x = ( drawingCenterX - logicalClientRect.GetLeft() ) * 2; - else if( drawingCenterX < clientCenterX ) - virtualSize.x = ( logicalClientRect.GetRight() - drawingCenterX ) * 2; - else - virtualSize.x = logicalClientRect.width; - } - else - { - if( drawingCenterX > clientCenterX ) - virtualSize.x = drawingRect.width + - ( (drawingRect.GetLeft() - logicalClientRect.GetLeft() ) * 2 ); - else if( drawingCenterX < clientCenterX ) - virtualSize.x = drawingRect.width + - ( (logicalClientRect.GetRight() - drawingRect.GetRight() ) * 2 ); - else - virtualSize.x = drawingRect.width; - } - } - - if( drawingRect.GetTop() < logicalClientRect.GetTop() && drawingRect.GetBottom() > logicalClientRect.GetBottom() ) - { - virtualSize.y = drawingRect.GetSize().y; - } - else - { - int drawingCenterY = drawingRect.y + ( drawingRect.height / 2 ); - int clientCenterY = logicalClientRect.y + ( logicalClientRect.height / 2 ); - - if( logicalClientRect.height > drawingRect.height ) - { - if( drawingCenterY > clientCenterY ) - virtualSize.y = ( drawingCenterY - logicalClientRect.GetTop() ) * 2; - else if( drawingCenterY < clientCenterY ) - virtualSize.y = ( logicalClientRect.GetBottom() - drawingCenterY ) * 2; - else - virtualSize.y = logicalClientRect.height; - } - else - { - if( drawingCenterY > clientCenterY ) - virtualSize.y = drawingRect.height + - ( ( drawingRect.GetTop() - logicalClientRect.GetTop() ) * 2 ); - else if( drawingCenterY < clientCenterY ) - virtualSize.y = drawingRect.height + - ( ( logicalClientRect.GetBottom() - drawingRect.GetBottom() ) * 2 ); - else - virtualSize.y = drawingRect.height; - } - } - } - - - if( screen->m_Center ) - { - screen->m_DrawOrg.x = -( KiROUND( (double) virtualSize.x / 2.0 ) ); - screen->m_DrawOrg.y = -( KiROUND( (double) virtualSize.y / 2.0 ) ); - } - else - { - screen->m_DrawOrg.x = -( KiROUND( (double) (virtualSize.x - drawingRect.width) / 2.0 ) ); - screen->m_DrawOrg.y = -( KiROUND( (double) (virtualSize.y - drawingRect.height) / 2.0 ) ); - } - - /* Always set scrollbar pixels per unit to 1 unless you want the zoom - * around cursor to jump around. This reported problem occurs when the - * zoom point is not on a pixel per unit increment. If you set the - * pixels per unit to 10, you have potential for the zoom point to - * jump around +/-5 pixels from the nearest grid point. - */ - screen->m_ScrollPixelsPerUnitX = screen->m_ScrollPixelsPerUnitY = 1; - - // Calculate the number of scroll bar units for the given zoom level in device units. - unitsX = KiROUND( (double) virtualSize.x * scalar ); - unitsY = KiROUND( (double) virtualSize.y * scalar ); - - // Calculate the scroll bar position in logical units to place the center position at - // the center of client rectangle. - screen->SetScrollCenterPosition( aCenterPosition ); - posX = aCenterPosition.x - KiROUND( (double) logicalClientRect.width / 2.0 ) - - screen->m_DrawOrg.x; - posY = aCenterPosition.y - KiROUND( (double) logicalClientRect.height / 2.0 ) - - screen->m_DrawOrg.y; - - // Convert scroll bar position to device units. - posX = KiROUND( (double) posX * scalar ); - posY = KiROUND( (double) posY * scalar ); - - if( posX < 0 ) - { - wxLogTrace( traceScrollSettings, wxT( "Required scroll bar X position %d" ), posX ); - posX = 0; - } - - if( posX > unitsX ) - { - wxLogTrace( traceScrollSettings, wxT( "Required scroll bar X position %d" ), posX ); - posX = unitsX; - } - - if( posY < 0 ) - { - wxLogTrace( traceScrollSettings, wxT( "Required scroll bar Y position %d" ), posY ); - posY = 0; - } - - if( posY > unitsY ) - { - wxLogTrace( traceScrollSettings, wxT( "Required scroll bar Y position %d" ), posY ); - posY = unitsY; - } - - screen->m_ScrollbarPos = wxPoint( posX, posY ); - screen->m_ScrollbarNumber = wxSize( unitsX, unitsY ); - - wxLogTrace( traceScrollSettings, - wxT( "Drawing = (%d, %d), Client = (%d, %d), Offset = (%d, %d), \ -SetScrollbars(%d, %d, %d, %d, %d, %d)" ), - virtualSize.x, virtualSize.y, logicalClientSize.x, logicalClientSize.y, - screen->m_DrawOrg.x, screen->m_DrawOrg.y, - screen->m_ScrollPixelsPerUnitX, screen->m_ScrollPixelsPerUnitY, - screen->m_ScrollbarNumber.x, screen->m_ScrollbarNumber.y, - screen->m_ScrollbarPos.x, screen->m_ScrollbarPos.y ); - - m_canvas->SetScrollbars( screen->m_ScrollPixelsPerUnitX, - screen->m_ScrollPixelsPerUnitY, - screen->m_ScrollbarNumber.x, - screen->m_ScrollbarNumber.y, - screen->m_ScrollbarPos.x, - screen->m_ScrollbarPos.y, noRefresh ); -} - - void EDA_DRAW_FRAME::SetLanguage( wxCommandEvent& event ) { EDA_BASE_FRAME::SetLanguage( event ); @@ -858,3 +654,188 @@ bool EDA_DRAW_FRAME::HandleBlockBegin( wxDC* aDC, int aKey, const wxPoint& aPosi Block->SetMessageBlock( this ); return true; } + + +void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) +{ + BASE_SCREEN* screen = GetScreen(); + + if( screen == NULL || m_canvas == NULL ) + return; + + // There are no safety limits on these calculations, so in NANOMETRES build it + // still blows up. This is incomplete work. + + double scale = screen->GetScalingFactor(); + + wxLogTrace( traceScrollSettings, wxT( "Center Position = ( %d, %d ), scale = %.16g" ), + aCenterPositionIU.x, aCenterPositionIU.y, scale ); + + // Calculate the portion of the drawing that can be displayed in the + // client area at the current zoom level. + + // visible viewport in device units ~ pixels + wxSize clientSizeDU = m_canvas->GetClientSize(); + + // Size of the client window in IU + DSIZE clientSizeIU( clientSizeDU.x / scale, clientSizeDU.y / scale ); + + // Full drawing or "page" rectangle in internal units + DRECT pageRectIU( 0, 0, GetPageSizeIU().x, GetPageSizeIU().y ); + + // The upper left corner of the client rectangle in internal units. + double xIU = aCenterPositionIU.x - clientSizeIU.x / 2.0; + double yIU = aCenterPositionIU.y - clientSizeIU.y / 2.0; + + // If drawn around the center, adjust the client rectangle accordingly. + if( screen->m_Center ) + { + // half page offset. + xIU += pageRectIU.width / 2.0; + yIU += pageRectIU.height / 2.0; + } + + DRECT clientRectIU( xIU, yIU, clientSizeIU.x, clientSizeIU.y ); + DSIZE virtualSizeIU; + + if( pageRectIU.GetLeft() < clientRectIU.GetLeft() && pageRectIU.GetRight() > clientRectIU.GetRight() ) + { + virtualSizeIU.x = pageRectIU.GetSize().x; + } + else + { + double drawingCenterX = pageRectIU.x + ( pageRectIU.width / 2 ); + double clientCenterX = clientRectIU.x + ( clientRectIU.width / 2 ); + + if( clientRectIU.width > pageRectIU.width ) + { + if( drawingCenterX > clientCenterX ) + virtualSizeIU.x = ( drawingCenterX - clientRectIU.GetLeft() ) * 2; + else if( drawingCenterX < clientCenterX ) + virtualSizeIU.x = ( clientRectIU.GetRight() - drawingCenterX ) * 2; + else + virtualSizeIU.x = clientRectIU.width; + } + else + { + if( drawingCenterX > clientCenterX ) + virtualSizeIU.x = pageRectIU.width + + ( (pageRectIU.GetLeft() - clientRectIU.GetLeft() ) * 2 ); + else if( drawingCenterX < clientCenterX ) + virtualSizeIU.x = pageRectIU.width + + ( (clientRectIU.GetRight() - pageRectIU.GetRight() ) * 2 ); + else + virtualSizeIU.x = pageRectIU.width; + } + } + + if( pageRectIU.GetTop() < clientRectIU.GetTop() && pageRectIU.GetBottom() > clientRectIU.GetBottom() ) + { + virtualSizeIU.y = pageRectIU.GetSize().y; + } + else + { + int drawingCenterY = pageRectIU.y + ( pageRectIU.height / 2 ); + int clientCenterY = clientRectIU.y + ( clientRectIU.height / 2 ); + + if( clientRectIU.height > pageRectIU.height ) + { + if( drawingCenterY > clientCenterY ) + virtualSizeIU.y = ( drawingCenterY - clientRectIU.GetTop() ) * 2; + else if( drawingCenterY < clientCenterY ) + virtualSizeIU.y = ( clientRectIU.GetBottom() - drawingCenterY ) * 2; + else + virtualSizeIU.y = clientRectIU.height; + } + else + { + if( drawingCenterY > clientCenterY ) + virtualSizeIU.y = pageRectIU.height + + ( ( pageRectIU.GetTop() - clientRectIU.GetTop() ) * 2 ); + else if( drawingCenterY < clientCenterY ) + virtualSizeIU.y = pageRectIU.height + + ( ( clientRectIU.GetBottom() - pageRectIU.GetBottom() ) * 2 ); + else + virtualSizeIU.y = pageRectIU.height; + } + } + + if( screen->m_Center ) + { + screen->m_DrawOrg.x = -KiROUND( virtualSizeIU.x / 2.0 ); + screen->m_DrawOrg.y = -KiROUND( virtualSizeIU.y / 2.0 ); + } + else + { + screen->m_DrawOrg.x = -KiROUND( ( virtualSizeIU.x - pageRectIU.width ) / 2.0 ); + screen->m_DrawOrg.y = -KiROUND( ( virtualSizeIU.y - pageRectIU.height ) / 2.0 ); + } + + /* Always set scrollbar pixels per unit to 1 unless you want the zoom + * around cursor to jump around. This reported problem occurs when the + * zoom point is not on a pixel per unit increment. If you set the + * pixels per unit to 10, you have potential for the zoom point to + * jump around +/-5 pixels from the nearest grid point. + */ + screen->m_ScrollPixelsPerUnitX = screen->m_ScrollPixelsPerUnitY = 1; + + // Number of scroll bar units for the given zoom level in device units. + double unitsX = virtualSizeIU.x * scale; + double unitsY = virtualSizeIU.y * scale; + + // Calculate the scroll bar position in internal units to place the + // center position at the center of client rectangle. + screen->SetScrollCenterPosition( aCenterPositionIU ); + + double posX = aCenterPositionIU.x - clientRectIU.width /2.0 - screen->m_DrawOrg.x; + double posY = aCenterPositionIU.y - clientRectIU.height/2.0 - screen->m_DrawOrg.y; + + // Convert scroll bar position to device units. + posX = KiROUND( posX * scale ); + posY = KiROUND( posY * scale ); + + if( posX < 0 ) + { + wxLogTrace( traceScrollSettings, wxT( "Required scroll bar X position %d" ), posX ); + posX = 0; + } + + if( posX > unitsX ) + { + wxLogTrace( traceScrollSettings, wxT( "Required scroll bar X position %d" ), posX ); + posX = unitsX; + } + + if( posY < 0 ) + { + wxLogTrace( traceScrollSettings, wxT( "Required scroll bar Y position %d" ), posY ); + posY = 0; + } + + if( posY > unitsY ) + { + wxLogTrace( traceScrollSettings, wxT( "Required scroll bar Y position %d" ), posY ); + posY = unitsY; + } + + screen->m_ScrollbarPos = wxPoint( KiROUND( posX ), KiROUND( posY ) ); + screen->m_ScrollbarNumber = wxSize( KiROUND( unitsX ), KiROUND( unitsY ) ); + + wxLogTrace( traceScrollSettings, + wxT( "Drawing = (%.16g, %.16g), Client = (%.16g, %.16g), Offset = (%d, %d), SetScrollbars(%d, %d, %d, %d, %d, %d)" ), + virtualSizeIU.x, virtualSizeIU.y, clientSizeIU.x, clientSizeIU.y, + screen->m_DrawOrg.x, screen->m_DrawOrg.y, + screen->m_ScrollPixelsPerUnitX, screen->m_ScrollPixelsPerUnitY, + screen->m_ScrollbarNumber.x, screen->m_ScrollbarNumber.y, + screen->m_ScrollbarPos.x, screen->m_ScrollbarPos.y ); + + bool noRefresh = true; + + m_canvas->SetScrollbars( screen->m_ScrollPixelsPerUnitX, + screen->m_ScrollPixelsPerUnitY, + screen->m_ScrollbarNumber.x, + screen->m_ScrollbarNumber.y, + screen->m_ScrollbarPos.x, + screen->m_ScrollbarPos.y, noRefresh ); +} + diff --git a/common/drawpanel.cpp b/common/drawpanel.cpp index fe95da1366..ee3e828bdb 100644 --- a/common/drawpanel.cpp +++ b/common/drawpanel.cpp @@ -158,28 +158,34 @@ void EDA_DRAW_PANEL::DrawCrossHair( wxDC* aDC, int aColor ) if( m_cursorLevel != 0 || aDC == NULL || !m_showCrossHair ) return; - wxPoint Cursor = GetScreen()->GetCrossHairPosition(); + wxPoint cursor = GetScreen()->GetCrossHairPosition(); GRSetDrawMode( aDC, GR_XOR ); - if( GetParent()->m_cursorShape != 0 ) /* Draws full screen crosshair. */ + if( GetParent()->m_cursorShape != 0 ) // Draws full screen crosshair. { - wxSize clientSize = GetClientSize(); - wxPoint lineStart = wxPoint( Cursor.x, aDC->DeviceToLogicalY( 0 ) ); - wxPoint lineEnd = wxPoint( Cursor.x, aDC->DeviceToLogicalY( clientSize.y ) ); - GRLine( &m_ClipBox, aDC, lineStart, lineEnd, 0, aColor ); // Y axis - lineStart = wxPoint( aDC->DeviceToLogicalX( 0 ), Cursor.y ); - lineEnd = wxPoint( aDC->DeviceToLogicalX( clientSize.x ), Cursor.y ); - GRLine( &m_ClipBox, aDC, lineStart, lineEnd, 0, aColor ); // X axis + wxSize clientSize = GetClientSize(); + + // Y axis + wxPoint lineStart( cursor.x, aDC->DeviceToLogicalY( 0 ) ); + wxPoint lineEnd( cursor.x, aDC->DeviceToLogicalY( clientSize.y ) ); + + GRLine( &m_ClipBox, aDC, lineStart, lineEnd, 0, aColor ); + + // X axis + lineStart = wxPoint( aDC->DeviceToLogicalX( 0 ), cursor.y ); + lineEnd = wxPoint( aDC->DeviceToLogicalX( clientSize.x ), cursor.y ); + + GRLine( &m_ClipBox, aDC, lineStart, lineEnd, 0, aColor ); } else { int len = aDC->DeviceToLogicalXRel( CURSOR_SIZE ); - GRLine( &m_ClipBox, aDC, Cursor.x - len, Cursor.y, - Cursor.x + len, Cursor.y, 0, aColor ); - GRLine( &m_ClipBox, aDC, Cursor.x, Cursor.y - len, - Cursor.x, Cursor.y + len, 0, aColor ); + GRLine( &m_ClipBox, aDC, cursor.x - len, cursor.y, + cursor.x + len, cursor.y, 0, aColor ); + GRLine( &m_ClipBox, aDC, cursor.x, cursor.y - len, + cursor.x, cursor.y + len, 0, aColor ); } } @@ -469,7 +475,7 @@ void EDA_DRAW_PANEL::EraseScreen( wxDC* DC ) m_ClipBox.GetRight(), m_ClipBox.GetBottom(), 0, g_DrawBgColor, g_DrawBgColor ); - /* Set to one (1) to draw bounding box validate bounding box calculation. */ + // Set to one (1) to draw bounding box validate bounding box calculation. #if DEBUG_SHOW_CLIP_RECT EDA_RECT bBox = m_ClipBox; GRRect( NULL, DC, bBox.GetOrigin().x, bBox.GetOrigin().y, @@ -823,7 +829,7 @@ void EDA_DRAW_PANEL::OnMouseWheel( wxMouseEvent& event ) wxRect rect = wxRect( wxPoint( 0, 0 ), GetClientSize() ); - /* Ignore scroll events if the cursor is outside the drawing area. */ + // Ignore scroll events if the cursor is outside the drawing area. if( event.GetWheelRotation() == 0 || !GetParent()->IsEnabled() || !rect.Contains( event.GetPosition() ) ) { @@ -937,12 +943,12 @@ void EDA_DRAW_PANEL::OnMouseEvent( wxMouseEvent& event ) if( event.MiddleDown() ) localbutt = GR_M_MIDDLE_DOWN; - localrealbutt |= localbutt; /* compensation default wxGTK */ + localrealbutt |= localbutt; // compensation default wxGTK INSTALL_UNBUFFERED_DC( DC, this ); DC.SetBackground( *wxBLACK_BRUSH ); - /* Compute the cursor position in drawing (logical) units. */ + // Compute the cursor position in drawing (logical) units. screen->SetMousePosition( event.GetLogicalPosition( DC ) ); int kbstat = 0; @@ -1101,7 +1107,7 @@ void EDA_DRAW_PANEL::OnMouseEvent( wxMouseEvent& event ) GetEventHandler()->ProcessEvent( cmd ); } - /* Calling the general function on mouse changes (and pseudo key commands) */ + // Calling the general function on mouse changes (and pseudo key commands) GetParent()->GeneralControl( &DC, event.GetLogicalPosition( DC ), 0 ); /*******************************/ @@ -1165,17 +1171,16 @@ void EDA_DRAW_PANEL::OnMouseEvent( wxMouseEvent& event ) if( !m_enableMiddleButtonPan && event.MiddleIsDown() ) cmd_type |= MOUSE_MIDDLE; - /* A block command is started if the drag is enough. A small - * drag is ignored (it is certainly a little mouse move when - * clicking) not really a drag mouse - */ + // A block command is started if the drag is enough. A small + // drag is ignored (it is certainly a little mouse move when + // clicking) not really a drag mouse if( MinDragEventCount < MIN_DRAG_COUNT_FOR_START_BLOCK_COMMAND ) MinDragEventCount++; else { if( !GetParent()->HandleBlockBegin( &DC, cmd_type, m_CursorStartPos ) ) { - // should not occurs: error + // should not occur: error GetParent()->DisplayToolMsg( wxT( "EDA_DRAW_PANEL::OnMouseEvent() Block Error" ) ); } @@ -1264,8 +1269,8 @@ void EDA_DRAW_PANEL::OnKeyEvent( wxKeyEvent& event ) switch( localkey ) { - default: - break; + default: + break; case WXK_ESCAPE: m_abortRequest = true; diff --git a/common/zoom.cpp b/common/zoom.cpp index 0f0b6524f1..dab51a79e3 100644 --- a/common/zoom.cpp +++ b/common/zoom.cpp @@ -52,15 +52,13 @@ void EDA_DRAW_FRAME::RedrawScreen( const wxPoint& aCenterPoint, bool aWarpPointe m_canvas->Refresh(); m_canvas->Update(); - } +} -/** Redraw the screen with best zoom level and the best centering - * that shows all the page or the board - */ void EDA_DRAW_FRAME::Zoom_Automatique( bool aWarpPointer ) { - BASE_SCREEN * screen = GetScreen(); + BASE_SCREEN* screen = GetScreen(); + screen->SetZoom( BestZoom() ); // Set the best zoom and get center point. if( screen->m_FirstRedraw ) @@ -76,16 +74,15 @@ void EDA_DRAW_FRAME::Zoom_Automatique( bool aWarpPointer ) */ void EDA_DRAW_FRAME::Window_Zoom( EDA_RECT& Rect ) { - double scalex, bestscale; - wxSize size; - - /* Compute the best zoom */ + // Compute the best zoom Rect.Normalize(); - size = m_canvas->GetClientSize(); + + wxSize size = m_canvas->GetClientSize(); // Use ceil to at least show the full rect - scalex = (double) Rect.GetSize().x / size.x; - bestscale = (double) Rect.GetSize().y / size.y; + double scalex = (double) Rect.GetSize().x / size.x; + double bestscale = (double) Rect.GetSize().y / size.y; + bestscale = MAX( bestscale, scalex ); GetScreen()->SetScalingFactor( bestscale ); @@ -102,7 +99,6 @@ void EDA_DRAW_FRAME::OnZoom( wxCommandEvent& event ) if( m_canvas == NULL ) return; - int i; int id = event.GetId(); bool zoom_at_cursor = false; BASE_SCREEN* screen = GetScreen(); @@ -151,9 +147,11 @@ void EDA_DRAW_FRAME::OnZoom( wxCommandEvent& event ) break; default: + unsigned i; + i = id - ID_POPUP_ZOOM_LEVEL_START; - if( ( i < 0 ) || ( (size_t) i >= screen->m_ZoomList.GetCount() ) ) + if( i >= screen->m_ZoomList.GetCount() ) { wxLogDebug( wxT( "%s %d: index %d is outside the bounds of the zoom list." ), __TFILE__, __LINE__, i ); @@ -175,7 +173,7 @@ void EDA_DRAW_FRAME::AddMenuZoomAndGrid( wxMenu* MasterMenu ) int maxZoomIds; int zoom; wxString msg; - BASE_SCREEN * screen = m_canvas->GetScreen(); + BASE_SCREEN* screen = m_canvas->GetScreen(); msg = AddHotkeyName( _( "Center" ), m_HotkeysZoomAndGridList, HK_ZOOM_CENTER ); AddMenuItem( MasterMenu, ID_POPUP_ZOOM_CENTER, msg, KiBitmap( zoom_center_on_screen_xpm ) ); @@ -199,7 +197,7 @@ void EDA_DRAW_FRAME::AddMenuZoomAndGrid( wxMenu* MasterMenu ) maxZoomIds = ( (size_t) maxZoomIds < screen->m_ZoomList.GetCount() ) ? maxZoomIds : screen->m_ZoomList.GetCount(); - /* Populate zoom submenu. */ + // Populate zoom submenu. for( int i = 0; i < maxZoomIds; i++ ) { msg.Printf( wxT( "%g" ), screen->m_ZoomList[i] ); @@ -210,7 +208,7 @@ void EDA_DRAW_FRAME::AddMenuZoomAndGrid( wxMenu* MasterMenu ) zoom_choice->Check( ID_POPUP_ZOOM_LEVEL_START + i, true ); } - /* Create grid submenu as required. */ + // Create grid submenu as required. if( screen->GetGridCount() ) { wxMenu* gridMenu = new wxMenu; diff --git a/include/class_base_screen.h b/include/class_base_screen.h index 47a390f0e4..26c9b2b99a 100644 --- a/include/class_base_screen.h +++ b/include/class_base_screen.h @@ -276,16 +276,22 @@ public: /** * Function SetScalingFactor - * @param aScale = the the current scale used to draw items on screen - * draw coordinates are user coordinates * GetScalingFactor() + * sets the scaling factor of "device units per logical unit". + * If the output device is a screen, then "device units" are pixels. The + * "logical unit" is wx terminology, and corresponds to KiCad's "Internal Unit (IU)". + * + * Another way of thinking of scaling factor, when applied to a screen, + * is "pixelsPerIU". + + * @param aScale = the the current scale used to draw items onto the device context wxDC. + * device coordinates (pixels) = IU coordinates * GetScalingFactor() */ void SetScalingFactor( double aScale ); /** * Function GetZoom + * returns the * @return the current zoom factor - * Note: the zoom factor is NOT the scaling factor - * the scaling factor is m_ZoomScalar * GetZoom() */ double GetZoom() const; @@ -420,7 +426,7 @@ public: void ClearBlockCommand() { m_BlockLocate.Clear(); } - wxPoint GetScrollCenterPosition() const { return m_scrollCenter; } + const wxPoint& GetScrollCenterPosition() const { return m_scrollCenter; } void SetScrollCenterPosition( const wxPoint& aCenterPosition ) { m_scrollCenter = aCenterPosition; diff --git a/include/vector2d.h b/include/vector2d.h new file mode 100644 index 0000000000..6248b43a0d --- /dev/null +++ b/include/vector2d.h @@ -0,0 +1,399 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2010 Virtenio GmbH, Torsten Hueter, torsten.hueter virtenio.de + * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef VECTOR2D_H_ +#define VECTOR2D_H_ + +#include +#include + + +/// Forward declaration for template friends +template class VECTOR2; + +/* +#include +template ostream& operator<<( ostream &stream, const VECTOR2& vector ); +*/ + +/** + * Class VECTOR2 + * defines a general 2D-vector. + * + * This class uses templates to be universal. Several operators are provided to help easy implementing + * of linear algebra equations. + * + */ +template class VECTOR2 +{ +public: + T x, y; + + // Constructors + + /// Construct a 2D-vector with x, y = 0 + VECTOR2(); + + /// Copy constructor + VECTOR2( const VECTOR2& aVector ); + + /// Constructor with a wxPoint as argument + VECTOR2( const wxPoint& aPoint ); + + /// Constructor with a wxSize as argument + VECTOR2( const wxSize& aSize ); + + /// Construct a vector with given components x, y + VECTOR2( T x, T y ); + + /// Destructor + // virtual ~VECTOR2(); + + /** + * Function Euclidean Norm + * computes the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2). + * It is used to calculate the length of the vector. + * @return Scalar, the euclidean norm + */ + T EuclideanNorm(); + + /** + * Function Perpendicular + * computes the perpendicular vector + * @return Perpendicular vector + */ + VECTOR2 Perpendicular(); + + /** + * Function Angle + * computes the angle of the vector + * @return vector angle + */ + T Angle(); + + // Operators + + /// Assignment operator + VECTOR2& operator=( const VECTOR2& aVector ); + + /// Vector addition operator + VECTOR2 operator+( const VECTOR2& aVector ); + + /// Compound assignment operator + VECTOR2& operator+=( const VECTOR2& aVector ); + + /// Vector subtraction operator + VECTOR2 operator-( const VECTOR2& aVector ); + + /// Compound assignment operator + VECTOR2& operator-=( const VECTOR2& aVector ); + + /// Negate Vector operator + VECTOR2 operator-(); + + /// Scalar product operator + T operator*( const VECTOR2& aVector ); + + /// Multiplication with a factor + VECTOR2 operator*( const T& aFactor ); + + /// Cross product operator + T operator^( const VECTOR2& aVector ); + + /// Equality operator + const bool operator==( const VECTOR2& aVector ); + + /// Not equality operator + const bool operator!=( const VECTOR2& aVector ); + + /// Smaller than operator + bool operator<( const VECTOR2& aVector ); + bool operator<=( const VECTOR2& aVector ); + + /// Greater than operator + bool operator>( const VECTOR2& aVector ); + bool operator>=( const VECTOR2& aVector ); + + /// Casting to int vector + // operator VECTOR2(); + + /// Type casting operator for the class wxPoint + //operator wxPoint(); + + // friend ostream& operator<< ( ostream &stream, const VECTOR2& vector ); +}; + + +// ---------------------- +// --- Implementation --- +// ---------------------- + +template VECTOR2::VECTOR2( VECTOR2 const& aVector ) : + x( aVector.x ), y( aVector.y ) +{ +} + +template VECTOR2::VECTOR2() +{ + x = y = 0.0; +} + +template VECTOR2::VECTOR2( wxPoint const& aPoint ) +{ + x = T( aPoint.x ); + y = T( aPoint.y ); +} + +template VECTOR2::VECTOR2( wxSize const& aSize ) +{ + x = T( aSize.x ); + y = T( aSize.y ); +} + +template VECTOR2::VECTOR2( T aX, T aY ) +{ + x = aX; + y = aY; +} + +// Not required at the moment for this class +//template VECTOR2::~VECTOR2() +//{ +// // TODO Auto-generated destructor stub +//} + +template T VECTOR2::EuclideanNorm() +{ + return sqrt( ( *this ) * ( *this ) ); +} + +template T VECTOR2::Angle() +{ + return atan2(y, x); +} + +template VECTOR2 VECTOR2::Perpendicular(){ + VECTOR2 perpendicular(-y, x); + return perpendicular; +} + +/* +template ostream &operator<<( ostream &aStream, const VECTOR2& aVector ) +{ + aStream << "[ " << aVector.x << " | " << aVector.y << " ]"; + return aStream; +} +*/ + +template VECTOR2 &VECTOR2::operator=( const VECTOR2& aVector ) +{ + x = aVector.x; + y = aVector.y; + return *this; +} + +template VECTOR2 &VECTOR2::operator+=( const VECTOR2& aVector ) +{ + x += aVector.x; + y += aVector.y; + return *this; +} + +template VECTOR2& VECTOR2::operator-=( const VECTOR2& aVector ) +{ + x -= aVector.x; + y -= aVector.y; + return *this; +} + +//template VECTOR2::operator wxPoint() +//{ +// wxPoint point; +// point.x = (int) x; +// point.y = (int) y; +// return point; +//} +// + +//// Use correct rounding for casting to wxPoint +//template<> VECTOR2::operator wxPoint() +//{ +// wxPoint point; +// point.x = point.x >= 0 ? (int) ( x + 0.5 ) : (int) ( x - 0.5 ); +// point.y = point.y >= 0 ? (int) ( y + 0.5 ) : (int) ( y - 0.5 ); +// return point; +//} + +// Use correct rounding for casting double->int +//template<> VECTOR2::operator VECTOR2() +//{ +// VECTOR2 vector; +// vector.x = vector.x >= 0 ? (int) ( x + 0.5 ) : (int) ( x - 0.5 ); +// vector.y = vector.y >= 0 ? (int) ( y + 0.5 ) : (int) ( y - 0.5 ); +// return vector; +//} + +template VECTOR2 VECTOR2::operator+( const VECTOR2& aVector ) +{ + return VECTOR2 ( x + aVector.x, y + aVector.y ); +} + +template VECTOR2 VECTOR2::operator-( const VECTOR2& aVector ) +{ + return VECTOR2 ( x - aVector.x, y - aVector.y ); +} + +template VECTOR2 VECTOR2::operator-() +{ + return VECTOR2 ( -x, -y ); +} + +template T VECTOR2::operator*( const VECTOR2& aVector ) +{ + return aVector.x * x + aVector.y * y; +} + +template VECTOR2 VECTOR2::operator*( const T& aFactor ) +{ + VECTOR2 vector( x * aFactor, y * aFactor ); + return vector; +} + +template VECTOR2 operator*( const T& aFactor, const VECTOR2& aVector){ + VECTOR2 vector( aVector.x * aFactor, aVector.y * aFactor ); + return vector; +} + +template T VECTOR2::operator^( const VECTOR2& aVector ) +{ + return x * aVector.y - y * aVector.x; +} + +template bool VECTOR2::operator<( const VECTOR2& o ) +{ + // VECTOR2 vector( aVector ); + return (double( x ) * x + double( y ) * y) < (double( o.x ) * o.x + double( o.y ) * y); +} + +template bool VECTOR2::operator<=( const VECTOR2& aVector ) +{ + VECTOR2 vector( aVector ); + return ( *this * *this ) <= ( vector * vector ); +} + +template bool VECTOR2::operator>( const VECTOR2& aVector ) +{ + VECTOR2 vector( aVector ); + return ( *this * *this ) > ( vector * vector ); +} + +template bool VECTOR2::operator>=( const VECTOR2& aVector ) +{ + VECTOR2 vector( aVector ); + return ( *this * *this ) >= ( vector * vector ); +} + +template bool const VECTOR2::operator==( VECTOR2 const& aVector ) +{ + return ( aVector.x == x ) && ( aVector.y == y ); +} + +template bool const VECTOR2::operator!=( VECTOR2 const& aVector ) +{ + return ( aVector.x != x ) || ( aVector.y != y ); +} + + +/** + * Class RECT + * is a description of a rectangle in cartesion coordinate system. + */ +template class RECT +{ +public: + RECT() : x(0), y(0), width(0), height(0) {} + + RECT( T aX, T aY, T aWidth, T aHeight ): + x( aX ), y( aY ), width( aWidth ), height( aHeight ) + {} + + + /// Copy constructor + RECT( const RECT& aRect ) : + x( aRect.x ), y( aRect.y ), width( aRect.width ), height( aRect.height ) + {} + + /// Constructor with a wxPoint as argument? + + VECTOR2 GetSize() const { return VECTOR2 ( width, height ); } + VECTOR2 GetPosition() const { return VECTOR2 ( x, y ); } + + T GetLeft() const { return x; } + void SetLeft( T n ) { width += x - n; x = n; } + void MoveLeftTo( T n ) { x = n; } + + T GetTop() const { return y; } + void SetTop( T n ) { height += y - n; y = n; } + void MoveTopTo( T n ) { y = n; } + + T GetBottom() const { return y + height; } + void SetBottom( T n ) { height += n - ( y + height ); } + void MoveBottomTo( T n ) { y = n - height; } + + T GetRight() const { return x + width; } + void SetRight( T n ) { width += n - ( x + width ); } + void MoveRightTo( T n ) { x = n - width; } + + VECTOR2 GetLeftTop() const { return VECTOR2( x , y ); } + void SetLeftTop( const VECTOR2& pt ) { width += x - pt.x; height += y - pt.y; x = pt.x; y = pt.y; } + void MoveLeftTopTo( const VECTOR2 &pt ) { x = pt.x; y = pt.y; } + + VECTOR2 GetLeftBottom() const { return VECTOR2( x, y + height ); } + void SetLeftBottom( const VECTOR2& pt ) { width += x - pt.x; height += pt.y - (y + height); x = pt.x; } + void MoveLeftBottomTo( const VECTOR2& pt ) { x = pt.x; y = pt.y - height; } + + VECTOR2 GetRightTop() const { return VECTOR2( x + width, y ); } + void SetRightTop( const VECTOR2& pt ) { width += pt.x - ( x + width ); height += y - pt.y; y = pt.y; } + void MoveRightTopTo( const VECTOR2& pt ) { x = pt.x - width; y = pt.y; } + + VECTOR2 GetRightBottom() const { return VECTOR2( x + width, y + height ); } + void SetRightBottom( const VECTOR2& pt ) { width += pt.x - ( x + width ); height += pt.y - ( y + height); } + void MoveRightBottomTo( const VECTOR2& pt ) { x = pt.x - width; y = pt.y - height; } + + VECTOR2 GetCentre() const { return VECTOR2( x + width/2, y + height/2 ); } + void SetCentre( const VECTOR2& pt ) { MoveCentreTo( pt ); } + void MoveCentreTo( const VECTOR2& pt ) { x += pt.x - (x + width/2), y += pt.y - (y + height/2); } + + T x, y, width, height; +}; + + +typedef VECTOR2 DPOINT; +typedef DPOINT DSIZE; + +typedef RECT DRECT; + + +#endif // VECTOR2D_H_ diff --git a/include/wxstruct.h b/include/wxstruct.h index 0638ae84e2..9577af8dfa 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -647,6 +647,11 @@ public: */ void RedrawScreen( const wxPoint& aCenterPoint, bool aWarpPointer ); + /** + * Function Zoom_Automatique + * redraws the screen with best zoom level and the best centering + * that shows all the page or the board + */ void Zoom_Automatique( bool aWarpPointer ); /* Set the zoom level to show the area Rect */ diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 8e25126426..58870b2490 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -810,8 +810,12 @@ void PCB_BASE_FRAME::updateZoomSelectBox() { msg = _( "Zoom " ); - wxString value; - value.Printf( wxT( "%g" ), GetScreen()->m_ZoomList[i]); + wxString value = wxString::Format( wxT( "%g" ), + + // @todo could do scaling here and show a "percentage" + GetScreen()->m_ZoomList[i] + ); + msg += value; m_zoomSelectBox->Append( msg ); @@ -821,6 +825,7 @@ void PCB_BASE_FRAME::updateZoomSelectBox() } } + /* Function GetActiveViewerFrame * return a reference to the current Module Viewer Frame if exists * if called from the PCB editor, this is the m_ModuleViewerFrame diff --git a/pcbnew/classpcb.cpp b/pcbnew/classpcb.cpp index e04da70eac..c12497f27e 100644 --- a/pcbnew/classpcb.cpp +++ b/pcbnew/classpcb.cpp @@ -42,6 +42,12 @@ */ static const double pcbZoomList[] = { +#if defined( USE_PCBNEW_NANOMETRES ) + ZOOM_FACTOR( 0.1 ), + ZOOM_FACTOR( 0.2 ), + ZOOM_FACTOR( 0.3 ), +#endif + ZOOM_FACTOR( 0.5 ), ZOOM_FACTOR( 1.0 ), ZOOM_FACTOR( 1.5 ), @@ -57,10 +63,14 @@ static const double pcbZoomList[] = ZOOM_FACTOR( 80.0 ), ZOOM_FACTOR( 120.0 ), ZOOM_FACTOR( 200.0 ), - ZOOM_FACTOR( 350.0 ), + ZOOM_FACTOR( 300.0 ), + + +#if !defined( USE_PCBNEW_NANOMETRES ) ZOOM_FACTOR( 500.0 ), ZOOM_FACTOR( 1000.0 ), ZOOM_FACTOR( 2000.0 ) +#endif }; @@ -98,6 +108,9 @@ static GRID_TYPE pcbGridList[] = PCB_SCREEN::PCB_SCREEN( const wxSize& aPageSizeIU ) : BASE_SCREEN( SCREEN_T ) { + wxSize displayz = wxGetDisplaySize(); + + for( unsigned i = 0; i < DIM( pcbZoomList ); ++i ) m_ZoomList.Add( pcbZoomList[i] ); diff --git a/polygon/math_for_graphics.cpp b/polygon/math_for_graphics.cpp index 10498b2fbc..8b3e44968c 100644 --- a/polygon/math_for_graphics.cpp +++ b/polygon/math_for_graphics.cpp @@ -12,6 +12,14 @@ #define NM_PER_MIL 25400 +double Distance( double x1, double y1, double x2, double y2 ) +{ + double dx = x1 - x2; + double dy = y1 - y2; + double d = sqrt( dx * dx + dy * dy ); + return d; +} + /** * Function TestLineHit @@ -1031,7 +1039,7 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, y2 = el2.Center.Y + el2.yrad* sin( s2 ); } - double d = Distance( (int) x, (int) y, (int) x2, (int) y2 ); + double d = Distance( x, y, x2, y2 ); if( d < dmin ) { @@ -1101,7 +1109,7 @@ double GetPointToLineDistance( double a, double b, int x, int y, double* xpp, do } // find distance - return Distance( x, y, (int) xp, (int) yp ); + return Distance( x, y, xp, yp ); } @@ -1151,7 +1159,7 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int // find distance if( InRange( xp, xi, xf ) && InRange( yp, yi, yf ) ) - return Distance( x, y, (int) xp, (int) yp ); + return Distance( x, y, xp, yp ); else return min( Distance( x, y, xi, yi ), Distance( x, y, xf, yf ) ); } @@ -1177,26 +1185,6 @@ bool InRange( double x, double xi, double xf ) } -// Get distance between 2 points -// -double Distance( int x1, int y1, int x2, int y2 ) -{ - double dx = x1 - x2; - double dy = y1 - y2; - - double d = sqrt( dx * dx + dy * dy ); - - if( d > INT_MAX || d < INT_MIN ) - { - wxASSERT( 0 ); - } - - // wxASSERT( d <= INT_MAX && d >= INT_MIN ); - - return int( d ); -} - - // this finds approximate solutions // note: this works best if el2 is smaller than el1 // @@ -1368,7 +1356,7 @@ double GetArcClearance( EllipseKH* el1, EllipseKH* el2, double x2 = el2->Center.X + el2->xrad * cos( theta2 ); double y2 = el2->Center.Y + el2->yrad * sin( theta2 ); - double d = Distance( (int) x, (int) y, (int) x2, (int) y2 ); + double d = Distance( x, y, x2, y2 ); if( d < dmin ) { diff --git a/polygon/math_for_graphics.h b/polygon/math_for_graphics.h index 99271bbe6d..5119cd7973 100644 --- a/polygon/math_for_graphics.h +++ b/polygon/math_for_graphics.h @@ -71,7 +71,9 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int double GetPointToLineDistance( double a, double b, int x, int y, double * xp=NULL, double * yp=NULL ); bool InRange( double x, double xi, double xf ); -double Distance( int x1, int y1, int x2, int y2 ); + +double Distance( double x1, double y1, double x2, double y2 ); + int GetArcIntersections( EllipseKH * el1, EllipseKH * el2, double * x1=NULL, double * y1=NULL, double * x2=NULL, double * y2=NULL );