Fix issues in zones creation (DRC and merging) I created in 3658.1

This commit is contained in:
jean-pierre charras 2012-07-30 09:40:25 +02:00
parent 1c9433fb31
commit f96d557e73
13 changed files with 263 additions and 116 deletions

View File

@ -46,6 +46,7 @@
#include <pcbnew.h>
#include <zones.h>
#include <math_for_graphics.h>
ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) :
@ -912,7 +913,7 @@ void ZONE_CONTAINER::AddPolygon( std::vector< wxPoint >& aPolygon )
AppendCorner( aPolygon[i] );
}
m_Poly->Close();
m_Poly->CloseLastContour();
}

View File

@ -429,7 +429,7 @@ public:
return m_Poly->GetHatchStyle();
}
void SetHatchStyle( CPolyLine::hatch_style aStyle )
void SetHatchStyle( CPolyLine::HATCH_STYLE aStyle )
{
m_Poly->SetHatchStyle( aStyle );
}

View File

@ -99,7 +99,6 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c
aTarget.m_FillMode = m_FillMode;
aTarget.m_ZoneClearance = m_ZoneClearance;
aTarget.m_ZoneMinThickness = m_ZoneMinThickness;
aTarget.m_Poly->SetHatch( m_Zone_HatchingStyle, Mils2iu( 20 ) );
aTarget.m_ArcToSegmentsCount = m_ArcToSegmentsCount;
aTarget.m_ThermalReliefGap = m_ThermalReliefGap;
aTarget.m_ThermalReliefCopperBridge = m_ThermalReliefCopperBridge;
@ -118,4 +117,8 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c
aTarget.SetLayer( m_CurrentZone_Layer );
aTarget.m_Poly->SetLayer( m_CurrentZone_Layer );
}
// call SetHatch last, because hatch lines will be rebuilt,
// using new parameters values
aTarget.m_Poly->SetHatch( m_Zone_HatchingStyle, Mils2iu( 20 ), true );
}

View File

