void CPolyLine::RemoveContour( int icont )
/******************************************/

/**
 * Function RemoveContour
 * @param icont = contour number to remove
 * remove a contour only if there is more than 1 contour
 */
{
    UnHatch();
    int istart  = GetContourStart( icont );
    int iend    = GetContourEnd( icont );

    int polycount = GetContoursCount();

    if( icont == 0 && polycount == 1 )
    {
        // remove the only contour
        wxASSERT( 0 );
    }
    else
    {
        // remove closed contour
        for( int ic = iend; ic>=istart; ic-- )
        {
            m_CornersList.DeleteCorner( ic );
        }
    }

    Hatch();
}
// move corner of polyline
//
void CPolyLine::MoveCorner( int ic, int x, int y )
{
    UnHatch();
    m_CornersList[ic].x = x;
    m_CornersList[ic].y = y;
    Hatch();
}
void CPolyLine::MoveOrigin( int x_off, int y_off )
{
    UnHatch();

    for( int ic = 0; ic < GetCornersCount(); ic++ )
    {
        SetX( ic, GetX( ic ) + x_off );
        SetY( ic, GetY( ic ) + y_off );
    }

    Hatch();
}
/**
 * Function InsertCorner
 * insert a new corner between two existing corners
 * @param ic = index for the insertion point: the corner is inserted AFTER ic
 * @param x, y = coordinates corner to insert
 */
void CPolyLine::InsertCorner( int ic, int x, int y )
{
    UnHatch();

    if( (unsigned) (ic) >= m_CornersList.GetCornersCount() )
    {
        m_CornersList.Append( CPolyPt( x, y ) );
    }
    else
    {
        m_CornersList.InsertCorner(ic, CPolyPt( x, y ) );
    }

    if( (unsigned) (ic + 1) < m_CornersList.GetCornersCount() )
    {
        if( m_CornersList[ic].end_contour )
        {
            m_CornersList[ic + 1].end_contour   = true;
            m_CornersList[ic].end_contour       = false;
        }
    }

    Hatch();
}
Exemple #5
0
// draw polyline by adding all graphics to display list
// if side style is ARC_CW or ARC_CCW but endpoints are not angled,
// convert to STRAIGHT
//
void CPolyLine::Draw(  CDisplayList * dl )
{
	int i_start_contour = 0;

	// first, undraw if necessary
	if( bDrawn )
		Undraw();

	// use new display list if provided
	if( dl )
		m_dlist = dl;

	if( m_dlist )
	{
		// set up CArrays
		dl_side.SetSize( m_ncorners );
		if( m_sel_box )
		{
			dl_side_sel.SetSize( m_ncorners );
			dl_corner_sel.SetSize( m_ncorners );
		}
		else
		{
			dl_side_sel.RemoveAll();
			dl_corner_sel.RemoveAll();
		}

		CDL_job *pDL_job;

		if (m_layer >= LAY_TOP_COPPER)
		{
			CDL_job_copper_area *pDL_job_ca = new CDL_job_copper_area(m_dlist, this);

			m_dl_job = pDL_job = pDL_job_ca;
		}
		else
		{
			pDL_job = m_dlist->GetJob_traces(m_layer);

            m_dl_job = NULL;
		}

		// now draw elements
		for( int ic=0; ic<m_ncorners; ic++ )
		{
			m_id.ii = ic;
			int xi = corner[ic].x;
			int yi = corner[ic].y;
			int xf, yf;
			if( corner[ic].end_contour == FALSE && ic < m_ncorners-1 )
			{
				xf = corner[ic+1].x;
				yf = corner[ic+1].y;
			}
			else
			{
				xf = corner[i_start_contour].x;
				yf = corner[i_start_contour].y;
				i_start_contour = ic+1;
			}
			// draw
			if( m_sel_box )
			{
				m_id.sst = ID_SEL_CORNER;
				dl_corner_sel[ic] = m_dlist->AddSelector( m_id, m_ptr, m_layer, DL_HOLLOW_RECT,
					1, 0, 0, xi-m_sel_box, yi-m_sel_box,
					xi+m_sel_box, yi+m_sel_box, 0, 0 );
			}
			if( ic<(m_ncorners-1) || corner[ic].end_contour )
			{
				// draw side
				if( xi == xf || yi == yf )
				{
					// if endpoints not angled, make side STRAIGHT
					side_style[ic] = STRAIGHT;
				}

				int g_type = DL_LINE;
				if( side_style[ic] == STRAIGHT )
					g_type = DL_LINE;
				else if( side_style[ic] == ARC_CW )
					g_type = DL_ARC_CW;
				else if( side_style[ic] == ARC_CCW )
					g_type = DL_ARC_CCW;

				m_id.sst = ID_SIDE;

				int dx = xf - xi;
				int dy = yf - yi;

#if 0 // BAF attempt to move borders in by w [
				int w = 10 * PCBU_PER_MIL;

				if (abs(dx) == 0)
				{
					// Vertical
					if (dy<0) w = -w;
					dl_side[ic] = m_dlist->Add( pDL_job, m_id, m_ptr, m_layer, g_type, 1, m_w+5*PCBU_PER_MIL, 0, 0, xi+w, yi, xf+w, yf, 0, 0 );
				}
				else if (abs(dy) == 0)
				{
					if (dx<0) w = -w;
					dl_side[ic] = m_dlist->Add( pDL_job, m_id, m_ptr, m_layer, g_type, 1, m_w+5*PCBU_PER_MIL, 0, 0, xi, yi-w, xf, yf-w, 0, 0 );
				}
				else
				{
					double s, l;

					if (abs(dy) > abs(dx))
					{
						s = double(dx)/dy;
						l = double(w) / sqrt(1 + s*s);
						if (dy<0) l = -l;

						dl_side[ic] = m_dlist->Add( pDL_job, m_id, m_ptr, m_layer, g_type, 1, m_w+5*PCBU_PER_MIL, 0, 0, xi+l, yi-s*l, xf+l, yf-s*l, 0, 0 );
					}
					else
					{
						s = double(dy)/dx;
						l = double(w) / sqrt(1 + s*s);
						if (dx<0) l = -l;

						dl_side[ic] = m_dlist->Add( pDL_job, m_id, m_ptr, m_layer, g_type, 1, m_w+5*PCBU_PER_MIL, 0, 0, xi+s*l, yi-l, xf+s*l, yf-l, 0, 0 );
					}
				}
#endif // ]

				dl_side[ic] = m_dlist->Add( pDL_job, m_id, m_ptr, m_layer, g_type, 1, m_w+0*PCBU_PER_MIL, 0, 0, xi, yi, xf, yf, 0, 0 );

				if( m_sel_box )
				{
					m_id.sst = ID_SEL_SIDE;
					dl_side_sel[ic] = m_dlist->AddSelector( m_id, m_ptr, m_layer, g_type, 1, m_w, 0, xi, yi, xf, yf, 0, 0 );
				}
			}
		}

		if( m_hatch )
			Hatch(pDL_job);

        m_dlist->Add(pDL_job, m_layer);
	}
	bDrawn = TRUE;
}
Exemple #6
0
void PieSlice (Scene& scene,
	       float x, float y, float r, float a, float e, 
	       float dist, float dx, float dy, int mode)
