// delete corner and adjust arrays // void CPolyLine::DeleteCorner( int ic, BOOL bDraw ) { Undraw(); int icont = GetContour( ic ); int istart = GetContourStart( icont ); int iend = GetContourEnd( icont ); BOOL bClosed = icont < GetNumContours()-1 || GetClosed(); if( !bClosed ) { // open contour, must be last contour corner.RemoveAt( ic ); if( ic != istart ) side_style.RemoveAt( ic-1 ); m_ncorners--; } else { // closed contour corner.RemoveAt( ic ); side_style.RemoveAt( ic ); if( ic == iend ) corner[ic-1].end_contour = TRUE; m_ncorners--; } if( bClosed && GetContourSize(icont) < 3 ) { // delete the entire contour RemoveContour( icont ); } if( bDraw ) Draw(); }
int CPolyLine::GetNumSides() { if( GetClosed() ) return m_ncorners; else return m_ncorners-1; }
// test to see if a point is inside polyline // bool CPolyLine::TestPointInside( int px, int py ) { if( !GetClosed() ) { wxASSERT( 0 ); } // Test all polygons. // Since the first is the main outline, and other are holes, // if the tested point is inside only one contour, it is inside the whole polygon // (in fact inside the main outline, and outside all holes). // if inside 2 contours (the main outline + an hole), it is outside the poly. int polycount = GetContoursCount(); bool inside = false; for( int icont = 0; icont < polycount; icont++ ) { int istart = GetContourStart( icont ); int iend = GetContourEnd( icont ); // test point inside the current polygon if( TestPointInsidePolygon( m_CornersList, istart, iend, px, py ) ) inside = not inside; } return inside; }
// delete corner and adjust arrays // void CPolyLine::DeleteCorner( int ic ) { UnHatch(); int icont = GetContour( ic ); int iend = GetContourEnd( icont ); bool closed = icont < GetContoursCount() - 1 || GetClosed(); if( !closed ) { // open contour, must be last contour m_CornersList.DeleteCorner( ic ); } else { // closed contour m_CornersList.DeleteCorner( ic ); if( ic == iend ) m_CornersList[ic - 1].end_contour = true; } if( closed && GetContourSize( icont ) < 3 ) { // delete the entire contour RemoveContour( icont ); } }
// close last polyline contour // void CPolyLine::Close( int style, BOOL bDraw ) { if( GetClosed() ) ASSERT(0); Undraw(); side_style[m_ncorners-1] = style; corner[m_ncorners-1].end_contour = TRUE; corner.SetSize( m_ncorners ); side_style.SetSize( m_ncorners ); if( bDraw ) Draw(); }
// Test for intersection of sides // int CPolyLine::TestIntersection( CPolyLine * poly ) { if( !GetClosed() ) ASSERT(0); if( !poly->GetClosed() ) ASSERT(0); for( int ic=0; ic<GetNumContours(); ic++ ) { int istart = GetContourStart(ic); int iend = GetContourEnd(ic); for( int is=istart; is<=iend; is++ ) { int xi = GetX(is); int yi = GetY(is); int xf, yf; if( is < GetContourEnd(ic) ) { xf = GetX(is+1); yf = GetY(is+1); } else { xf = GetX(istart); yf = GetY(istart); } int style = GetSideStyle(is); for( int ic2=0; ic2<poly->GetNumContours(); ic2++ ) { int istart2 = poly->GetContourStart(ic2); int iend2 = poly->GetContourEnd(ic2); for( int is2=istart2; is2<=iend2; is2++ ) { int xi2 = poly->GetX(is2); int yi2 = poly->GetY(is2); int xf2, yf2; if( is2 < poly->GetContourEnd(ic2) ) { xf2 = poly->GetX(is2+1); yf2 = poly->GetY(is2+1); } else { xf2 = poly->GetX(istart2); yf2 = poly->GetY(istart2); } int style2 = poly->GetSideStyle(is2); // test for intersection between side and side2 } } } } return 0; }
void CPolyLine::MakeVisible( BOOL visible ) { if( m_dlist ) { int ns = m_ncorners-1; if( GetClosed() ) ns = m_ncorners; for( int is=0; is<ns; is++ ) m_dlist->Set_visible( dl_side[is], visible ); for( int ih=0; ih<m_nhatch; ih++ ) m_dlist->Set_visible( dl_hatch[ih], visible ); } }
// highlight side by drawing line over it // void CPolyLine::HighlightSide( int is ) { if( !m_dlist ) ASSERT(0); if( GetClosed() && is >= m_ncorners ) return; if( !GetClosed() && is >= (m_ncorners-1) ) return; int style; if( side_style[is] == CPolyLine::STRAIGHT ) style = DL_LINE; else if( side_style[is] == CPolyLine::ARC_CW ) style = DL_ARC_CW; else if( side_style[is] == CPolyLine::ARC_CCW ) style = DL_ARC_CCW; m_dlist->HighLight( style, m_dlist->Get_x( dl_side_sel[is] ), m_dlist->Get_y( dl_side_sel[is] ), m_dlist->Get_xf( dl_side_sel[is] ), m_dlist->Get_yf( dl_side_sel[is] ), m_dlist->Get_w( dl_side_sel[is]) ); }
// make a gpc_polygon for a closed polyline contour // approximates arcs with multiple straight-line segments // if icontour = -1, make polygon with all contours, // combining intersecting contours if possible // returns data on arcs in arc_array // int CPolyLine::MakeGpcPoly( int icontour, CArray<CArc> * arc_array ) { if( m_gpc_poly->num_contours ) FreeGpcPoly(); if( !GetClosed() && (icontour == (GetNumContours()-1) || icontour == -1)) return 1; // error // initialize m_gpc_poly m_gpc_poly->num_contours = 0; m_gpc_poly->hole = NULL; m_gpc_poly->contour = NULL; int n_arcs = 0; int first_contour = icontour; int last_contour = icontour; if( icontour == -1 ) { first_contour = 0; last_contour = GetNumContours() - 1; } if( arc_array ) arc_array->SetSize(0); int iarc = 0; for( int icont=first_contour; icont<=last_contour; icont++ ) { // make gpc_polygon for this contour gpc_polygon * gpc = new gpc_polygon; gpc->num_contours = 0; gpc->hole = NULL; gpc->contour = NULL; // first, calculate number of vertices in contour int n_vertices = 0; int ic_st = GetContourStart(icont); int ic_end = GetContourEnd(icont); for( int ic=ic_st; ic<=ic_end; ic++ ) { int style = side_style[ic]; int x1 = corner[ic].x; int y1 = corner[ic].y; int x2, y2; if( ic < ic_end ) { x2 = corner[ic+1].x; y2 = corner[ic+1].y; } else { x2 = corner[ic_st].x; y2 = corner[ic_st].y; } if( style == STRAIGHT ) n_vertices++; else { // style is ARC_CW or ARC_CCW int n; // number of steps for arcs n = (abs(x2-x1)+abs(y2-y1))/(CArc::MAX_STEP); n = max( n, CArc::MIN_STEPS ); // or at most 5 degrees of arc n_vertices += n; n_arcs++; } } // now create gcp_vertex_list for this contour gpc_vertex_list * g_v_list = new gpc_vertex_list; g_v_list->vertex = (gpc_vertex*)calloc( sizeof(gpc_vertex), n_vertices ); g_v_list->num_vertices = n_vertices; int ivtx = 0; for( int ic=ic_st; ic<=ic_end; ic++ ) { int style = side_style[ic]; int x1 = corner[ic].x; int y1 = corner[ic].y; int x2, y2; if( ic < ic_end ) { x2 = corner[ic+1].x; y2 = corner[ic+1].y; } else { x2 = corner[ic_st].x; y2 = corner[ic_st].y; } if( style == STRAIGHT ) { g_v_list->vertex[ivtx].x = x1; g_v_list->vertex[ivtx].y = y1; ivtx++; } else { // style is arc_cw or arc_ccw int n; // number of steps for arcs n = (abs(x2-x1)+abs(y2-y1))/(CArc::MAX_STEP); n = max( n, CArc::MIN_STEPS ); // or at most 5 degrees of arc double xo, yo, theta1, theta2, a, b; a = fabs( (double)(x1 - x2) ); b = fabs( (double)(y1 - y2) ); if( style == CPolyLine::ARC_CW ) { // clockwise arc (ie.quadrant of ellipse) int i=0, j=0; if( x2 > x1 && y2 > y1 ) { // first quadrant, draw second quadrant of ellipse xo = x2; yo = y1; theta1 = pi; theta2 = pi/2.0; } else if( x2 < x1 && y2 > y1 ) { // second quadrant, draw third quadrant of ellipse xo = x1; yo = y2; theta1 = 3.0*pi/2.0; theta2 = pi; } else if( x2 < x1 && y2 < y1 ) { // third quadrant, draw fourth quadrant of ellipse xo = x2; yo = y1; theta1 = 2.0*pi; theta2 = 3.0*pi/2.0; } else { xo = x1; // fourth quadrant, draw first quadrant of ellipse yo = y2; theta1 = pi/2.0; theta2 = 0.0; } } else { // counter-clockwise arc int i=0, j=0; if( x2 > x1 && y2 > y1 ) { xo = x1; // first quadrant, draw fourth quadrant of ellipse yo = y2; theta1 = 3.0*pi/2.0; theta2 = 2.0*pi; } else if( x2 < x1 && y2 > y1 ) { xo = x2; // second quadrant yo = y1; theta1 = 0.0; theta2 = pi/2.0; } else if( x2 < x1 && y2 < y1 ) { xo = x1; // third quadrant yo = y2; theta1 = pi/2.0; theta2 = pi; } else { xo = x2; // fourth quadrant yo = y1; theta1 = pi; theta2 = 3.0*pi/2.0; } } // now write steps for arc if( arc_array ) { arc_array->SetSize(iarc+1); (*arc_array)[iarc].style = style; (*arc_array)[iarc].n_steps = n; (*arc_array)[iarc].xi = x1; (*arc_array)[iarc].yi = y1; (*arc_array)[iarc].xf = x2; (*arc_array)[iarc].yf = y2; iarc++; } for( int is=0; is<n; is++ ) { double theta = theta1 + ((theta2-theta1)*(double)is)/n; double x = xo + a*cos(theta); double y = yo + b*sin(theta); if( is == 0 ) { x = x1; y = y1; } g_v_list->vertex[ivtx].x = x; g_v_list->vertex[ivtx].y = y; ivtx++; } } } if( n_vertices != ivtx ) ASSERT(0); // add vertex_list to gpc gpc_add_contour( gpc, g_v_list, 0 ); // now clip m_gpc_poly with gpc, put new poly into result gpc_polygon * result = new gpc_polygon; if( icontour == -1 && icont != 0 ) gpc_polygon_clip( GPC_DIFF, m_gpc_poly, gpc, result ); // hole else gpc_polygon_clip( GPC_UNION, m_gpc_poly, gpc, result ); // outside // now copy result to m_gpc_poly gpc_free_polygon( m_gpc_poly ); delete m_gpc_poly; m_gpc_poly = result; gpc_free_polygon( gpc ); delete gpc; free( g_v_list->vertex ); free( g_v_list ); } return 0; }
// test to see if a point is inside polyline contour // BOOL CPolyLine::TestPointInsideContour( int icont, int x, int y ) { if( icont >= GetNumContours() ) return FALSE; enum { MAXPTS = 100 }; if( !GetClosed() ) ASSERT(0); // define line passing through (x,y), with slope = 2/3; // get intersection points double xx[MAXPTS], yy[MAXPTS]; double slope = (double)2.0/3.0; double a = y - slope*x; int nloops = 0; int npts; // 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; 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[m_ncorners-1], &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[npts] = (int)x; yy[npts] = (int)y; npts++; ASSERT( npts<MAXPTS ); // overflow } if( ok == 2 ) { xx[npts] = (int)x2; yy[npts] = (int)y2; npts++; ASSERT( npts<MAXPTS ); // overflow } } nloops++; a += PCBU_PER_MIL/100; } while( npts%2 != 0 && nloops < 3 ); ASSERT( npts%2==0 ); // odd number of intersection points, error // count intersection points to right of (x,y), if odd (x,y) is inside polyline int ncount = 0; for( int ip=0; ip<npts; ip++ ) { if( xx[ip] == x && yy[ip] == y ) return FALSE; // (x,y) is on a side, call it outside else if( xx[ip] > x ) ncount++; } if( ncount%2 ) return TRUE; else return FALSE; }
// draw hatch lines // void CPolyLine::Hatch(CDL_job *pDL_job) { if( m_hatch == NO_HATCH ) { m_nhatch = 0; return; } if( m_dlist && GetClosed() ) { enum { MAXPTS = 100, MAXLINES = 1000 }; dl_hatch.SetSize( MAXLINES, MAXLINES ); int xx[MAXPTS], yy[MAXPTS]; // define range for hatch lines int min_x = corner[0].x; int max_x = corner[0].x; int min_y = corner[0].y; int max_y = corner[0].y; for( int ic=1; ic<m_ncorners; ic++ ) { if( corner[ic].x < min_x ) min_x = corner[ic].x; if( corner[ic].x > max_x ) max_x = corner[ic].x; if( corner[ic].y < min_y ) min_y = corner[ic].y; if( corner[ic].y > max_y ) max_y = corner[ic].y; } int slope_flag = 1 - 2*(m_layer%2); // 1 or -1 double slope = 0.707106*slope_flag; //slope=0; int spacing; if( m_hatch == DIAGONAL_EDGE ) spacing = 10*PCBU_PER_MIL; else spacing = 6*PCBU_PER_MIL; int max_a, min_a; if( slope_flag == 1 ) { max_a = (int)(max_y - slope*min_x); min_a = (int)(min_y - slope*max_x); } else { max_a = (int)(max_y - slope*max_x); min_a = (int)(min_y - slope*min_x); } min_a = (min_a/spacing)*spacing; int offset; if( m_layer < (LAY_TOP_COPPER+2) ) offset = 0; else if( m_layer < (LAY_TOP_COPPER+4) ) offset = spacing/2; else if( m_layer < (LAY_TOP_COPPER+6) ) offset = spacing/4; else if( m_layer < (LAY_TOP_COPPER+8) ) offset = 3*spacing/4; else if( m_layer < (LAY_TOP_COPPER+10) ) offset = 1*spacing/8; else if( m_layer < (LAY_TOP_COPPER+12) ) offset = 3*spacing/8; else if( m_layer < (LAY_TOP_COPPER+14) ) offset = 5*spacing/8; else if( m_layer < (LAY_TOP_COPPER+16) ) offset = 7*spacing/8; else ASSERT(0); min_a += offset; // now calculate and draw hatch lines int nc = m_ncorners; int nhatch = 0; // loop through hatch lines for( int a=min_a; a<max_a; a+=spacing ) { // get intersection points for this hatch line int nloops = 0; int npts; // make this a loop in case my homebrew hatching algorithm screws up do { npts = 0; int i_start_contour = 0; for( int ic=0; ic<nc; ic++ ) { double x, y, x2, y2; int ok; if( corner[ic].end_contour ) { ok = FindLineSegmentIntersection( a, slope, corner[ic].x, corner[ic].y, corner[i_start_contour].x, corner[i_start_contour].y, side_style[ic], &x, &y, &x2, &y2 ); i_start_contour = ic + 1; } else { ok = FindLineSegmentIntersection( a, slope, corner[ic].x, corner[ic].y, corner[ic+1].x, corner[ic+1].y, side_style[ic], &x, &y, &x2, &y2 ); } if( ok ) { xx[npts] = (int)x; yy[npts] = (int)y; npts++; ASSERT( npts<MAXPTS ); // overflow } if( ok == 2 ) { xx[npts] = (int)x2; yy[npts] = (int)y2; npts++; ASSERT( npts<MAXPTS ); // overflow } } nloops++; a += PCBU_PER_MIL/100; } while( npts%2 != 0 && nloops < 3 ); ASSERT( npts%2==0 ); // odd number of intersection points, error // sort points in order of descending x (if more than 2) if( npts>2 ) { for( int istart=0; istart<(npts-1); istart++ ) { int max_x = INT_MIN; int imax; for( int i=istart; i<npts; i++ ) { if( xx[i] > max_x ) { max_x = xx[i]; imax = i; } } int temp = xx[istart]; xx[istart] = xx[imax]; xx[imax] = temp; temp = yy[istart]; yy[istart] = yy[imax]; yy[imax] = temp; } } // draw lines int width = spacing/3; for( int ip=0; ip<npts; ip+=2 ) { id hatch_id = m_id; hatch_id.sst = ID_HATCH; hatch_id.ii = nhatch; int dx = xx[ip+1] - xx[ip]; const int edge_width = 20; if( m_hatch == DIAGONAL_FULL || abs(dx) < edge_width*2*NM_PER_MIL ) { dl_element * dl = m_dlist->Add( pDL_job, hatch_id, 0, m_layer, DL_LINE, 1, width, 0, 0, xx[ip], yy[ip], xx[ip+1], yy[ip+1], 0, 0 ); dl_hatch.SetAtGrow(nhatch, dl); nhatch++; } else { int dy = yy[ip+1] - yy[ip]; double slope = double(dy)/dx; if( dx > 0 ) dx = edge_width*NM_PER_MIL; else dx = -edge_width*NM_PER_MIL; int x1 = xx[ip] + dx; int x2 = xx[ip+1] - dx; int y1 = yy[ip] + dx*slope; int y2 = yy[ip+1] - dx*slope; dl_element * dl; dl = m_dlist->Add( pDL_job, hatch_id, 0, m_layer, DL_LINE, 1, width, 0, 0, xx[ip], yy[ip], x1, y1, 0, 0 ); dl_hatch.SetAtGrow(nhatch, dl); dl = m_dlist->Add( pDL_job, hatch_id, 0, m_layer, DL_LINE, 1, width, 0, 0, xx[ip+1], yy[ip+1], x2, y2, 0, 0 ); dl_hatch.SetAtGrow(nhatch+1, dl); nhatch += 2; } } } // end for m_nhatch = nhatch; dl_hatch.SetSize( m_nhatch ); } }
// start dragging corner to new position, make adjacent sides and hatching invisible // void CPolyLine::StartDraggingToMoveCorner( CDC * pDC, int ic, int x, int y, int crosshair ) { if( !m_dlist ) ASSERT(0); // see if corner is the first or last corner of an open contour int icont = GetContour( ic ); int istart = GetContourStart( icont ); int iend = GetContourEnd( icont ); if( !GetClosed() && icont == GetNumContours() - 1 && (ic == istart || ic == iend) ) { // yes int style, xi, yi, iside; if( ic == istart ) { // first corner iside = ic; xi = GetX( ic+1 ); yi = GetY( ic+1 ); style = GetSideStyle( iside ); // reverse arc since we are drawing from corner 1 to 0 if( style == CPolyLine::ARC_CW ) style = CPolyLine::ARC_CCW; else if( style == CPolyLine::ARC_CCW ) style = CPolyLine::ARC_CW; } else { // last corner iside = ic - 1; xi = GetX( ic-1 ); yi = GetY( ic-1); style = GetSideStyle( iside ); } m_dlist->StartDraggingArc( pDC, style, GetX(ic), GetY(ic), xi, yi, LAY_SELECTION, 1, crosshair ); m_dlist->CancelHighLight(); m_dlist->Set_visible( dl_side[iside], 0 ); for( int ih=0; ih<m_nhatch; ih++ ) m_dlist->Set_visible( dl_hatch[ih], 0 ); } else { // no // get indexes for preceding and following corners int pre_c, post_c; int poly_side_style1, poly_side_style2; int style1, style2; if( ic == istart ) { pre_c = iend; post_c = istart+1; poly_side_style1 = side_style[iend]; poly_side_style2 = side_style[istart]; } else if( ic == iend ) { // last side pre_c = ic-1; post_c = istart; poly_side_style1 = side_style[ic-1]; poly_side_style2 = side_style[ic]; } else { pre_c = ic-1; post_c = ic+1; poly_side_style1 = side_style[ic-1]; poly_side_style2 = side_style[ic]; } if( poly_side_style1 == STRAIGHT ) style1 = DSS_STRAIGHT; else if( poly_side_style1 == ARC_CW ) style1 = DSS_ARC_CW; else if( poly_side_style1 == ARC_CCW ) style1 = DSS_ARC_CCW; if( poly_side_style2 == STRAIGHT ) style2 = DSS_STRAIGHT; else if( poly_side_style2 == ARC_CW ) style2 = DSS_ARC_CW; else if( poly_side_style2 == ARC_CCW ) style2 = DSS_ARC_CCW; int xi = corner[pre_c].x; int yi = corner[pre_c].y; int xf = corner[post_c].x; int yf = corner[post_c].y; m_dlist->StartDraggingLineVertex( pDC, x, y, xi, yi, xf, yf, LAY_SELECTION, LAY_SELECTION, 1, 1, style1, style2, 0, 0, 0, 0, crosshair ); m_dlist->CancelHighLight(); m_dlist->Set_visible( dl_side[pre_c], 0 ); m_dlist->Set_visible( dl_side[ic], 0 ); for( int ih=0; ih<m_nhatch; ih++ ) m_dlist->Set_visible( dl_hatch[ih], 0 ); } }
void CPolyLine::Hatch() { m_HatchLines.clear(); if( m_hatchStyle == NO_HATCH || m_hatchPitch == 0 ) return; if( !GetClosed() ) // If not closed, the poly is beeing created and not finalised. Not not hatch return; // define range for hatch lines int min_x = m_CornersList[0].x; int max_x = m_CornersList[0].x; int min_y = m_CornersList[0].y; int max_y = m_CornersList[0].y; for( unsigned ic = 1; ic < m_CornersList.GetCornersCount(); ic++ ) { if( m_CornersList[ic].x < min_x ) min_x = m_CornersList[ic].x; if( m_CornersList[ic].x > max_x ) max_x = m_CornersList[ic].x; if( m_CornersList[ic].y < min_y ) min_y = m_CornersList[ic].y; if( m_CornersList[ic].y > max_y ) max_y = m_CornersList[ic].y; } // Calculate spacing between 2 hatch lines int spacing; if( m_hatchStyle == DIAGONAL_EDGE ) spacing = m_hatchPitch; else spacing = m_hatchPitch * 2; // set the "length" of hatch lines (the lenght on horizontal axis) double hatch_line_len = m_hatchPitch; // To have a better look, give a slope depending on the layer LAYER_NUM layer = GetLayer(); int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1 double slope = 0.707106 * slope_flag; // 45 degrees slope int max_a, min_a; if( slope_flag == 1 ) { max_a = KiROUND( max_y - slope * min_x ); min_a = KiROUND( min_y - slope * max_x ); } else { max_a = KiROUND( max_y - slope * max_x ); min_a = KiROUND( min_y - slope * min_x ); } min_a = (min_a / spacing) * spacing; // calculate an offset depending on layer number, // for a better look of hatches on a multilayer board int offset = (layer * 7) / 8; min_a += offset; // now calculate and draw hatch lines int nc = m_CornersList.GetCornersCount(); // loop through hatch lines #define MAXPTS 200 // Usually we store only few values per one hatch line // depending on the compexity of the zone outline static std::vector <wxPoint> pointbuffer; pointbuffer.clear(); pointbuffer.reserve( MAXPTS + 2 ); for( int a = min_a; a < max_a; a += spacing ) { // get intersection points for this hatch line // Note: because we should have an even number of intersections with the // current hatch line and the zone outline (a closed polygon, // or a set of closed polygons), if an odd count is found // we skip this line (should not occur) pointbuffer.clear(); int i_start_contour = 0; for( int ic = 0; ic<nc; ic++ ) { double x, y, x2, y2; int ok; if( m_CornersList[ic].end_contour || ( ic == (int) (m_CornersList.GetCornersCount() - 1) ) ) { ok = FindLineSegmentIntersection( a, slope, m_CornersList[ic].x, m_CornersList[ic].y, m_CornersList[i_start_contour].x, m_CornersList[i_start_contour].y, &x, &y, &x2, &y2 ); i_start_contour = ic + 1; } else { ok = FindLineSegmentIntersection( a, slope, m_CornersList[ic].x, m_CornersList[ic].y, m_CornersList[ic + 1].x, m_CornersList[ic + 1].y, &x, &y, &x2, &y2 ); } if( ok ) { wxPoint point( KiROUND( x ), KiROUND( y ) ); pointbuffer.push_back( point ); } if( ok == 2 ) { wxPoint point( KiROUND( x2 ), KiROUND( y2 ) ); pointbuffer.push_back( point ); } if( pointbuffer.size() >= MAXPTS ) // overflow { wxASSERT( 0 ); break; } } // ensure we have found an even intersection points count // because intersections are the ends of segments // inside the polygon(s) and a segment has 2 ends. // if not, this is a strange case (a bug ?) so skip this hatch if( pointbuffer.size() % 2 != 0 ) continue; // sort points in order of descending x (if more than 2) to // ensure the starting point and the ending point of the same segment // are stored one just after the other. if( pointbuffer.size() > 2 ) sort( pointbuffer.begin(), pointbuffer.end(), sort_ends_by_descending_X ); // creates lines or short segments inside the complex polygon for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 ) { double dx = pointbuffer[ip + 1].x - pointbuffer[ip].x; // Push only one line for diagonal hatch, // or for small lines < twice the line len // else push 2 small lines if( m_hatchStyle == DIAGONAL_FULL || fabs( dx ) < 2 * hatch_line_len ) { m_HatchLines.push_back( CSegment( pointbuffer[ip], pointbuffer[ip + 1] ) ); } else { double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y; double slope = dy / dx; if( dx > 0 ) dx = hatch_line_len; else dx = -hatch_line_len; double x1 = pointbuffer[ip].x + dx; double x2 = pointbuffer[ip + 1].x - dx; double y1 = pointbuffer[ip].y + dx * slope; double y2 = pointbuffer[ip + 1].y - dx * slope; m_HatchLines.push_back( CSegment( pointbuffer[ip].x, pointbuffer[ip].y, KiROUND( x1 ), KiROUND( y1 ) ) ); m_HatchLines.push_back( CSegment( pointbuffer[ip + 1].x, pointbuffer[ip + 1].y, KiROUND( x2 ), KiROUND( y2 ) ) ); } } } }
int inventory_visible(){ return !GetClosed(); }
int inventory_accessible(){ return !GetClosed(); }
int GetOpen(){ return !(Closed); if(GetClosed()) return 0; else return 1; }