@ -44,6 +44,7 @@
#include <class_track.h>
#include <class_zone.h>
#include <class_marker_pcb.h>
#include <math_for_graphics.h>
/* compare 2 trapezoids (can be rectangle) and return true if distance > aDist

View File

@ -1404,17 +1404,18 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics )
zone->SetLayer( layer );
zone->SetNet( 0 );
int outline_hatch = CPolyLine::DIAGONAL_EDGE;
CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE;
zone->m_Poly->Start( layer, kicad_x( r.x1 ), kicad_y( r.y1 ), outline_hatch );
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ) );
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ) );
zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) );
zone->m_Poly->Close();
zone->m_Poly->CloseLastContour();
// this is not my fault:
zone->m_Poly->SetHatch( outline_hatch,
Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ) );
Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ),
true );
}
m_xpath->pop();
}
@ -2360,7 +2361,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
zone->SetNet( netCode );
zone->SetNetName( netName );
int outline_hatch = CPolyLine::DIAGONAL_EDGE;
CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE;
bool first = true;
for( CITER vi = it->second.begin(); vi != it->second.end(); ++vi )
@ -2380,10 +2381,11 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
zone->AppendCorner( wxPoint( kicad_x( v.x ), kicad_y( v.y ) ) );
}
zone->m_Poly->Close();
zone->m_Poly->CloseLastContour();
zone->m_Poly->SetHatch( outline_hatch,
Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ) );
Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ),
true );
// clearances, etc.
zone->SetArcSegCount( 32 ); // @todo: should be a constructor default?

View File

@ -2109,7 +2109,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
{
auto_ptr<ZONE_CONTAINER> zc( new ZONE_CONTAINER( m_board ) );
int outline_hatch = CPolyLine::NO_HATCH;
CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::NO_HATCH;
bool sawCorner = false;
char buf[1024];
@ -2133,7 +2133,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
sawCorner = true;
if( flag )
zc->m_Poly->Close();
zc->m_Poly->CloseLastContour();
}
else if( TESTLINE( "ZInfo" ) ) // general info found
@ -2350,9 +2350,11 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
zc->SetNet( 0 );
}
// Hatch here, after outlines corners are read
// Set hatch here, after outlines corners are read
zc->m_Poly->SetHatch( outline_hatch,
Mils2iu( zc->m_Poly->GetDefaultHatchPitchMils() ) );
Mils2iu( CPolyLine::GetDefaultHatchPitchMils() ),
true );
m_board->Add( zc.release() );
}

View File

@ -2292,8 +2292,8 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
wxT( " as ZONE_CONTAINER." ) );
int hatchStyle = CPolyLine::NO_HATCH; // Fix compile warning
int hatchPitch = 0; // Fix compile warning
CPolyLine::HATCH_STYLE hatchStyle = CPolyLine::NO_HATCH;
int hatchPitch = Mils2iu( CPolyLine::GetDefaultHatchPitchMils() );
wxPoint pt;
T token;
@ -2587,7 +2587,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
}
// Set hatch here, after outlines corners are read
zone->m_Poly->SetHatch( hatchStyle, hatchPitch );
zone->m_Poly->SetHatch( hatchStyle, hatchPitch, true );
}
if( pts.size() )

View File

@ -679,8 +679,12 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC )
if( !Drc_On || !zone->IsOnCopperLayer() || ( m_drc->Drc( zone, ii - 1 ) == OK_DRC ) )
{
// Ok, we can add a new corner
if( m_canvas->IsMouseCaptured() )
m_canvas->CallMouseCapture( DC, wxPoint(0,0), false );
zone->AppendCorner( GetScreen()->GetCrossHairPosition() );
SetCurItem( zone ); // calls DisplayInfo().
if( m_canvas->IsMouseCaptured() )
m_canvas->CallMouseCapture( DC, wxPoint(0,0), false );
}
}
}
@ -738,7 +742,7 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC )
// Put new zone in list
if( !s_CurrentZone )
{
zone->m_Poly->Close(); // Close the current corner list
zone->m_Poly->CloseLastContour(); // Close the current corner list
GetBoard()->Add( zone );
GetBoard()->m_CurrentZoneContour = NULL;
@ -753,7 +757,7 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC )
s_CurrentZone->AppendCorner( zone->GetCornerPosition( ii ) );
}
s_CurrentZone->m_Poly->Close(); // Close the current corner list
s_CurrentZone->m_Poly->CloseLastContour(); // Close the current corner list
zone->RemoveAllContours(); // All corners are copied in s_CurrentZone. Free corner list.
zone = s_CurrentZone;
}

View File

@ -41,6 +41,7 @@
#include <pcbnew.h>
#include <drc_stuff.h>
#include <math_for_graphics.h>
static bool bDontShowSelfIntersectionArcsWarning;
@ -311,19 +312,15 @@ int BOARD::ClipAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList,
str += wxT( "This may result in splitting the area.\n" );
str += wxT( "If the area is complex, this may take a few seconds." );
wxMessageBox( str );
// bDontShowSelfIntersectionWarning = dlg.bDontShowBoxState;
}
}
//** TODO test for cutouts outside of area
//** if( test == 1 )
{
std::vector<CPolyLine*>* pa = new std::vector<CPolyLine*>;
curr_polygon->UnHatch();
int n_poly = aCurrArea->m_Poly->NormalizeAreaOutlines( pa, bRetainArcs );
// i.e if clipping has created some polygons, we must add these new copper areas.
// If clipping has created some polygons, we must add these new copper areas.
if( n_poly > 1 )
{
ZONE_CONTAINER* NewArea;
@ -803,10 +800,10 @@ int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_r
}
// polygons intersect, combine them
// std::vector<CArc> arc_array1;
// std::vector<CArc> arc_array2;
bool keep_area_to_combine = false; // TODO test if areas intersect
// TODO: test here if areas intersect and combine only if so
#if 0
// do not set to 1 (not fully working): only for me (JP. Charras) until this code is finished
KI_POLYGON_WITH_HOLES areaRefPoly;
KI_POLYGON_WITH_HOLES areaToMergePoly;
CopyPolysListToKiPolygonWithHole( area_ref->m_Poly->m_CornersList, areaRefPoly );
@ -814,14 +811,12 @@ int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_r
KI_POLYGON_WITH_HOLES_SET mergedOutlines;
mergedOutlines.push_back( areaRefPoly );
mergedOutlines += areaToMergePoly;
mergedOutlines |= areaToMergePoly;
// We should have only one polygon with holes in mergedOutlines
// or the 2 initial outlines do not intersect
if( mergedOutlines.size() > 1 )
return 0;
// We can have more than one polygon with holes in mergedOutlines
// depending on the complexity of outlines
areaRefPoly = mergedOutlines[0];
areaRefPoly = mergedOutlines[0]; // TODO: read and create all created polygons
area_ref->m_Poly->RemoveAllContours();
KI_POLYGON_WITH_HOLES::iterator_type corner = areaRefPoly.begin();
@ -833,7 +828,7 @@ int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_r
area_ref->m_Poly->AppendCorner( corner->x(), corner->y() );
}
area_ref->m_Poly->Close();
area_ref->m_Poly->CloseLastContour();
// add holes (set of polygons)
KI_POLYGON_WITH_HOLES::iterator_holes_type hole = areaRefPoly.begin_holes();
@ -846,17 +841,83 @@ int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_r
area_ref->m_Poly->AppendCorner( hole_corner->x(), hole_corner->y() );
hole_corner++;
}
area_ref->m_Poly->Close();
area_ref->m_Poly->CloseLastContour();
hole++;
}
#else
void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false );
Bool_Engine* booleng = new Bool_Engine();
armBoolEng( booleng );
area_ref->m_Poly->AddPolygonsToBoolEng( booleng, GROUP_A );
area_to_combine->m_Poly->AddPolygonsToBoolEng(booleng, GROUP_B );
booleng->Do_Operation( BOOL_OR );
if( !keep_area_to_combine )
RemoveArea( aDeletedList, area_to_combine );
// create area with external contour: Recreate only area edges, NOT holes
if( booleng->StartPolygonGet() )
{
if( booleng->GetPolygonPointEdgeType() == KB_INSIDE_EDGE )
{
DisplayError( NULL, wxT( "BOARD::CombineAreas() error: unexpected hole descriptor" ) );
}
area_ref->m_Poly->RemoveAllContours();
// foreach point in the polygon
bool first = true;
while( booleng->PolygonHasMorePoints() )
{
int x = (int) booleng->GetPolygonXPoint();
int y = (int) booleng->GetPolygonYPoint();
if( first )
{
first = false;
area_ref->m_Poly->Start( area_ref->GetLayer(
), x, y, area_ref->m_Poly->GetHatchStyle() );
}
else
{
area_ref->m_Poly->AppendCorner( x, y );
}
}
booleng->EndPolygonGet();
area_ref->m_Poly->CloseLastContour();
}
// add holes
bool show_error = true;
while( booleng->StartPolygonGet() )
{
// we expect all vertex are holes inside the main outline
if( booleng->GetPolygonPointEdgeType() != KB_INSIDE_EDGE )
{
if( show_error ) // show this error only once, if happens
DisplayError( NULL,
wxT( "BOARD::CombineAreas() error: unexpected outside contour descriptor" ) );
show_error = false;
continue;
}
while( booleng->PolygonHasMorePoints() )
{
int x = (int) booleng->GetPolygonXPoint();
int y = (int) booleng->GetPolygonYPoint();
area_ref->m_Poly->AppendCorner( x, y );
}
area_ref->m_Poly->CloseLastContour();
booleng->EndPolygonGet();
}
#endif
RemoveArea( aDeletedList, area_to_combine );
area_ref->utility = 1;
// area_ref->m_Poly->RestoreArcs( &arc_array1 );
// area_ref->m_Poly->RestoreArcs( &arc_array2 );
area_ref->m_Poly->Hatch();
return 1;
@ -917,6 +978,11 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
// ZONE_CONTAINER::GetClearance().
int zone2zoneClearance = Area_Ref->GetClearance( area_to_test );
// Keepout areas have no clearance, so set zone2zoneClearance to 1
// ( zone2zoneClearance = 0 can create problems in test functions)
if( Area_Ref->GetIsKeepout() )
zone2zoneClearance = 1;
// test for some corners of Area_Ref inside area_to_test
for( int ic = 0; ic < refSmoothedPoly->GetNumCorners(); ic++ )
{
@ -1114,6 +1180,11 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
if( area_to_test->GetIsKeepout() != aArea->GetIsKeepout() )
continue;
// For keepout, there is no clearance, so use a minimal value for it
// use 1, not 0 as value to avoid some issues in tests
if( area_to_test->GetIsKeepout() )
zone_clearance = 1;
// test for ending line inside area_to_test
if( area_to_test->m_Poly->TestPointInside( end.x, end.y ) )
{
@ -1159,7 +1230,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
0,
ax1, ay1, ax2, ay2, astyle,
0,
0,
zone_clearance,
&x, &y );
if( d < zone_clearance )

View File

@ -13,11 +13,13 @@
#include <PolyLine.h>
#include <bezier_curves.h>
#include <polygon_test_point_inside.h>
#include <math_for_graphics.h>
CPolyLine::CPolyLine()
{
m_hatchStyle = NO_HATCH;
m_hatchPitch = 0;
m_layer = 0;
m_width = 0;
m_utility = 0;
m_Kbool_Poly_Engine = NULL;
@ -44,7 +46,7 @@ CPolyLine::~CPolyLine()
* false: holes are not linked: in this mode contours are added clockwise
* and polygons added counter clockwise are holes (default)
*/
static void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false );
void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false );
/**
* Function NormalizeWithKbool
@ -128,16 +130,19 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*>* aExtraPolyList, bool
}
m_Kbool_Poly_Engine->EndPolygonGet();
Close();
CloseLastContour();
n_ext_cont++;
}
else if( aExtraPolyList ) // a new outside contour is found: create a new CPolyLine
else if( aExtraPolyList ) // a new outside contour is found: create a new CPolyLine
{
polyline = new CPolyLine; // create new poly
aExtraPolyList->push_back( polyline ); // put it in array
polyline = new CPolyLine;
polyline->SetLayer( GetLayer() );
polyline->SetHatchStyle( GetHatchStyle() );
polyline->SetHatchPitch( GetHatchPitch() );
aExtraPolyList->push_back( polyline ); // put it in array
bool first = true;
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // read next external contour
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // read next external contour
{
int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint();
int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint();
@ -152,7 +157,7 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*>* aExtraPolyList, bool
}
m_Kbool_Poly_Engine->EndPolygonGet();
polyline->Close( STRAIGHT, false );
polyline->CloseLastContour();
n_ext_cont++;
}
}
@ -201,7 +206,7 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*>* aExtraPolyList, bool
polyline->AppendCorner( x, y, STRAIGHT, false );
}
polyline->Close( STRAIGHT, false );
polyline->CloseLastContour();
}
}
@ -219,6 +224,42 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*>* aExtraPolyList, bool
}
/**
* Function AddPolygonsToBoolEng
* Add a CPolyLine to a kbool engine, preparing a boolean op between polygons
* @param aBooleng : pointer on a bool engine (handle a set of polygons)
* @param aGroup : group to fill (aGroup = GROUP_A or GROUP_B) operations are made between GROUP_A and GROUP_B
*/
int CPolyLine::AddPolygonsToBoolEng( Bool_Engine* aBooleng, GroupType aGroup )
{
int count = 0;
/* Convert the current polyline contour to a kbool polygon: */
MakeKboolPoly();
/* add the resulting kbool set of polygons to the current kcool engine */
while( m_Kbool_Poly_Engine->StartPolygonGet() )
{
if( aBooleng->StartPolygonAdd( GROUP_A ) )
{
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() )
{
int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint();
int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint();
aBooleng->AddPoint( x, y );
count++;
}
aBooleng->EndPolygonAdd();
}
m_Kbool_Poly_Engine->EndPolygonGet();
}
delete m_Kbool_Poly_Engine;
m_Kbool_Poly_Engine = NULL;
return count;
}
/**
* Function MakeKboolPoly
* fill a kbool engine with a closed polyline contour
@ -247,13 +288,32 @@ int CPolyLine::MakeKboolPoly( std::vector<CArc>* arc_array )
int iarc = 0;
for( int icont = 0; icont<=last_contour; icont++ )
for( int icont = 0; icont <= last_contour; icont++ )
{
// Fill a kbool engine for this contour,
// and combine it with previous contours
Bool_Engine* booleng = new Bool_Engine();
armBoolEng( booleng, false );
if( m_Kbool_Poly_Engine ) // a previous contour exists. Put it in new engine
{
while( m_Kbool_Poly_Engine->StartPolygonGet() )
{
if( booleng->StartPolygonAdd( GROUP_A ) )
{
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() )
{
int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint();
int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint();
booleng->AddPoint( x, y );
}
booleng->EndPolygonAdd();
}
m_Kbool_Poly_Engine->EndPolygonGet();
}
}
// first, calculate number of vertices in contour
int n_vertices = 0;
int ic_st = GetContourStart( icont );
@ -735,7 +795,7 @@ int CPolyLine::RestoreArcs( std::vector<CArc>* arc_array, std::vector<CPolyLine*
void CPolyLine::Start( int layer, int x, int y, int hatch )
{
m_layer = layer;
SetHatchStyle( (enum hatch_style) hatch );
SetHatchStyle( (enum HATCH_STYLE) hatch );
CPolyPt poly_pt( x, y );
poly_pt.end_contour = false;
@ -766,19 +826,9 @@ void CPolyLine::AppendCorner( int x, int y, int style, bool bDraw )
// close last polyline contour
//
void CPolyLine::Close( int style, bool bDraw )
void CPolyLine::CloseLastContour()
{
if( GetClosed() )
{
wxASSERT( 0 );
}
UnHatch();
m_SideStyle[m_CornersList.size() - 1] = style;
m_CornersList[m_CornersList.size() - 1].end_contour = true;
if( bDraw )
Hatch();
}
@ -944,7 +994,7 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance )
newPoly->AppendCorner( x1 + nx, y1 + ny );
}
newPoly->Close();
newPoly->CloseLastContour();
}
return newPoly;
@ -1072,7 +1122,7 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments )
}
}
newPoly->Close();
newPoly->CloseLastContour();
}
return newPoly;
@ -1632,11 +1682,13 @@ void CPolyLine::SetEndContour( int ic, bool end_contour )
m_CornersList[ic].end_contour = end_contour;
}
/*
* AppendArc adds segments to current contour to approximate the given arc
*/
void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num )
{
// get radius
double r = sqrt( (double) (xi - xc) * (xi - xc) + (double) (yi - yc) * (yi - yc) );
double radius = hypot( (double) (xi - xc), (double) (yi - yc) );
// get angles of start and finish
double th_i = atan2( (double) (yi - yc), (double) (xi - xc) );
@ -1645,15 +1697,15 @@ void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int n
double theta = th_i;
// generate arc
for( int ic = 0; ic<num; ic++ )
for( int ic = 0; ic < num; ic++ )
{
int x = KiROUND( xc + r * cos( theta ) );
int y = KiROUND( yc + r * sin( theta ) );
int x = KiROUND( xc + radius * cos( theta ) );
int y = KiROUND( yc + radius * sin( theta ) );
AppendCorner( x, y, STRAIGHT, 0 );
theta += th_d;
}
Close( STRAIGHT );
CloseLastContour();
}

View File

@ -58,9 +58,6 @@ public:
}
};
#include <math_for_graphics.h>
class CArc
{
public:
@ -107,7 +104,7 @@ class CPolyLine
{
public:
enum m_SideStyle { STRAIGHT, ARC_CW, ARC_CCW }; // side styles
enum hatch_style { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE }; // hatch styles
enum HATCH_STYLE { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE }; // hatch styles
// constructors/destructor
CPolyLine();
@ -119,7 +116,7 @@ public:
void InsertCorner( int ic, int x, int y );
void DeleteCorner( int ic, bool bDraw = false );
void MoveCorner( int ic, int x, int y );
void Close( int style = STRAIGHT, bool bDraw = false );
void CloseLastContour();
void RemoveContour( int icont );
/**
@ -155,6 +152,11 @@ public:
void Copy( CPolyLine* src );
bool TestPointInside( int x, int y );
bool IsCutoutContour( int icont );
/**
* Function AppendArc.
* Adds segments to current contour to approximate the given arc
*/
void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num );
// access functions
@ -181,14 +183,15 @@ public:
int GetSideStyle( int is );
int GetHatchPitch() { return m_hatchPitch; }
int GetDefaultHatchPitchMils() { return 20; } // default hatch pitch value in mils
static int GetDefaultHatchPitchMils() { return 20; } // default hatch pitch value in mils
enum hatch_style GetHatchStyle() { return m_hatchStyle; }
void SetHatch( int hatch, int pitch )
enum HATCH_STYLE GetHatchStyle() { return m_hatchStyle; }
void SetHatch( int aHatchStyle, int aHatchPitch, bool aRebuildHatch )
{
SetHatchPitch( pitch );
m_hatchStyle = (enum hatch_style) hatch;
Hatch();
SetHatchPitch( aHatchPitch );
m_hatchStyle = (enum HATCH_STYLE) aHatchStyle;
if( aRebuildHatch )
Hatch();
}
void SetX( int ic, int x );
@ -196,7 +199,7 @@ public:
void SetEndContour( int ic, bool end_contour );
void SetSideStyle( int is, int style );
void SetHatchStyle( enum hatch_style style )
void SetHatchStyle( enum HATCH_STYLE style )
{
m_hatchStyle = style;
}
@ -210,6 +213,14 @@ public:
// KBOOL functions
/**
* Function AddPolygonsToBoolEng
* Add a CPolyLine to a kbool engine, preparing a boolean op between polygons
* @param aBooleng : pointer on a bool engine (handle a set of polygons)
* @param aGroup : group to fill (aGroup = GROUP_A or GROUP_B) operations are made between GROUP_A and GROUP_B
*/
int AddPolygonsToBoolEng( Bool_Engine* aBooleng, GroupType aGroup );
/**
* Function MakeKboolPoly
* fill a kbool engine with a closed polyline contour
@ -261,7 +272,7 @@ public:
private:
int m_layer; // layer to draw on
int m_width; // lines width when drawing. Provided but not really used
enum hatch_style m_hatchStyle; // hatch style, see enum above
enum HATCH_STYLE m_hatchStyle; // hatch style, see enum above
int m_hatchPitch; // for DIAGONAL_EDGE hatched outlines, basic distance between 2 hatch lines
// and the len of eacvh segment
// for DIAGONAL_FULL, the pitch is twice this value

View File

@ -9,9 +9,23 @@
#include <fctsys.h>
#include <PolyLine.h>
#include <math_for_graphics.h>
#define NM_PER_MIL 25400
typedef struct PointTag
{
double X,Y;
} PointT;
typedef struct EllipseTag
{
PointT Center; /* ellipse center */
double xrad, yrad; // radii on x and y
double theta1, theta2; // start and end angle for arc
} EllipseKH;
double Distance( double x1, double y1, double x2, double y2 )
{
double dx = x1 - x2;
@ -21,6 +35,13 @@ double Distance( double x1, double y1, double x2, double y2 )
}
static int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
double * x1=NULL, double * y1=NULL,
double * x2=NULL, double * y2=NULL );
static bool InRange( double x, double xi, double xf );
/**
* Function TestLineHit
* test for hit on line segment i.e. a point within a given distance from segment
@ -862,26 +883,26 @@ bool FindLineEllipseIntersections( double a, double b, double c, double d, doubl
// Get clearance between 2 segments
// Returns point in segment closest to other segment in x, y
// in clearance > max_cl, just returns max_cl and doesn't return x,y
// in clearance > max_cl, just returns max_cl+1 and doesn't return x,y
//
int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, int w1,
int x2i, int y2i, int x2f, int y2f, int style2, int w2,
int max_cl, int* x, int* y )
{
// check clearance between bounding rectangles
int test = max_cl + w1 / 2 + w2 / 2;
int min_dist = max_cl + ( (w1 + w2) / 2 );
if( min( x1i, x1f ) - max( x2i, x2f ) > test )
return max_cl;
if( min( x1i, x1f ) - max( x2i, x2f ) > min_dist )
return max_cl+1;
if( min( x2i, x2f ) - max( x1i, x1f ) > test )
return max_cl;
if( min( x2i, x2f ) - max( x1i, x1f ) > min_dist )
return max_cl+1;
if( min( y1i, y1f ) - max( y2i, y2f ) > test )
return max_cl;
if( min( y1i, y1f ) - max( y2i, y2f ) > min_dist )
return max_cl+1;
if( min( y2i, y2f ) - max( y1i, y1f ) > test )
return max_cl;
if( min( y2i, y2f ) - max( y1i, y1f ) > min_dist )
return max_cl+1;
if( style1 == CPolyLine::STRAIGHT && style1 == CPolyLine::STRAIGHT )
{
@ -890,7 +911,9 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
double dd;
TestForIntersectionOfStraightLineSegments( x1i, y1i, x1f, y1f,
x2i, y2i, x2f, y2f, &xx, &yy, &dd );
int d = max( 0, (int) dd - w1 / 2 - w2 / 2 );
int d = (int) dd - ( (w1 + w2) / 2 );
if( d < 0 )
d = 0;
if( x )
*x = xx;
@ -905,10 +928,10 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
// see if segments intersect
double xr[2];
double yr[2];
test =
int count =
FindSegmentIntersections( x1i, y1i, x1f, y1f, style1, x2i, y2i, x2f, y2f, style2, xr, yr );
if( test )
if( count )
{
if( x )
*x = (int) xr[0];

View File

@ -1,22 +1,5 @@
// math stuff for graphics, from FreePCB
#ifndef abs
#define abs(x) (((x) >=0) ? (x) : (-(x)))
#endif
typedef struct PointTag
{
double X,Y;
} PointT;
typedef struct EllipseTag
{
PointT Center; /* ellipse center */
double xrad, yrad; // radii on x and y
double theta1, theta2; // start and end angle for arc
} EllipseKH;
// math stuff for graphics
bool Quadratic( double a, double b, double c, double *x1, double *x2 );
@ -70,11 +53,5 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int yf );
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( 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 );