//
//  Hatches or fills a circular arc (sector) of radius 'r'
//  centered at (x,y) with a start angle 'a' and end angle 'e'. 
//  The operation is controlled by the mode flags:
//
//	0	To draw a sector which is hatched with 
//		parallel lines using the current linestyle
//		and color. The direction of the hatching lines
//		is given by the direction (dx,dy). If the norm
//		of the direction vector is zero then horizontal
//		hatching lines are drawn, that means dx=1,dy=0
//		is assumed. The distance between the hatching
//		lines is given by 'dist'. The outline of the
//		sector is not automatically drawn (see below) !
//
//	Fill	To draw a sector which is uniformly filled with
//		the current drawing color. In this case the 
//		informations for the hatching lines are ignored.
//
//	Outline The polygonal will be hatched and its outline
//		will be drawn using the current drawing color.
//
//  If ommitted the default values dx = 1, dy = 1 and mode = Outline
//  are assumed. This routine is the basis for drawing pieslice 
//  diagrams.
//
{ 
    // The circle is approximated by a nsegs-polygonal
    int nsegs = 50;

    double cx,cy,ex,ey,cosine,sine,delta;
    double *vx,*vy=0;
    short i,k,n,fill,outline;
    long color;

    // current drawing color
    color = scene.linecolor;

    // the fill flag
    fill = mode & Fill;

    // the outline flag
    outline = mode & Outline;

    // storage for polygonal vertices
    n = nsegs+1;
    if ( !(vx = new double[n]) ||
         !(vy = new double[n]) ) Matpack.Error(Mat::UnspecifiedError,"PieSlice: out of memory");
    
    // convert circle to polygonal 
    a = DegToRad(a);
    e = DegToRad(e);
    delta = (e - a) / (nsegs - 1.0);
    cosine = cos(delta);
    sine   = sin(delta);
    vx[0] = x;
    vy[0] = y;
    vx[1] = cx = x + r * cos(a);
    vy[1] = cy = y + r * sin(a);
    for (k = 2, i = 1; i < nsegs; i++) {
	ex = cx - x;
	ey = cy - y;
	vx[k] = cx = x + ex * cosine - ey * sine;
	vy[k] = cy = y + ex * sine + ey * cosine;
	k++; 
    }

    // fill or hatch the polygonal
    if (fill)
	scene.Polygon(n,vx,vy,color,Fill|outline);
    else
	Hatch(scene,n,vx,vy,dist,dx,dy,outline);

    // free auxilliary storage
    delete[] vy;
    delete[] vx;
}