From 30e1aaec26ca5e17986dd373d181689d353235c5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 28 Mar 2013 17:30:09 +0100 Subject: [PATCH] Replacement of classes BOX2 and VECTOR2 with their extended versions include/vector2d.h: Removed old version include/math/math_util.h: rescale() for VECTOR2 include/math/vector2d.h: New version of VECTOR2 include/math/box2.h: New version of BOX2 common/drawframe.cpp: Refactorization of code, so it is compatible with new classes include/plot_common.h, pcbnew/basepcbframe.cpp: Changed header inclusion path CMakeLists.txt: Added definition to turn on WX_COMPATIBILITY for replacement classes --- CMakeLists.txt | 3 + common/drawframe.cpp | 54 ++-- include/math/box2.h | 483 ++++++++++++++++++++++++++++++ include/math/math_util.h | 97 ++++++ include/math/vector2d.h | 624 +++++++++++++++++++++++++++++++++++++++ include/plot_common.h | 2 +- include/vector2d.h | 414 -------------------------- pcbnew/basepcbframe.cpp | 2 +- 8 files changed, 1236 insertions(+), 443 deletions(-) create mode 100644 include/math/box2.h create mode 100644 include/math/math_util.h create mode 100644 include/math/vector2d.h delete mode 100644 include/vector2d.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e3c6ae22a0..cb3fd9589e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -248,6 +248,9 @@ include(Functions) #================================================ include(CheckFindPackageResult) +# Turn on wxWidgets compatibility mode for some classes +add_definitions(-DWX_COMPATIBILITY) + ####################### # Find OpenGL library # ####################### diff --git a/common/drawframe.cpp b/common/drawframe.cpp index e67d5996ff..e2b86f57c5 100644 --- a/common/drawframe.cpp +++ b/common/drawframe.cpp @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include @@ -753,7 +753,7 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) DSIZE clientSizeIU( clientSizeDU.x / scale, clientSizeDU.y / scale ); // Full drawing or "page" rectangle in internal units - DBOX pageRectIU( 0, 0, GetPageSizeIU().x, GetPageSizeIU().y ); + DBOX pageRectIU( wxPoint( 0, 0 ), wxSize( GetPageSizeIU().x, GetPageSizeIU().y ) ); // The upper left corner of the client rectangle in internal units. double xIU = aCenterPositionIU.x - clientSizeIU.x / 2.0; @@ -763,11 +763,11 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) if( screen->m_Center ) { // half page offset. - xIU += pageRectIU.width / 2.0; - yIU += pageRectIU.height / 2.0; + xIU += pageRectIU.GetWidth() / 2.0; + yIU += pageRectIU.GetHeight() / 2.0; } - DBOX clientRectIU( xIU, yIU, clientSizeIU.x, clientSizeIU.y ); + DBOX clientRectIU( wxPoint( xIU, yIU ), wxSize( clientSizeIU.x, clientSizeIU.y ) ); wxPoint centerPositionIU; #if 1 || defined( USE_PCBNEW_NANOMETRES ) @@ -782,13 +782,13 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) clientRectIU.MoveBottomTo( VIRT_MAX ); #endif - centerPositionIU.x = KiROUND( clientRectIU.x + clientRectIU.width/2 ); - centerPositionIU.y = KiROUND( clientRectIU.y + clientRectIU.height/2 ); + centerPositionIU.x = KiROUND( clientRectIU.GetX() + clientRectIU.GetWidth() / 2 ); + centerPositionIU.y = KiROUND( clientRectIU.GetY() + clientRectIU.GetHeight() / 2 ); if( screen->m_Center ) { - centerPositionIU.x -= KiROUND( pageRectIU.width / 2.0 ); - centerPositionIU.y -= KiROUND( pageRectIU.height / 2.0 ); + centerPositionIU.x -= KiROUND( pageRectIU.GetWidth() / 2.0 ); + centerPositionIU.y -= KiROUND( pageRectIU.GetHeight() / 2.0 ); } DSIZE virtualSizeIU; @@ -799,26 +799,26 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) } else { - double pageCenterX = pageRectIU.x + ( pageRectIU.width / 2 ); - double clientCenterX = clientRectIU.x + ( clientRectIU.width / 2 ); + double pageCenterX = pageRectIU.GetX() + ( pageRectIU.GetWidth() / 2 ); + double clientCenterX = clientRectIU.GetX() + ( clientRectIU.GetWidth() / 2 ); - if( clientRectIU.width > pageRectIU.width ) + if( clientRectIU.GetWidth() > pageRectIU.GetWidth() ) { if( pageCenterX > clientCenterX ) virtualSizeIU.x = ( pageCenterX - clientRectIU.GetLeft() ) * 2; else if( pageCenterX < clientCenterX ) virtualSizeIU.x = ( clientRectIU.GetRight() - pageCenterX ) * 2; else - virtualSizeIU.x = clientRectIU.width; + virtualSizeIU.x = clientRectIU.GetWidth(); } else { if( pageCenterX > clientCenterX ) - virtualSizeIU.x = pageRectIU.width + ( (pageRectIU.GetLeft() - clientRectIU.GetLeft() ) * 2 ); + virtualSizeIU.x = pageRectIU.GetWidth() + ( (pageRectIU.GetLeft() - clientRectIU.GetLeft() ) * 2 ); else if( pageCenterX < clientCenterX ) - virtualSizeIU.x = pageRectIU.width + ( (clientRectIU.GetRight() - pageRectIU.GetRight() ) * 2 ); + virtualSizeIU.x = pageRectIU.GetWidth() + ( (clientRectIU.GetRight() - pageRectIU.GetRight() ) * 2 ); else - virtualSizeIU.x = pageRectIU.width; + virtualSizeIU.x = pageRectIU.GetWidth(); } } @@ -828,28 +828,28 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) } else { - double pageCenterY = pageRectIU.y + ( pageRectIU.height / 2 ); - double clientCenterY = clientRectIU.y + ( clientRectIU.height / 2 ); + double pageCenterY = pageRectIU.GetY() + ( pageRectIU.GetHeight() / 2 ); + double clientCenterY = clientRectIU.GetY() + ( clientRectIU.GetHeight() / 2 ); - if( clientRectIU.height > pageRectIU.height ) + if( clientRectIU.GetHeight() > pageRectIU.GetHeight() ) { if( pageCenterY > clientCenterY ) virtualSizeIU.y = ( pageCenterY - clientRectIU.GetTop() ) * 2; else if( pageCenterY < clientCenterY ) virtualSizeIU.y = ( clientRectIU.GetBottom() - pageCenterY ) * 2; else - virtualSizeIU.y = clientRectIU.height; + virtualSizeIU.y = clientRectIU.GetHeight(); } else { if( pageCenterY > clientCenterY ) - virtualSizeIU.y = pageRectIU.height + + virtualSizeIU.y = pageRectIU.GetHeight() + ( ( pageRectIU.GetTop() - clientRectIU.GetTop() ) * 2 ); else if( pageCenterY < clientCenterY ) - virtualSizeIU.y = pageRectIU.height + + virtualSizeIU.y = pageRectIU.GetHeight() + ( ( clientRectIU.GetBottom() - pageRectIU.GetBottom() ) * 2 ); else - virtualSizeIU.y = pageRectIU.height; + virtualSizeIU.y = pageRectIU.GetHeight(); } } @@ -866,8 +866,8 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) } else { - screen->m_DrawOrg.x = -KiROUND( ( virtualSizeIU.x - pageRectIU.width ) / 2.0 ); - screen->m_DrawOrg.y = -KiROUND( ( virtualSizeIU.y - pageRectIU.height ) / 2.0 ); + screen->m_DrawOrg.x = -KiROUND( ( virtualSizeIU.x - pageRectIU.GetWidth() ) / 2.0 ); + screen->m_DrawOrg.y = -KiROUND( ( virtualSizeIU.y - pageRectIU.GetHeight() ) / 2.0 ); } /* Always set scrollbar pixels per unit to 1 unless you want the zoom @@ -886,8 +886,8 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) // center position at the center of client rectangle. screen->SetScrollCenterPosition( centerPositionIU ); - double posX = centerPositionIU.x - clientRectIU.width /2.0 - screen->m_DrawOrg.x; - double posY = centerPositionIU.y - clientRectIU.height/2.0 - screen->m_DrawOrg.y; + double posX = centerPositionIU.x - clientRectIU.GetWidth() / 2.0 - screen->m_DrawOrg.x; + double posY = centerPositionIU.y - clientRectIU.GetHeight() / 2.0 - screen->m_DrawOrg.y; // Convert scroll bar position to device units. posX = KiROUND( posX * scale ); diff --git a/include/math/box2.h b/include/math/box2.h new file mode 100644 index 0000000000..470fa6ac88 --- /dev/null +++ b/include/math/box2.h @@ -0,0 +1,483 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com + * Copyright (C) 2008-2011 Wayne Stambaugh + * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2013 CERN + * + * 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 __BOX2_H +#define __BOX2_H + +#include + + +template +class BOX2_TRAITS +{ +}; + +template <> +class BOX2_TRAITS +{ +public: + enum { + c_max_size = INT_MAX - 1, + c_min_coord_value = INT_MIN / 2 + 1 + }; +}; + +/** + * Class BOX2 + * handles a 2-D bounding box, built on top of an origin point + * and size vector, both of templated class Vec + */ +template +class BOX2 +{ +private: + Vec m_Pos; // Rectangle Origin + Vec m_Size; // Rectangle Size + +public: + typedef typename Vec::coord_type coord_type; + typedef typename Vec::extended_type ecoord_type; + + BOX2() { }; + + BOX2( const Vec& aPos, const Vec& aSize ) : + m_Pos( aPos ), + m_Size( aSize ) + { } + + void SetMaximum() + { + m_Pos.x = m_Pos.y = BOX2_TRAITS().c_min_coord_value; + m_Size.x = m_Size.y = BOX2_TRAITS().c_max_size; + } + + Vec Centre() const + { + return Vec( m_Pos.x + ( m_Size.x / 2 ), + m_Pos.y + ( m_Size.y / 2 ) ); + } + + /** + * @brief Compute the bounding box from a given list of points. + * + * @param aPointList is the list points of the object. + */ + template + void Compute( const Container& aPointList ) + { + Vec vmin, vmax; + typename Container::const_iterator i; + + if( !aPointList.size() ) + return; + + vmin = vmax = aPointList[0]; + + for( i = aPointList.begin(); i != aPointList.end(); ++i ) + { + Vec p( *i ); + vmin.x = std::min( vmin.x, p.x ); + vmin.y = std::min( vmin.y, p.y ); + vmax.x = std::max( vmax.x, p.x ); + vmax.y = std::max( vmax.y, p.y ); + } + + SetOrigin( vmin ); + SetSize( vmax - vmin ); + } + + /** + * Function Move + * moves the rectangle by the \a aMoveVector. + * @param aMoveVector A point that is the value to move this rectangle + */ + void Move( const Vec& aMoveVector ) + { + m_Pos += aMoveVector; + } + + /** + * Function Normalize + * ensures that the height ant width are positive. + */ + BOX2& Normalize() + { + if( m_Size.y < 0 ) + { + m_Size.y = -m_Size.y; + m_Pos.y -= m_Size.y; + } + + if( m_Size.x < 0 ) + { + m_Size.x = -m_Size.x; + m_Pos.x -= m_Size.x; + } + + return *this; + } + + /** + * Function Contains + * @param aPoint = the point to test + * @return true if aPoint is inside the boundary box. A point on a edge is seen as inside + */ + bool Contains( const Vec& aPoint ) const + { + Vec rel_pos = aPoint - m_Pos; + Vec size = m_Size; + + if( size.x < 0 ) + { + size.x = -size.x; + rel_pos.x += size.x; + } + + if( size.y < 0 ) + { + size.y = -size.y; + rel_pos.y += size.y; + } + + return (rel_pos.x >= 0) && (rel_pos.y >= 0) && ( rel_pos.y <= size.y) && ( rel_pos.x <= size.x); + } + + /** + * Function Contains + * @param x = the x coordinate of the point to test + * @param y = the x coordinate of the point to test + * @return true if point is inside the boundary box. A point on a edge is seen as inside + */ + bool Contains( coord_type x, coord_type y ) const { return Contains( Vec( x, y ) ); } + + /** + * Function Contains + * @param aRect = the BOX2 to test + * @return true if aRect is Contained. A common edge is seen as contained + */ + bool Contains( const BOX2& aRect ) const + { + return Contains( aRect.GetOrigin() ) && Contains( aRect.GetEnd() ); + } + + const Vec& GetSize() const { return m_Size; } + coord_type GetX() const { return m_Pos.x; } + coord_type GetY() const { return m_Pos.y; } + + const Vec& GetOrigin() const { return m_Pos; } + const Vec& GetPosition() const { return m_Pos; } + const Vec GetEnd() const { return Vec( GetRight(), GetBottom() ); } + + coord_type GetWidth() const { return m_Size.x; } + coord_type GetHeight() const { return m_Size.y; } + coord_type GetRight() const { return m_Pos.x + m_Size.x; } + coord_type GetBottom() const { return m_Pos.y + m_Size.y; } + + // Compatibility aliases + coord_type GetLeft() const { return GetX(); } + coord_type GetTop() const { return GetY(); } + void MoveTopTo( coord_type aTop ) { m_Pos.y = aTop; } + void MoveBottomTo( coord_type aBottom ) { m_Size.y = aBottom - m_Pos.y; } + void MoveLeftTo( coord_type aLeft ) { m_Pos.x = aLeft; } + void MoveRightTo( coord_type aRight ) { m_Size.x = aRight - m_Pos.x; } + + void SetOrigin( const Vec& pos ) { m_Pos = pos; } + void SetOrigin( coord_type x, coord_type y ) { m_Pos.x = x; m_Pos.y = y; } + void SetSize( const Vec& size ) { m_Size = size; } + void SetSize( coord_type w, coord_type h ) { m_Size.x = w; m_Size.y = h; } + void Offset( coord_type dx, coord_type dy ) { m_Pos.x += dx; m_Pos.y += dy; } + void Offset( const Vec& offset ) + { + m_Pos.x += offset.x; m_Pos.y += + offset.y; + } + + void SetX( coord_type val ) { m_Pos.x = val; } + void SetY( coord_type val ) { m_Pos.y = val; } + void SetWidth( coord_type val ) { m_Size.x = val; } + void SetHeight( coord_type val ) { m_Size.y = val; } + void SetEnd( coord_type x, coord_type y ) { SetEnd( Vec( x, y ) ); } + void SetEnd( const Vec& pos ) + { + m_Size.x = pos.x - m_Pos.x; m_Size.y = pos.y - m_Pos.y; + } + + /** + * Function Intersects + * @return bool - true if the argument rectangle intersects this rectangle. + * (i.e. if the 2 rectangles have at least a common point) + */ + bool Intersects( const BOX2& aRect ) const + { + // this logic taken from wxWidgets' geometry.cpp file: + bool rc; + + BOX2 me( *this ); + BOX2 rect( aRect ); + me.Normalize(); // ensure size is >= 0 + rect.Normalize(); // ensure size is >= 0 + + // calculate the left common area coordinate: + int left = std::max( me.m_Pos.x, rect.m_Pos.x ); + // calculate the right common area coordinate: + int right = std::min( me.m_Pos.x + me.m_Size.x, rect.m_Pos.x + rect.m_Size.x ); + // calculate the upper common area coordinate: + int top = std::max( me.m_Pos.y, aRect.m_Pos.y ); + // calculate the lower common area coordinate: + int bottom = std::min( me.m_Pos.y + me.m_Size.y, rect.m_Pos.y + rect.m_Size.y ); + + // if a common area exists, it must have a positive (null accepted) size + if( left <= right && top <= bottom ) + rc = true; + else + rc = false; + + return rc; + } + + const std::string Format() const + { + std::stringstream ss; + + ss << "( box corner " << m_Pos.Format() << " w " << m_Size.x << " h " << m_Size.y << " )"; + + return ss.str(); + } + + /** + * Function Inflate + * inflates the rectangle horizontally by \a dx and vertically by \a dy. If \a dx + * and/or \a dy is negative the rectangle is deflated. + */ + BOX2& Inflate( coord_type dx, coord_type dy ) + { + if( m_Size.x >= 0 ) + { + if( m_Size.x < -2 * dx ) + { + // Don't allow deflate to eat more width than we have, + m_Pos.x += m_Size.x / 2; + m_Size.x = 0; + } + else + { + // The inflate is valid. + m_Pos.x -= dx; + m_Size.x += 2 * dx; + } + } + else // size.x < 0: + { + if( m_Size.x > -2 * dx ) + { + // Don't allow deflate to eat more width than we have, + m_Pos.x -= m_Size.x / 2; + m_Size.x = 0; + } + else + { + // The inflate is valid. + m_Pos.x += dx; + m_Size.x -= 2 * dx; // m_Size.x <0: inflate when dx > 0 + } + } + + if( m_Size.y >= 0 ) + { + if( m_Size.y < -2 * dy ) + { + // Don't allow deflate to eat more height than we have, + m_Pos.y += m_Size.y / 2; + m_Size.y = 0; + } + else + { + // The inflate is valid. + m_Pos.y -= dy; + m_Size.y += 2 * dy; + } + } + else // size.y < 0: + { + if( m_Size.y > 2 * dy ) + { + // Don't allow deflate to eat more height than we have, + m_Pos.y -= m_Size.y / 2; + m_Size.y = 0; + } + else + { + // The inflate is valid. + m_Pos.y += dy; + m_Size.y -= 2 * dy; // m_Size.y <0: inflate when dy > 0 + } + } + + return *this; + } + + /** + * Function Inflate + * inflates the rectangle horizontally and vertically by \a aDelta. If \a aDelta + * is negative the rectangle is deflated. + */ + BOX2& Inflate( int aDelta ) + { + Inflate( aDelta, aDelta ); + return *this; + } + + /** + * Function Merge + * modifies the position and size of the rectangle in order to contain \a aRect. It is + * mainly used to calculate bounding boxes. + * @param aRect The rectangle to merge with this rectangle. + */ + BOX2& Merge( const BOX2& aRect ) + { + Normalize(); // ensure width and height >= 0 + BOX2 rect = aRect; + rect.Normalize(); // ensure width and height >= 0 + Vec end = GetEnd(); + Vec rect_end = rect.GetEnd(); + + // Change origin and size in order to contain the given rect + m_Pos.x = std::min( m_Pos.x, rect.m_Pos.x ); + m_Pos.y = std::min( m_Pos.y, rect.m_Pos.y ); + end.x = std::max( end.x, rect_end.x ); + end.y = std::max( end.y, rect_end.y ); + SetEnd( end ); + return *this; + } + + /** + * Function Merge + * modifies the position and size of the rectangle in order to contain the given point. + * @param aPoint The point to merge with the rectangle. + */ + BOX2& Merge( const Vec& aPoint ) + { + Normalize(); // ensure width and height >= 0 + + Vec end = GetEnd(); + // Change origin and size in order to contain the given rect + m_Pos.x = std::min( m_Pos.x, aPoint.x ); + m_Pos.y = std::min( m_Pos.y, aPoint.y ); + end.x = std::max( end.x, aPoint.x ); + end.y = std::max( end.y, aPoint.y ); + SetEnd( end ); + return *this; + } + + /** + * Function GetArea + * returns the area of the rectangle. + * @return The area of the rectangle. + */ + ecoord_type GetArea() const + { + return (ecoord_type) GetWidth() * (ecoord_type) GetHeight(); + } + + /** + * Function GetArea + * returns the length of the diagonal of the rectangle. + * @return The area of the diagonal. + */ + ecoord_type Diagonal() const + { + return m_Size.EuclideanNorm(); + } + + ecoord_type SquaredDistance( const Vec& aP ) const + { + ecoord_type x2 = m_Pos.x + m_Size.x; + ecoord_type y2 = m_Pos.y + m_Size.y; + ecoord_type xdiff = std::max( aP.x < m_Pos.x ? m_Pos.x - aP.x : m_Pos.x - x2, 0 ); + ecoord_type ydiff = std::max( aP.y < m_Pos.y ? m_Pos.y - aP.y : m_Pos.y - y2, 0 ); + return xdiff * xdiff + ydiff * ydiff; + } + + ecoord_type Distance( const Vec& aP ) const + { + return sqrt( SquaredDistance( aP ) ); + } + + /** + * Function SquaredDistance + * returns the square of the minimum distance between self and box aBox + * @param aBox: the other box + * @return The distance, squared + */ + ecoord_type SquaredDistance( const BOX2& aBox ) const + { + ecoord_type s = 0; + + if( aBox.m_Pos.x + aBox.m_Size.x < m_Pos.x ) + { + ecoord_type d = aBox.m_Pos.x + aBox.m_Size.x - m_Pos.x; + s += d * d; + } + else if( aBox.m_Pos.x > m_Pos.x + m_Size.x ) + { + ecoord_type d = aBox.m_Pos.x - m_Size.x - m_Pos.x; + s += d * d; + } + + if( aBox.m_Pos.y + aBox.m_Size.y < m_Pos.y ) + { + ecoord_type d = aBox.m_Pos.y + aBox.m_Size.y - m_Pos.y; + s += d * d; + } + else if( aBox.m_Pos.y > m_Pos.y + m_Size.y ) + { + ecoord_type d = aBox.m_Pos.y - m_Size.y - m_Pos.y; + s += d * d; + } + + return s; + } + + /** + * Function Distance + * returns the minimum distance between self and box aBox + * @param aBox: the other box + * @return The distance + */ + ecoord_type Distance( const BOX2& aBox ) const + { + return sqrt( SquaredDistance( aBox ) ); + } +}; + +/* Default specializations */ +typedef BOX2 BOX2I; +typedef BOX2 BOX2D; + +// FIXME should be removed to avoid multiple typedefs for the same type +typedef BOX2D DBOX; + +#endif diff --git a/include/math/math_util.h b/include/math/math_util.h new file mode 100644 index 0000000000..3a4049ae29 --- /dev/null +++ b/include/math/math_util.h @@ -0,0 +1,97 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (c) 2005 Michael Niedermayer + * Copyright (C) 2013 Tomasz Wlostowski + * + * 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 __MATH_UTIL_H +#define __MATH_UTIL_H + +#include +#include +#include + +/** + * Function rescale() + * + * Scales a number (value) by rational (numerator/denominator). Numerator must be <= denominator. + */ + +template static T rescale( T numerator, T value, T denominator ) +{ + return numerator * value / denominator; +} + + +// explicit specializations for integer types, taking care of overflow. +template<> int rescale( int numerator, int value, int denominator ) +{ + return (int) ( (int64_t) numerator * (int64_t) value / (int64_t) denominator ); +} + +template<> int64_t rescale( int64_t numerator, int64_t value, int64_t denominator ) +{ + uint64_t r = 0; + int64_t sign = ( ( numerator < 0) ? -1 : 1 ) * ( denominator < 0 ? - 1: 1 ) * (value < 0 ? - 1 : 1); + + uint64_t a = abs( numerator ); + uint64_t b = abs( value ); + uint64_t c = abs( denominator ); + + r = c / 2; + + if( b <= INT_MAX && c <= INT_MAX ) + { + if( a <= INT_MAX ) + return sign * ( (a * b + r ) / c ); + else + return sign * (a / c * b + (a % c * b + r) / c); + } else { + uint64_t a0 = a & 0xFFFFFFFF; + uint64_t a1 = a >> 32; + uint64_t b0 = b & 0xFFFFFFFF; + uint64_t b1 = b >> 32; + uint64_t t1 = a0 * b1 + a1 * b0; + uint64_t t1a = t1 << 32; + int i; + + a0 = a0 * b0 + t1a; + a1 = a1 * b1 + (t1 >> 32) + (a0 < t1a); + a0 += r; + a1 += a0 < r; + + for( i = 63; i >= 0; i-- ) + { + a1 += a1 + ( (a0 >> i) & 1 ); + t1 += t1; + + if( c <= a1 ) + { + a1 -= c; + t1++; + } + } + + return t1 * sign; + } +}; + +#endif // __MATH_UTIL_H diff --git a/include/math/vector2d.h b/include/math/vector2d.h new file mode 100644 index 0000000000..e8f4172f9f --- /dev/null +++ b/include/math/vector2d.h @@ -0,0 +1,624 @@ +/* + * 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. + * Copyright (C) 2013 Tomasz Wlostowski + * + * 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 +#include + +#include + +#ifdef WX_COMPATIBILITY + #include +#endif + +/** + * Class VECTOR2_TRAITS + * traits class for VECTOR2. + */ +template +struct VECTOR2_TRAITS +{ + ///> extended range/precision types used by operations involving multiple + ///> multiplications to prevent overflow. + typedef T extended_type; +}; + +template <> +struct VECTOR2_TRAITS +{ + typedef int64_t extended_type; +}; + +// Forward declarations for template friends +template +class VECTOR2; +template +std::ostream& operator<<( std::ostream& stream, const VECTOR2& vector ); + +/** + * Class VECTOR2 + * defines a general 2D-vector/point. + * + * This class uses templates to be universal. Several operators are provided to help easy implementing + * of linear algebra equations. + * + */ +template +class VECTOR2 : public VECTOR2_TRAITS +{ +public: + typedef typename VECTOR2_TRAITS::extended_type extended_type; + typedef T coord_type; + + T x, y; + + // Constructors + + /// Construct a 2D-vector with x, y = 0 + VECTOR2(); + +#ifdef WX_COMPATIBILITY + /// Constructor with a wxPoint as argument + VECTOR2( const wxPoint& aPoint ); + + /// Constructor with a wxSize as argument + VECTOR2( const wxSize& aSize ); +#endif + + /// Construct a vector with given components x, y + VECTOR2( T x, T y ); + + /// Initializes a vector from another specialization. Beware of rouding + /// issues. + template + VECTOR2( const VECTOR2& aVec ) + { + x = (T) aVec.x; + y = (T) aVec.y; + } + + /// Casts a vector to another specialized subclass. Beware of rouding + /// issues. + template + VECTOR2 operator()() const + { + return VECTOR2( (CastedType) x, (CastedType) 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() const; + + /** + * Function Perpendicular + * computes the perpendicular vector + * @return Perpendicular vector + */ + VECTOR2 Perpendicular() const; + + /** + * Function LineProjection + * computes the perpendicular projection point of self on a line + * going through aA and aB points. + * @return Projected point + */ + VECTOR2 LineProjection( const VECTOR2& aA, const VECTOR2& aB ) const; + + /** + * Function LineSide + * determines on which side of directed line passing via points aEnd + * and a start aStart we are. + * @return: < 0: left, 0 : on the line, > 0 : right + */ + int LineSide( const VECTOR2& aStart, const VECTOR2& aEnd ) const; + + /** + * Function LineDistance + * returns the closest Euclidean distance to a line defined by points + * aStart and aEnd. + * @param aDetermineSide: when true, the sign of the returned value indicates + * the side of the line at which we are (negative = left) + * @return the distance + */ + T LineDistance( const VECTOR2& aStart, const VECTOR2& aEnd, bool aDetermineSide = false ) const; + + /** + * Function ClosestSegmentPoint + * returns the closest point on a line segment defined by aStart and aEnd. + * @return: our point + */ + VECTOR2 ClosestSegmentPoint( const VECTOR2& aStart, const VECTOR2& aEnd ) const; + + /** + * Function Resize + * returns a vector of the same direction, but length specified in aNewLength + * @param aNewLength: length of the rescaled vector + * @return rescaled vector + */ + VECTOR2 Resize( T aNewLength ) const; + + /** + * Function Angle + * computes the angle of the vector + * @return vector angle, in radians + */ + double Angle() const; + + /** + * Function Rotate + * rotates the vector by a given angle + * @param aAngle rotation angle in radians + * @return rotated vector + */ + VECTOR2 Rotate( double aAngle ) const; + + /** + * Function Format + * returns the vector formatted as a string + * @return the formatted string + */ + const std::string Format() const; + + /** + * Function Cross() + * computes cross product of self with aVector + */ + extended_type Cross( const VECTOR2& aVector ) const; + + /** + * Function Dot() + * computes dot product of self with aVector + */ + extended_type Dot( const VECTOR2& aVector ) const; + + + // Operators + + /// Assignment operator + VECTOR2& operator=( const VECTOR2& aVector ); + + /// Vector addition operator + VECTOR2 operator+( const VECTOR2& aVector ) const; + + /// Compound assignment operator + VECTOR2& operator+=( const VECTOR2& aVector ); + + /// Vector subtraction operator + VECTOR2 operator-( const VECTOR2& aVector ) const; + + /// Compound assignment operator + VECTOR2& operator-=( const VECTOR2& aVector ); + + /// Negate Vector operator + VECTOR2 operator-(); + + /// Scalar product operator + extended_type operator*( const VECTOR2& aVector ) const; + + /// Multiplication with a factor + VECTOR2 operator*( const T& aFactor ) const; + + /// Division with a factor + VECTOR2 operator/( const T& aFactor ) const; + + /// Equality operator + const bool operator==( const VECTOR2& aVector ) const; + + /// Not equality operator + const bool operator!=( const VECTOR2& aVector ) const; + + /// Smaller than operator + bool operator<( const VECTOR2& aVector ) const; + bool operator<=( const VECTOR2& aVector ) const; + + /// Greater than operator + bool operator>( const VECTOR2& aVector ) const; + bool operator>=( const VECTOR2& aVector ) const; + + friend std::ostream & operator<< ( std::ostream & stream, const VECTOR2 &vector ); +}; + + +// ---------------------- +// --- Implementation --- +// ---------------------- + +template +VECTOR2::VECTOR2() +{ + x = y = 0.0; +} + + +#ifdef WX_COMPATIBILITY +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 ); +} +#endif + +template +VECTOR2::VECTOR2( T aX, T aY ) +{ + x = aX; + y = aY; +} + + +template +T VECTOR2::EuclideanNorm() const +{ + return sqrt( (extended_type) x * x + (extended_type) y * y ); +} + + +template +double VECTOR2::Angle() const +{ + return atan2( y, x ); +} + + +template +VECTOR2 VECTOR2::Perpendicular() const +{ + VECTOR2 perpendicular( -y, x ); + return perpendicular; +} + + +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 +int VECTOR2::LineSide( const VECTOR2& aStart, const VECTOR2& aEnd ) const +{ + VECTOR2 d = aEnd - aStart; + VECTOR2 ap = *this - aStart; + + extended_type det = (extended_type) d.x * (extended_type) ap.y + - (extended_type) d.y * (extended_type) ap.x; + + return det < 0 ? -1 : (det > 0 ? 1 : 0); +} + + +template +VECTOR2 VECTOR2::LineProjection( const VECTOR2& aA, const VECTOR2& aB ) const +{ + const VECTOR2 d = aB - aA; + extended_type det = (extended_type) d.x * d.x + d.y * (extended_type) d.y; + extended_type dxdy = (extended_type) d.x * d.y; + extended_type qx = + ( (extended_type) aA.x * d.y * d.y + (extended_type) d.x * d.x * x - dxdy * + (aA.y - y) ) / det; + extended_type qy = + ( (extended_type) aA.y * d.x * d.x + (extended_type) d.y * d.y * y - dxdy * + (aA.x - x) ) / det; + + return VECTOR2 ( (T) qx, (T) qy ); +} + + +template +T VECTOR2::LineDistance( const VECTOR2& aStart, const VECTOR2& aEnd, bool aDetermineSide ) const +{ + extended_type a = aStart.y - aEnd.y; + extended_type b = aEnd.x - aStart.x; + extended_type c = -a * aStart.x - b * aStart.y; + + T dist = ( a * x + b * y + c ) / sqrt( a * a + b * b ); + return aDetermineSide ? dist : abs(dist); +} + + +template +VECTOR2 VECTOR2::ClosestSegmentPoint( const VECTOR2& aStart, const VECTOR2& aEnd ) const +{ + VECTOR2 d = (aEnd - aStart); + extended_type l_squared = (extended_type) d.x * d.x + (extended_type) d.y * d.y; + + + if( l_squared == 0 ) + { + return aStart; + } + + extended_type t = + (extended_type) (x - aStart.x) * (extended_type) d.x + + (extended_type) (y - aStart.y) * (extended_type) d.y; + + if( t < 0 ) + { + return aStart; + } + else if( t > l_squared ) + { + return aEnd; + } + + double xp = (double) t * (double) d.x / (double) l_squared; + double yp = (double) t * (double) d.y / (double) l_squared; + + /*VECTOR2 proj = aStart + VECTOR2 ( ( t * (extended_type) d.x / l_squared ), + ( t * ( extended_type) d.y / l_squared ) );*/ + + VECTOR2 proj = aStart + VECTOR2 ( (T)xp, (T) yp ); + + return proj; +} + + +template +VECTOR2 VECTOR2::Rotate( double aAngle ) const +{ + double sa = sin( aAngle ); + double ca = cos( aAngle ); + + return VECTOR2 ( T( (double) x * ca - (double) y * sa ), + T( (double) x * sa + (double) y * ca ) ); +} + + +template +VECTOR2 VECTOR2::Resize( T aNewLength ) const +{ + if( x == 0 && y == 0 ) + return VECTOR2 ( 0, 0 ); + + T l = this->EuclideanNorm(); + + return VECTOR2 ( + rescale( aNewLength, x, l ), + rescale( aNewLength, y, l ) ); +} + + +template +const std::string VECTOR2::Format() const +{ + std::stringstream ss; + + ss << "( xy " << x << " " << y << " )"; + + return ss.str(); +} + + +template +VECTOR2 VECTOR2::operator+( const VECTOR2& aVector ) const +{ + return VECTOR2 ( x + aVector.x, y + aVector.y ); +} + + +template +VECTOR2 VECTOR2::operator-( const VECTOR2& aVector ) const +{ + return VECTOR2 ( x - aVector.x, y - aVector.y ); +} + + +template +VECTOR2 VECTOR2::operator-() +{ + return VECTOR2 ( -x, -y ); +} + + +template +typename VECTOR2::extended_type VECTOR2::operator*( const VECTOR2& aVector ) const +{ + return aVector.x * x + aVector.y * y; +} + + +template +VECTOR2 VECTOR2::operator*( const T& aFactor ) const +{ + VECTOR2 vector( x * aFactor, y * aFactor ); + return vector; +} + + +template +VECTOR2 VECTOR2::operator/( const T& aFactor ) const +{ + 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 +typename VECTOR2::extended_type VECTOR2::Cross( const VECTOR2& aVector ) const +{ + return (extended_type) x * (extended_type) aVector.y - + (extended_type) y * (extended_type) aVector.x; +} + + +template +typename VECTOR2::extended_type VECTOR2::Dot( const VECTOR2& aVector ) const +{ + return (extended_type) x * (extended_type) aVector.x + + (extended_type) y * (extended_type) aVector.y; +} + + +template +bool VECTOR2::operator<( const VECTOR2& aVector ) const +{ + return ( *this * *this ) < ( aVector * aVector ); +} + + +template +bool VECTOR2::operator<=( const VECTOR2& aVector ) const +{ + return ( *this * *this ) <= ( aVector * aVector ); +} + + +template +bool VECTOR2::operator>( const VECTOR2& aVector ) const +{ + return ( *this * *this ) > ( aVector * aVector ); +} + + +template +bool VECTOR2::operator>=( const VECTOR2& aVector ) const +{ + return ( *this * *this ) >= ( aVector * aVector ); +} + + +template +bool const VECTOR2::operator==( VECTOR2 const& aVector ) const +{ + return ( aVector.x == x ) && ( aVector.y == y ); +} + + +template +bool const VECTOR2::operator!=( VECTOR2 const& aVector ) const +{ + return ( aVector.x != x ) || ( aVector.y != y ); +} + + +template +const VECTOR2 LexicographicalMax( const VECTOR2& aA, const VECTOR2& aB ) +{ + if( aA.x > aB.x ) + return aA; + else if( aA.x == aB.x && aA.y > aB.y ) + return aA; + + return aB; +} + + +template +const VECTOR2 LexicographicalMin( const VECTOR2& aA, const VECTOR2& aB ) +{ + if( aA.x < aB.x ) + return aA; + else if( aA.x == aB.x && aA.y < aB.y ) + return aA; + + return aB; +} + + +template +const int LexicographicalCompare( const VECTOR2& aA, const VECTOR2& aB ) +{ + if( aA.x < aB.x ) + return -1; + else if( aA.x > aB.x ) + return 1; + else // aA.x == aB.x + { + if( aA.y < aB.y ) + return -1; + else if( aA.y > aB.y ) + return 1; + else + return 0; + } +} + + +template +std::ostream& operator<<( std::ostream& aStream, const VECTOR2& aVector ) +{ + aStream << "[ " << aVector.x << " | " << aVector.y << " ]"; + return aStream; +} + +/* Default specializations */ +typedef VECTOR2 VECTOR2D; +typedef VECTOR2 VECTOR2I; + +/* Compatibility typedefs */ +// FIXME should be removed to avoid multiple typedefs for the same type +typedef VECTOR2 DPOINT; +typedef DPOINT DSIZE; + +#endif // VECTOR2D_H_ diff --git a/include/plot_common.h b/include/plot_common.h index 437c676d8d..66005c1fe1 100644 --- a/include/plot_common.h +++ b/include/plot_common.h @@ -9,7 +9,7 @@ #define PLOT_COMMON_H_ #include -#include +#include #include #include // PAGE_INFO #include // FILL_T diff --git a/include/vector2d.h b/include/vector2d.h deleted file mode 100644 index 3968984df1..0000000000 --- a/include/vector2d.h +++ /dev/null @@ -1,414 +0,0 @@ -/* - * 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; - - -/** - * 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(); - - /// 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() -{ - 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& aVector ) -{ - // VECTOR2 vector( aVector ); - // need a specialization for T = int because of overflow: - // return (double( x ) * x + double( y ) * y) < (double( o.x ) * o.x + double( o.y ) * y); - return ( *this * *this ) < ( aVector * aVector ); -} - -template bool VECTOR2::operator<=( const VECTOR2& aVector ) -{ - return ( *this * *this ) <= ( aVector * aVector ); -} - -template bool VECTOR2::operator>( const VECTOR2& aVector ) -{ - return ( *this * *this ) > ( aVector * aVector ); -} - -template bool VECTOR2::operator>=( const VECTOR2& aVector ) -{ - return ( *this * *this ) >= ( aVector * aVector ); -} - -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 BOX2 - * is a description of a rectangle in a cartesion coordinate system. - */ -template class BOX2 -{ -public: - BOX2() : x(0), y(0), width(0), height(0) {} - - BOX2( T aX, T aY, T aWidth, T aHeight ): - x( aX ), y( aY ), width( aWidth ), height( aHeight ) - {} - - BOX2( const VECTOR2& aPos, const VECTOR2& aSize ) : - x( aPos.x ), y( aPos.y ), width( aSize.x ), height( aSize.y ) - {} - - BOX2( const wxPoint& aPos, const wxSize& aSize ) : - x( aPos.x ), y( aPos.y ), width( aSize.x ), height( aSize.y ) - {} - - /* - BOX2( const EDA_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); } - - /** - * Function Normalize - * ensures that the height ant width are positive. - */ - void Normalize() - { - if( height < 0 ) - { - height = -height; - y -= height; - } - - if( width < 0 ) - { - width = -width; - x -= width; - } - } - - T x, y, width, height; -}; - - -typedef VECTOR2 DPOINT; -typedef DPOINT DSIZE; - -typedef BOX2 DBOX; - - -#endif // VECTOR2D_H_ diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index c35d951f86..b68f1cc42a 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -45,7 +45,7 @@ #include #include -#include +#include // Configuration entry names.