コード例 #1
0
ファイル: xstrans.C プロジェクト: Kevin-M-Smith/SPRNT
int xs_trans::_cmethod(double t) {
  int cntr, jj;
  long int xs, ys, xp, yp;
  double angp, angs;
  
  _rxx[0] = _xxin[0];
  _ryy[0] = _yyin[0];
  
  xs = _xxin[0];
  ys = _yyin[0];
  cntr = 1;
  
  xp = _xxin[1];
  yp = _yyin[1];
  angp = _angle(xp,yp,xs,ys);
  
  for (jj=2; jj<_num_pts; jj++) {
    angs = _angle(_xxin[jj],_yyin[jj], xs, ys);
    
    if ( fabs( (angs-angp) ) < t ) {
      /* skip */
      xp = _xxin[jj];
      yp = _yyin[jj];
      
    } else {
      /* store */
      _rxx[cntr]   = xp;
      _ryy[cntr++] = yp;
      
      xs = xp;
      ys = yp;
      xp = _xxin[jj];
      yp = _yyin[jj];
      
      angp = _angle(xp, yp, xs, ys);
      
    }
  }
  /* always keep the last one */
  _rxx[cntr] = _xxin[_num_pts-1];
  _ryy[cntr++] = _yyin[_num_pts-1];

  return cntr;   
}
コード例 #2
0
/*
 * Convolve one subpath with a convex pen.  The result is
 * a closed path.
 */
static void
_twin_subpath_convolve (twin_path_t	*path,
			twin_path_t	*stroke,
			twin_path_t	*pen)
{
    twin_spoint_t   *sp   = stroke->points;
    twin_spoint_t   *pp   = pen->points;
    int		    ns    = stroke->npoints;
    int		    np    = pen->npoints;
    twin_spoint_t   *sp0  = &sp[0];
    twin_spoint_t   *sp1  = &sp[1];
    int		    start = _twin_path_leftpoint (pen, sp0, sp1);
    twin_spoint_t   *spn1 = &sp[ns-1];
    twin_spoint_t   *spn2 = &sp[ns-2];
    int		    ret   = _twin_path_leftpoint (pen, spn1, spn2);
    int		    p;
    int		    s;
    int		    starget;
    int		    ptarget;
    int		    inc;
    int		    first;

    DBGOUT ("convolve stroke:\n");
    for (s = 0; s < ns; s++)
	DBGOUT ("\ts%02d: %9.4f, %9.4f\n", s, F(sp[s].x), F(sp[s].y));
    DBGOUT ("convolve pen:\n");
    for (p = 0; p < np; p++)
	DBGOUT ("\tp%02d: %9.4f, %9.4f\n", p, F(pp[p].x), F(pp[p].y));
    
    s = 0;
    p = start;
    DBGOUT ("start:  ");
    DBGOUT ("s%02d (%9.4f, %9.4f), p%02d (%9.4f, %9.4f): %9.4f, %9.4f\n",
	    s, F(sp[s].x), F(sp[s].y),
	    p, F(pp[p].x), F(pp[p].y),
	    F(sp[s].x + pp[p].x), F(sp[s].y + pp[p].y));
    _twin_path_smove (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
    first = path->npoints - 1;
    
    /* step along the path first */
    inc = 1;
    starget = ns-1;
    ptarget = ret;
    for (;;)
    {
	/*
	 * Convolve the edges
	 */
	do
	{
	    int	sn = s + inc;
	    int	pn = (p == np - 1) ? 0 : p + 1;
	    int	pm = (p == 0) ? np - 1 : p - 1;
    
	    /*
	     * step along pen (forwards or backwards) or stroke as appropriate
	     */
	     
	    DBGOUT ("\tangles: stroke %9.4f +pen %9.4f -pen %9.4f\n",
		    _angle (&sp[s], &sp[sn]),
		    _angle (&pp[p], &pp[pn]),
		    _angle (&pp[pm], &pp[p]));
	    if (_around_order (&sp[s],&sp[sn],&pp[p],&pp[pn]) > 0)
	    {
		DBGOUT ("+pen:   ");
		p = pn;
	    }
	    else if (_around_order (&sp[s],&sp[sn],&pp[pm],&pp[p]) < 0)
	    {
		DBGOUT ("-pen:   ");
		p = pm;
	    }
	    else
	    {
		DBGOUT ("stroke: ");
		s = sn;
	    }
	    DBGOUT ("s%02d (%9.4f, %9.4f), p%02d (%9.4f, %9.4f): %9.4f, %9.4f\n",
		    s, F(sp[s].x), F(sp[s].y),
		    p, F(pp[p].x), F(pp[p].y),
		    F(sp[s].x + pp[p].x), F(sp[s].y + pp[p].y));
	    _twin_path_sdraw (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
	} while (s != starget);
	
	/*
	 * Finish this edge
	 */
	
	/* draw a cap */
	switch (path->state.cap_style) {
	    int		pm;
	case TwinCapProjecting:
	    /*
	     * This draws a rough projecting cap using the
	     * pen.
	     *
	     * First, project the line forward one pen radius
	     * by finding the pen location halfway between the
	     * two normals.
	     *
	     * Then, just add that to the normals themselves to
	     * find the corners of the projecting cap.  
	     * 
	     * The result may have significant error, so overwrite
	     * the existing corners with the new coordinates to
	     * avoid a kink.
	     */
	    if (p <= ptarget)
		pm = (ptarget + p) >> 1;
	    else
	    {
		pm = (ptarget + np + p) >> 1;
		if (pm >= np) pm -= np;
	    }
	    
	    /* replace last point with corner of cap */
	    path->npoints--;
	    _twin_path_sdraw (path,
			      sp[s].x + pp[pm].x + pp[p].x,
			      sp[s].y + pp[pm].y + pp[p].y);
	    p = ptarget;
	    if (inc == 1)
	    {
		/* start next line at cap corner */
		_twin_path_sdraw (path,
				  sp[s].x + pp[pm].x + pp[p].x,
				  sp[s].y + pp[pm].y + pp[p].y);
	    }
	    else
	    {
		/* overwrite initial point */
		path->points[first].x = sp[s].x + pp[pm].x + pp[p].x;
		path->points[first].y = sp[s].y + pp[pm].y + pp[p].y;
	    }
	    break;
	case TwinCapButt:
	    p = ptarget-1;
	    /* fall through … */
	case TwinCapRound:
	    while (p != ptarget)
	    {
		if (++p == np) p = 0;
		DBGOUT("cap:    ");
		DBGOUT ("s%02d (%9.4f, %9.4f), p%02d (%9.4f, %9.4f): %9.4f, %9.4f\n",
			s, F(sp[s].x), F(sp[s].y),
			p, F(pp[p].x), F(pp[p].y),
			F(sp[s].x + pp[p].x), F(sp[s].y + pp[p].y));
		_twin_path_sdraw (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
	    }
	    break;
	}
	
	if (inc == -1)
	    break;
	
	/* reach the end of the path?  Go back the other way now */
	inc = -1;
	ptarget = start;
	starget = 0;
    }