Fix bug in PolyLine.cpp, Fix bug in DRC calculations (see changelog).
Cvpcb and Gerbview: move dialog files in dialogs/. Eeschema: fix bug in libedit: crashes with import a symbol.
This commit is contained in:
commit
787ca931f1
|
@ -4,6 +4,17 @@ KiCad ChangeLog 2010
|
||||||
Please add newer entries at the top, list the date and your name with
|
Please add newer entries at the top, list the date and your name with
|
||||||
email address.
|
email address.
|
||||||
|
|
||||||
|
2010-oct-15, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||||
|
================================================================================
|
||||||
|
PolyLine.cpp:
|
||||||
|
remove unused method CPolyLine::TestPointInsideContour() which was a duplicate of
|
||||||
|
TestPointInsidePolygon().
|
||||||
|
In CPolyLine::TestPointInside(); replace curious algo (which have a problem)
|
||||||
|
to test a point inside a polygon by TestPointInsidePolygon()
|
||||||
|
++Pcbnew:
|
||||||
|
fix a bug in Drc and clearance calculations when using a dummy pad
|
||||||
|
( in zones calcualtions and to test holes ot tracks and holes to pads DRC).
|
||||||
|
|
||||||
2010-oct-26 UPDATE Wayne Stambaugh <stambaughw@verizon.net>
|
2010-oct-26 UPDATE Wayne Stambaugh <stambaughw@verizon.net>
|
||||||
================================================================================
|
================================================================================
|
||||||
++EESchema
|
++EESchema
|
||||||
|
|
|
@ -4,6 +4,7 @@ add_definitions(-DCVPCB)
|
||||||
# Includes
|
# Includes
|
||||||
###
|
###
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/dialogs
|
||||||
${Boost_INCLUDE_DIR}
|
${Boost_INCLUDE_DIR}
|
||||||
../3d-viewer
|
../3d-viewer
|
||||||
../pcbnew
|
../pcbnew
|
||||||
|
@ -13,6 +14,13 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
###
|
###
|
||||||
# Sources
|
# Sources
|
||||||
###
|
###
|
||||||
|
set(CVPCB_DIALOGS
|
||||||
|
dialogs/dialog_cvpcb_config.cpp
|
||||||
|
dialogs/dialog_cvpcb_config_fbp.cpp
|
||||||
|
dialogs/dialog_display_options.cpp
|
||||||
|
dialogs/dialog_display_options_base.cpp
|
||||||
|
)
|
||||||
|
|
||||||
set(CVPCB_SRCS
|
set(CVPCB_SRCS
|
||||||
autosel.cpp
|
autosel.cpp
|
||||||
cfg.cpp
|
cfg.cpp
|
||||||
|
@ -22,10 +30,6 @@ set(CVPCB_SRCS
|
||||||
class_footprints_listbox.cpp
|
class_footprints_listbox.cpp
|
||||||
cvframe.cpp
|
cvframe.cpp
|
||||||
cvpcb.cpp
|
cvpcb.cpp
|
||||||
dialog_cvpcb_config.cpp
|
|
||||||
dialog_cvpcb_config_fbp.cpp
|
|
||||||
dialog_display_options.cpp
|
|
||||||
dialog_display_options_base.cpp
|
|
||||||
dummy_functions.cpp
|
dummy_functions.cpp
|
||||||
genequiv.cpp
|
genequiv.cpp
|
||||||
init.cpp
|
init.cpp
|
||||||
|
@ -69,6 +73,7 @@ endif(APPLE)
|
||||||
###
|
###
|
||||||
add_executable(cvpcb WIN32 MACOSX_BUNDLE
|
add_executable(cvpcb WIN32 MACOSX_BUNDLE
|
||||||
${CVPCB_SRCS}
|
${CVPCB_SRCS}
|
||||||
|
${CVPCB_DIALOGS}
|
||||||
${CVPCB_RESOURCES})
|
${CVPCB_RESOURCES})
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
add_definitions(-DEESCHEMA)
|
add_definitions(-DEESCHEMA)
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/dialogs
|
||||||
${CMAKE_SOURCE_DIR}/common
|
${CMAKE_SOURCE_DIR}/common
|
||||||
${CMAKE_SOURCE_DIR}/dialogs
|
|
||||||
${Boost_INCLUDE_DIR}
|
${Boost_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ void WinEDA_LibeditFrame::LoadOneSymbol( void )
|
||||||
wxMessageBox( msg, _( "Warning" ), wxOK | wxICON_EXCLAMATION, this );
|
wxMessageBox( msg, _( "Warning" ), wxOK | wxICON_EXCLAMATION, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
Component = (LIB_COMPONENT*) Lib->GetFirstEntry();
|
Component = Lib->GetFirstEntry()->GetComponent();
|
||||||
LIB_DRAW_ITEM_LIST& drawList = Component->GetDrawItemList();
|
LIB_DRAW_ITEM_LIST& drawList = Component->GetDrawItemList();
|
||||||
|
|
||||||
BOOST_FOREACH( LIB_DRAW_ITEM& item, drawList )
|
BOOST_FOREACH( LIB_DRAW_ITEM& item, drawList )
|
||||||
|
|
|
@ -13,6 +13,14 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
###
|
###
|
||||||
# Sources
|
# Sources
|
||||||
###
|
###
|
||||||
|
set(DIALOGS_SRCS
|
||||||
|
dialogs/gerbview_dialog_display_options_frame_base.cpp
|
||||||
|
dialogs/gerbview_dialog_display_options_frame.cpp
|
||||||
|
dialogs/dialog_gerber_config.cpp
|
||||||
|
dialogs/dialog_print_using_printer.cpp
|
||||||
|
dialogs/dialog_print_using_printer_base.cpp
|
||||||
|
)
|
||||||
|
|
||||||
set(GERBVIEW_SRCS
|
set(GERBVIEW_SRCS
|
||||||
block.cpp
|
block.cpp
|
||||||
class_aperture_macro.cpp
|
class_aperture_macro.cpp
|
||||||
|
@ -22,9 +30,6 @@ set(GERBVIEW_SRCS
|
||||||
controle.cpp
|
controle.cpp
|
||||||
dcode.cpp
|
dcode.cpp
|
||||||
deltrack.cpp
|
deltrack.cpp
|
||||||
dialog_gerber_config.cpp
|
|
||||||
dialog_print_using_printer.cpp
|
|
||||||
dialog_print_using_printer_base.cpp
|
|
||||||
dummy_functions.cpp
|
dummy_functions.cpp
|
||||||
draw_gerber_screen.cpp
|
draw_gerber_screen.cpp
|
||||||
edit.cpp
|
edit.cpp
|
||||||
|
@ -32,8 +37,6 @@ set(GERBVIEW_SRCS
|
||||||
files.cpp
|
files.cpp
|
||||||
gerberframe.cpp
|
gerberframe.cpp
|
||||||
gerbview_config.cpp
|
gerbview_config.cpp
|
||||||
gerbview_dialog_display_options_frame_base.cpp
|
|
||||||
gerbview_dialog_display_options_frame.cpp
|
|
||||||
gerbview.cpp
|
gerbview.cpp
|
||||||
hotkeys.cpp
|
hotkeys.cpp
|
||||||
initpcb.cpp
|
initpcb.cpp
|
||||||
|
@ -87,6 +90,7 @@ endif(APPLE)
|
||||||
###
|
###
|
||||||
add_executable(gerbview WIN32 MACOSX_BUNDLE
|
add_executable(gerbview WIN32 MACOSX_BUNDLE
|
||||||
${GERBVIEW_SRCS}
|
${GERBVIEW_SRCS}
|
||||||
|
${DIALOGS_SRCS}
|
||||||
${GERBVIEW_EXTRA_SRCS}
|
${GERBVIEW_EXTRA_SRCS}
|
||||||
${GERBVIEW_RESOURCES})
|
${GERBVIEW_RESOURCES})
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetClearance(): NULL netclass") );
|
wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetClearance():NULL netclass,type %d"), Type() );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const
|
||||||
if( board == NULL ) // Should not occurs
|
if( board == NULL ) // Should not occurs
|
||||||
{
|
{
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetNetClass(): NULL board, type %d"), Type() );
|
wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetNetClass():NULL board,type %d"), Type() );
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
if( netclass == NULL )
|
if( netclass == NULL )
|
||||||
{
|
{
|
||||||
wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetNetClass(): NULL netclass") );
|
wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetNetClass():NULL netclass,type %d"), Type());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,8 +213,12 @@ void D_PAD::Copy( D_PAD* source )
|
||||||
* returns the clearance in internal units. If \a aItem is not NULL then the
|
* returns the clearance in internal units. If \a aItem is not NULL then the
|
||||||
* returned clearance is the greater of this object's clearance and
|
* returned clearance is the greater of this object's clearance and
|
||||||
* aItem's clearance. If \a aItem is NULL, then this objects
|
* aItem's clearance. If \a aItem is NULL, then this objects
|
||||||
|
<<<<<<< TREE
|
||||||
|
* clearance is returned.
|
||||||
|
=======
|
||||||
* clearance
|
* clearance
|
||||||
* is returned.
|
* is returned.
|
||||||
|
>>>>>>> MERGE-SOURCE
|
||||||
* @param aItem is another BOARD_CONNECTED_ITEM or NULL
|
* @param aItem is another BOARD_CONNECTED_ITEM or NULL
|
||||||
* @return int - the clearance in internal units.
|
* @return int - the clearance in internal units.
|
||||||
*/
|
*/
|
||||||
|
@ -230,10 +234,17 @@ int D_PAD::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
|
||||||
clearance = ( (MODULE*) GetParent() )->m_LocalClearance;
|
clearance = ( (MODULE*) GetParent() )->m_LocalClearance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< TREE
|
||||||
|
if( clearance == 0 ) // If the parent footprint clearance value = 0, use NETCLASS value
|
||||||
|
return BOARD_CONNECTED_ITEM::GetClearance( aItem );
|
||||||
|
|
||||||
|
// We have a specific clearance
|
||||||
|
=======
|
||||||
if( clearance == 0 ) // If the parent footprint clearance value = 0, use NETCLASS value
|
if( clearance == 0 ) // If the parent footprint clearance value = 0, use NETCLASS value
|
||||||
return BOARD_CONNECTED_ITEM::GetClearance( aItem );
|
return BOARD_CONNECTED_ITEM::GetClearance( aItem );
|
||||||
|
|
||||||
// We have a specific clearance.
|
// We have a specific clearance.
|
||||||
|
>>>>>>> MERGE-SOURCE
|
||||||
// if aItem, return the biggest clearance
|
// if aItem, return the biggest clearance
|
||||||
if( aItem )
|
if( aItem )
|
||||||
{
|
{
|
||||||
|
|
|
@ -556,10 +556,14 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd,
|
||||||
{
|
{
|
||||||
int layerMask = aRefPad->m_Masque_Layer & ALL_CU_LAYERS;
|
int layerMask = aRefPad->m_Masque_Layer & ALL_CU_LAYERS;
|
||||||
|
|
||||||
// used to test DRC pad to holes: this dummypad is a pad hole to test
|
/* used to test DRC pad to holes: this dummy pad has the size and shape of the hole
|
||||||
// pad to pad hole DRC, using pad to pad DRC test.
|
* to test pad to pad hole DRC, using the pad to pad DRC test function.
|
||||||
// this dummy pad is a circle or an oval.
|
* Therefore, this dummy pad is a circle or an oval.
|
||||||
static D_PAD dummypad( (MODULE*) NULL );
|
* A pad must have a parent because some functions expect a non null parent
|
||||||
|
* to find the parent board, and some other data
|
||||||
|
*/
|
||||||
|
MODULE dummymodule( m_pcb ); // Creates a dummy parent
|
||||||
|
D_PAD dummypad( &dummymodule );
|
||||||
dummypad.m_Masque_Layer |= ALL_CU_LAYERS; // Ensure the hole is on all copper layers
|
dummypad.m_Masque_Layer |= ALL_CU_LAYERS; // Ensure the hole is on all copper layers
|
||||||
dummypad.m_LocalClearance = 1; /* Use the minimal local clerance value for the dummy pad
|
dummypad.m_LocalClearance = 1; /* Use the minimal local clerance value for the dummy pad
|
||||||
* the clearance of the active pad will be used
|
* the clearance of the active pad will be used
|
||||||
|
|
|
@ -264,9 +264,16 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
|
||||||
/* Phase 1 : test DRC track to pads : */
|
/* Phase 1 : test DRC track to pads : */
|
||||||
/******************************************/
|
/******************************************/
|
||||||
|
|
||||||
// Use a dummy pad to test DRC tracks versus holes, for pads not on all copper layers
|
/* Use a dummy pad to test DRC tracks versus holes, for pads not on all copper layers
|
||||||
// but having a hole
|
* but having a hole
|
||||||
D_PAD dummypad( (MODULE*) NULL ); // construct this once outside following loop
|
* This dummy pad has the size and shape of the hole
|
||||||
|
* to test tracks to pad hole DRC, using checkClearanceSegmToPad test function.
|
||||||
|
* Therefore, this dummy pad is a circle or an oval.
|
||||||
|
* A pad must have a parent because some functions expect a non null parent
|
||||||
|
* to find the parent board, and some other data
|
||||||
|
*/
|
||||||
|
MODULE dummymodule( m_pcb ); // Creates a dummy parent
|
||||||
|
D_PAD dummypad( &dummymodule );
|
||||||
dummypad.m_Masque_Layer = ALL_CU_LAYERS; // Ensure the hole is on all layers
|
dummypad.m_Masque_Layer = ALL_CU_LAYERS; // Ensure the hole is on all layers
|
||||||
|
|
||||||
// Compute the min distance to pads
|
// Compute the min distance to pads
|
||||||
|
|
|
@ -173,7 +173,15 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
static std::vector <CPolyPt> cornerBufferPolysToSubstract;
|
static std::vector <CPolyPt> cornerBufferPolysToSubstract;
|
||||||
cornerBufferPolysToSubstract.clear();
|
cornerBufferPolysToSubstract.clear();
|
||||||
|
|
||||||
D_PAD dummyPad( (MODULE*) NULL );
|
/* Use a dummy pad to calculate hole clerance when a pad is not on all copper layers
|
||||||
|
* and this pad has a hole
|
||||||
|
* This dummy pad has the size and shape of the hole
|
||||||
|
* Therefore, this dummy pad is a circle or an oval.
|
||||||
|
* A pad must have a parent because some functions expect a non null parent
|
||||||
|
* to find the parent board, and some other data
|
||||||
|
*/
|
||||||
|
MODULE dummymodule( aPcb ); // Creates a dummy parent
|
||||||
|
D_PAD dummypad( &dummymodule );
|
||||||
D_PAD* nextpad;
|
D_PAD* nextpad;
|
||||||
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
|
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
|
||||||
{
|
{
|
||||||
|
@ -190,11 +198,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Use a dummy pad to calculate a hole shape that have the same dimension as the pad hole
|
// Use a dummy pad to calculate a hole shape that have the same dimension as the pad hole
|
||||||
dummyPad.m_Size = pad->m_Drill;
|
dummypad.m_Size = pad->m_Drill;
|
||||||
dummyPad.m_Orient = pad->m_Orient;
|
dummypad.m_Orient = pad->m_Orient;
|
||||||
dummyPad.m_PadShape = pad->m_DrillShape;
|
dummypad.m_PadShape = pad->m_DrillShape;
|
||||||
dummyPad.m_Pos = pad->m_Pos;
|
dummypad.m_Pos = pad->m_Pos;
|
||||||
pad = &dummyPad;
|
pad = &dummypad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pad->GetNet() != GetNet() )
|
if( pad->GetNet() != GetNet() )
|
||||||
|
|
|
@ -209,7 +209,15 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
static std::vector <CPolyPt> cornerBufferPolysToSubstract;
|
static std::vector <CPolyPt> cornerBufferPolysToSubstract;
|
||||||
cornerBufferPolysToSubstract.clear();
|
cornerBufferPolysToSubstract.clear();
|
||||||
|
|
||||||
D_PAD dummyPad( (MODULE*) NULL );
|
/* Use a dummy pad to calculate hole clerance when a pad is not on all copper layers
|
||||||
|
* and this pad has a hole
|
||||||
|
* This dummy pad has the size and shape of the hole
|
||||||
|
* Therefore, this dummy pad is a circle or an oval.
|
||||||
|
* A pad must have a parent because some functions expect a non null parent
|
||||||
|
* to find the parent board, and some other data
|
||||||
|
*/
|
||||||
|
MODULE dummymodule( aPcb ); // Creates a dummy parent
|
||||||
|
D_PAD dummypad( &dummymodule );
|
||||||
D_PAD* nextpad;
|
D_PAD* nextpad;
|
||||||
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
|
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
|
||||||
{
|
{
|
||||||
|
@ -226,11 +234,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Use a dummy pad to calculate a hole shape that have the same dimension as the pad hole
|
// Use a dummy pad to calculate a hole shape that have the same dimension as the pad hole
|
||||||
dummyPad.m_Size = pad->m_Drill;
|
dummypad.m_Size = pad->m_Drill;
|
||||||
dummyPad.m_Orient = pad->m_Orient;
|
dummypad.m_Orient = pad->m_Orient;
|
||||||
dummyPad.m_PadShape = pad->m_DrillShape;
|
dummypad.m_PadShape = pad->m_DrillShape;
|
||||||
dummyPad.m_Pos = pad->m_Pos;
|
dummypad.m_Pos = pad->m_Pos;
|
||||||
pad = &dummyPad;
|
pad = &dummypad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pad->GetNet() != GetNet() )
|
if( pad->GetNet() != GetNet() )
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "PolyLine.h"
|
#include "PolyLine.h"
|
||||||
#include "gr_basic.h"
|
#include "gr_basic.h"
|
||||||
#include "bezier_curves.h"
|
#include "bezier_curves.h"
|
||||||
|
#include "polygon_test_point_inside.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -1366,150 +1367,25 @@ bool CPolyLine::TestPointInside( int px, int py )
|
||||||
wxASSERT( 0 );
|
wxASSERT( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// define line passing through (x,y), with slope = 2/3;
|
// Test all polygons.
|
||||||
// get intersection points
|
// Since the first is the main outline, and other are hole,
|
||||||
int xx, yy;
|
// if the tested point is inside only one contour, it is inside the whole polygon
|
||||||
double slope = (double) 2.0 / 3.0;
|
// (in fact inside the main outline, and outside all holes).
|
||||||
double a = py - slope * px;
|
// if inside 2 contours (the main outline + an hole), it is outside the poly.
|
||||||
int nloops = 0;
|
int polycount = GetNumContours();
|
||||||
int npts;
|
bool inside = false;
|
||||||
bool inside = false;
|
for( int icont = 0; icont < polycount; icont++ )
|
||||||
|
|
||||||
// make this a loop so if my homebrew algorithm screws up, we try it again
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
// now find all intersection points of line with polyline sides
|
|
||||||
npts = 0;
|
|
||||||
inside = false;
|
|
||||||
for( int icont = 0; icont<GetNumContours(); icont++ )
|
|
||||||
{
|
|
||||||
int istart = GetContourStart( icont );
|
|
||||||
int iend = GetContourEnd( icont );
|
|
||||||
for( int ic = istart; ic<=iend; ic++ )
|
|
||||||
{
|
|
||||||
double x, y, x2, y2;
|
|
||||||
int ok;
|
|
||||||
if( ic == istart )
|
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
|
||||||
corner[iend].x, corner[iend].y,
|
|
||||||
corner[istart].x, corner[istart].y,
|
|
||||||
side_style[iend],
|
|
||||||
&x, &y, &x2, &y2 );
|
|
||||||
else
|
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
|
||||||
corner[ic - 1].x, corner[ic - 1].y,
|
|
||||||
corner[ic].x, corner[ic].y,
|
|
||||||
side_style[ic - 1],
|
|
||||||
&x, &y, &x2, &y2 );
|
|
||||||
if( ok )
|
|
||||||
{
|
|
||||||
xx = (int) x;
|
|
||||||
yy = (int) y;
|
|
||||||
if( xx == px && yy == py )
|
|
||||||
return FALSE; // (x,y) is on a side, call it outside
|
|
||||||
else if( xx > px )
|
|
||||||
inside = not inside;
|
|
||||||
npts++;
|
|
||||||
}
|
|
||||||
if( ok == 2 )
|
|
||||||
{
|
|
||||||
xx = (int) x2;
|
|
||||||
yy = (int) y2;
|
|
||||||
if( xx == px && yy == py )
|
|
||||||
return FALSE; // (x,y) is on a side, call it outside
|
|
||||||
else if( xx > px )
|
|
||||||
inside = not inside;
|
|
||||||
npts++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nloops++;
|
|
||||||
a += PCBU_PER_MIL / 100;
|
|
||||||
} while( npts % 2 != 0 && nloops < 3 );
|
|
||||||
|
|
||||||
wxASSERT( npts % 2==0 ); // odd number of intersection points, error
|
|
||||||
|
|
||||||
return inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// test to see if a point is inside polyline contour
|
|
||||||
//
|
|
||||||
bool CPolyLine::TestPointInsideContour( int icont, int px, int py )
|
|
||||||
{
|
|
||||||
if( icont >= GetNumContours() )
|
|
||||||
return FALSE;
|
|
||||||
if( !GetClosed() )
|
|
||||||
{
|
|
||||||
wxASSERT( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// define line passing through (x,y), with slope = 2/3;
|
|
||||||
// get intersection points
|
|
||||||
int xx, yy;
|
|
||||||
double slope = (double) 2.0 / 3.0;
|
|
||||||
double a = py - slope * px;
|
|
||||||
int nloops = 0;
|
|
||||||
int npts;
|
|
||||||
bool inside = false;
|
|
||||||
|
|
||||||
// make this a loop so if my homebrew algorithm screws up, we try it again
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// now find all intersection points of line with polyline sides
|
|
||||||
npts = 0;
|
|
||||||
inside = false;
|
|
||||||
int istart = GetContourStart( icont );
|
int istart = GetContourStart( icont );
|
||||||
int iend = GetContourEnd( icont );
|
int iend = GetContourEnd( icont );
|
||||||
for( int ic = istart; ic<=iend; ic++ )
|
// Test this polygon:
|
||||||
{
|
if( TestPointInsidePolygon( corner, istart, iend, px, py) ) // test point inside the current polygon
|
||||||
double x, y, x2, y2;
|
inside = not inside;
|
||||||
int ok;
|
}
|
||||||
if( ic == istart )
|
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
|
||||||
corner[iend].x, corner[iend].y,
|
|
||||||
corner[istart].x, corner[istart].y,
|
|
||||||
side_style[iend],
|
|
||||||
&x, &y, &x2, &y2 );
|
|
||||||
else
|
|
||||||
ok = FindLineSegmentIntersection( a, slope,
|
|
||||||
corner[ic - 1].x, corner[ic - 1].y,
|
|
||||||
corner[ic].x, corner[ic].y,
|
|
||||||
side_style[ic - 1],
|
|
||||||
&x, &y, &x2, &y2 );
|
|
||||||
if( ok )
|
|
||||||
{
|
|
||||||
xx = (int) x;
|
|
||||||
yy = (int) y;
|
|
||||||
npts++;
|
|
||||||
if( xx == px && yy == py )
|
|
||||||
return FALSE; // (x,y) is on a side, call it outside
|
|
||||||
else if( xx > px )
|
|
||||||
inside = not inside;
|
|
||||||
}
|
|
||||||
if( ok == 2 )
|
|
||||||
{
|
|
||||||
xx = (int) x2;
|
|
||||||
yy = (int) y2;
|
|
||||||
npts++;
|
|
||||||
if( xx == px && yy == py )
|
|
||||||
return FALSE; // (x,y) is on a side, call it outside
|
|
||||||
else if( xx > px )
|
|
||||||
inside = not inside;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nloops++;
|
|
||||||
a += PCBU_PER_MIL / 100;
|
|
||||||
} while( npts % 2 != 0 && nloops < 3 );
|
|
||||||
|
|
||||||
wxASSERT( npts % 2==0 ); // odd number of intersection points, error
|
|
||||||
|
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// copy data from another poly, but don't draw it
|
// copy data from another poly, but don't draw it
|
||||||
//
|
//
|
||||||
void CPolyLine::Copy( CPolyLine* src )
|
void CPolyLine::Copy( CPolyLine* src )
|
||||||
|
|
|
@ -145,7 +145,6 @@ public:
|
||||||
CRect GetCornerBounds( int icont );
|
CRect GetCornerBounds( int icont );
|
||||||
void Copy( CPolyLine* src );
|
void Copy( CPolyLine* src );
|
||||||
bool TestPointInside( int x, int y );
|
bool TestPointInside( int x, int y );
|
||||||
bool TestPointInsideContour( int icont, int x, int y );
|
|
||||||
bool IsCutoutContour( int icont );
|
bool IsCutoutContour( int icont );
|
||||||
void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num );
|
void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num );
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* Because the starting point of a segment is also the ending point of the previous, only one must be used.
|
* Because the starting point of a segment is also the ending point of the previous, only one must be used.
|
||||||
* And we do no use twice the same segment, so we do NOT use both starting and ending points of these 2 segments.
|
* And we do no use twice the same segment, so we do NOT use both starting and ending points of these 2 segments.
|
||||||
* So we must use only one ending point of each segment when calculating intersections
|
* So we must use only one ending point of each segment when calculating intersections
|
||||||
* but it cannot be always the starting or the endind point. This depend on relative position of 2 consectutive segments
|
* but it cannot be always the starting or the ending point. This depend on relative position of 2 consectutive segments
|
||||||
* Here, the ending point above the Y reference position is used
|
* Here, the ending point above the Y reference position is used
|
||||||
* and the ending point below or equal the Y reference position is NOT used
|
* and the ending point below or equal the Y reference position is NOT used
|
||||||
* Obviously, others cases are irrelevant because there is not intersection.
|
* Obviously, others cases are irrelevant because there is not intersection.
|
||||||
|
@ -35,10 +35,9 @@ bool TestPointInsidePolygon( std::vector <CPolyPt> aPolysList,
|
||||||
/** Function TestPointInsidePolygon
|
/** Function TestPointInsidePolygon
|
||||||
* test if a point is inside or outside a polygon.
|
* test if a point is inside or outside a polygon.
|
||||||
* the polygon must have only lines (not arcs) for outlines.
|
* the polygon must have only lines (not arcs) for outlines.
|
||||||
* Use TestPointInside or TestPointInsideContour for more complex polygons
|
|
||||||
* @param aPolysList: the list of polygons
|
* @param aPolysList: the list of polygons
|
||||||
* @param aIdxstart: the starting point of a given polygon in m_FilledPolysList.
|
* @param aIdxstart: the starting point of a given polygon in m_FilledPolysList.
|
||||||
* @param aIdxend: the ending point of the polygon in m_FilledPolysList.
|
* @param aIdxend: the ending point of this polygon in m_FilledPolysList.
|
||||||
* @param aRefx, aRefy: the point coordinate to test
|
* @param aRefx, aRefy: the point coordinate to test
|
||||||
* @return true if the point is inside, false for outside
|
* @return true if the point is inside, false for outside
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue