Ejemplo n.º 1
0
 DOMNode* Workspace<EncodingT>::saveXML(DOMDocument* xml_doc) const
 {
     DOMElement* xml_wrks    = NULL;
     DOMNode*    xml_comment = NULL;
     DOMText*    xml_text    = NULL;
     try 
     {
         xml_wrks = xml_doc->createElement( AX("Workspace") );
         xml_wrks->setAttribute( AX("Name"), CX(m_name) );
         xml_wrks->setAttribute( AX("Author"), CX(m_author) );
         xml_wrks->setAttribute( AX("Brief"), CX(m_brief) );
         xml_wrks->setAttribute( AX("Version"), CX(m_version) );
         xml_wrks->setAttribute( AX("Type"), (m_type==WRK_FILE)?AX("File"):AX("Project") );
         xml_wrks->setAttribute( AX("Option"), AX(ToString::parse(m_option)));
         if (hasComment()) 
         {
             xml_comment = xml_doc->createElement( AX("Comments") );
             xml_wrks->appendChild(xml_comment);
             xml_text = xml_doc->createTextNode( CX(m_comment) );
             xml_comment->appendChild(xml_text);
         }
         for (const_file_iterator ite = beginFiles(); ite != endFiles(); ++ite)
         {
             xml_wrks->appendChild(ite->saveXML(xml_doc));
         }
         m_logger->debug("Workspace::saveXML() : XML workspace saved");
     } 
     catch ( const DOMException& e ) 
     {
         m_logger->fatalStream() << "Workspace::saveXML() : XML workspace save error: " 
                                 << A(e.getMessage());
         //throw e;
     }
     return xml_wrks;
 }
Ejemplo n.º 2
0
static void write_debug()
{
  char tmpout[150] = "";

  simple_snprintf(tmpout, sizeof tmpout, "* Last 3 contexts: %s/%d [%s], %s/%d [%s], %s/%d [%s]",
                                  CX(cx_ptr - 2), CX(cx_ptr - 1), CX(cx_ptr));
  putlog(LOG_MISC, "*", "%s (Paste to bryan)", tmpout);
  printf("%s\n", tmpout);
}
Ejemplo n.º 3
0
/*! \brief

<pre>
    Purpose
    =======

    SCSUM1 takes the sum of the absolute values of a complex
    vector and returns a single precision result.

    Based on SCASUM from the Level 1 BLAS.
    The change is to use the 'genuine' absolute value.

    Contributed by Nick Higham for use with CLACON.

    Arguments
    =========

    N       (input) INT
            The number of elements in the vector CX.

    CX      (input) COMPLEX array, dimension (N)
            The vector whose elements will be summed.

    INCX    (input) INT
            The spacing between successive values of CX.  INCX > 0.

    =====================================================================
</pre>
*/
double scsum1_(int *n, complex *cx, int *incx)
{
    /* System generated locals */
    int i__1, i__2;
    float ret_val;
    /* Builtin functions */
    double c_abs(complex *);
    /* Local variables */
    static int i, nincx;
    static float stemp;


#define CX(I) cx[(I)-1]


    ret_val = 0.f;
    stemp = 0.f;
    if (*n <= 0) {
        return ret_val;
    }
    if (*incx == 1) {
        goto L20;
    }

/*     CODE FOR INCREMENT NOT EQUAL TO 1 */

    nincx = *n * *incx;
    i__1 = nincx;
    i__2 = *incx;
    for (i = 1; *incx < 0 ? i >= nincx : i <= nincx; i += *incx) {

/*        NEXT LINE MODIFIED. */

        stemp += c_abs(&CX(i));
/* L10: */
    }
    ret_val = stemp;
    return ret_val;

/*     CODE FOR INCREMENT EQUAL TO 1 */

L20:
    i__2 = *n;
    for (i = 1; i <= *n; ++i) {

/*        NEXT LINE MODIFIED. */

        stemp += c_abs(&CX(i));
/* L30: */
    }
    ret_val = stemp;
    return ret_val;

/*     End of SCSUM1 */

} /* scsum1_ */
Ejemplo n.º 4
0
/*! \brief

 <pre>
    Purpose   
    =======   

    DZSUM1 takes the sum of the absolute values of a complex   
    vector and returns a double precision result.   

    Based on DZASUM from the Level 1 BLAS.   
    The change is to use the 'genuine' absolute value.   

    Contributed by Nick Higham for use with ZLACON.   

    Arguments   
    =========   

    N       (input) INT   
            The number of elements in the vector CX.   

    CX      (input) COMPLEX*16 array, dimension (N)   
            The vector whose elements will be summed.   

    INCX    (input) INT   
            The spacing between successive values of CX.  INCX > 0.   

    ===================================================================== 
</pre>
*/  
double dzsum1_slu(int *n, doublecomplex *cx, int *incx)
{

    /* Builtin functions */
    double z_abs(doublecomplex *);
    
    /* Local variables */
    int i, nincx;
    double stemp;


#define CX(I) cx[(I)-1]

    stemp = 0.;
    if (*n <= 0) {
	return stemp;
    }
    if (*incx == 1) {
	goto L20;
    }

    /*     CODE FOR INCREMENT NOT EQUAL TO 1 */

    nincx = *n * *incx;
    for (i = 1; *incx < 0 ? i >= nincx : i <= nincx; i += *incx) {

	/*        NEXT LINE MODIFIED. */

	stemp += z_abs(&CX(i));
/* L10: */
    }
    
    return stemp;

    /*     CODE FOR INCREMENT EQUAL TO 1 */

L20:
    for (i = 1; i <= *n; ++i) {

	/*        NEXT LINE MODIFIED. */

	stemp += z_abs(&CX(i));
/* L30: */
    }
    
    return stemp;

    /*     End of DZSUM1 */

} /* dzsum1_slu */
Ejemplo n.º 5
0
Archivo: matrix.c Proyecto: cran/kyotil
void get_sub_matrix(int* ix,int* jx,const char* _major_x,int nrx,int ncx,double* x,const char* _major_y,int nry,int ncy,double* y)
{
	int row_major_x = ((int)*_major_x == (int)'r') || ((int)*_major_x == (int)'R');	
	int row_major_y = ((int)*_major_y == (int)'r') || ((int)*_major_y == (int)'R');	
		
	if(!row_major_x && !row_major_y){  
		for(int i = 0;i < nry;i++){
			int p = (ix ? ix[i] : i);
			for(int j = 0;j < ncy;j++){
				int q = (jx ? jx[j] : j);
				y[CX(i,j,nry)] = x[CX(p,q,nrx)]; 
			}
		}
		return;
	}
	
	if(!row_major_x && row_major_y){  
		for(int i = 0;i < nry;i++){
			int p = (ix ? ix[i] : i);
			for(int j = 0;j < ncy;j++){
				int q = (jx ? jx[j] : j);
				y[RX(i,j,ncy)] = x[CX(p,q,nrx)]; 
			}
		}	
		return;
	}
	
	if(row_major_x && row_major_y){  
		for(int i = 0;i < nry;i++){
			int p = (ix ? ix[i] : i);
			for(int j = 0;j < ncy;j++){
				int q = (jx ? jx[j] : j);
				y[RX(i,j,ncy)] = x[RX(p,q,ncx)]; 
			}
		}	
		return;
	}

	if(row_major_x && !row_major_y){  
		for(int i = 0;i < nry;i++){
			int p = (ix ? ix[i] : i);
			for(int j = 0;j < ncy;j++){
				int q = (jx ? jx[j] : j);
				y[CX(i,j,nry)] = x[RX(p,q,ncx)]; 
			}
		}	
		return;
	}	
}
Ejemplo n.º 6
0
Archivo: map.cpp Proyecto: f3yagi/mysrc
void MoveMap(Map *map)
{
    Object *o = TO_OBJECT(GetPlayer());
    float x = CX(o);
    float y = CY(o);
    float width  = (float)ENGINE_WIDTH;
    float height = (float)ENGINE_HEIGTH;
    
    if (x + width / 2.0f > map->width * BLOCK_WIDTH) {
        map->x = map->width * BLOCK_WIDTH - width;
    } 
    if (x - width / 2.0f >= 0 &&
        x + width / 2.0f < map->width * BLOCK_WIDTH) {
        map->x = x - width / 2.0f;
    }
/*    
    if (y + height / 2.0f > map->height * BLOCK_HEIGHT) {
        map->y = map->height * BLOCK_HEIGHT - height;
    }
    if (y - height / 2.0f >= 0 &&
        y + height / 2.0f < map->height * BLOCK_HEIGHT) {
        map->y = y - height / 2.0f;
    }
*/    
}    
Ejemplo n.º 7
0
Archivo: matrix.c Proyecto: cran/kyotil
// x = _{nrx,ncx} in column-major order
// y = rep-cbind(x)
// exactly one of times,each > 0, the other is 0
// times is integer >= 0
// each is integer >= 0
// each takes precedence
// vec_each is length ncx takes precedence over each
void rcbind(double* _x,int nrx,int ncx,int times,int each,int* vec_each,double* _y){

	double* x = _x;
	double* y = _y;
		
	if(vec_each){
		for(int j = 0;j < ncx;j++){
			int each_j = vec_each[j];
			for(int i = 0;i < nrx;i++){
				for(int k = 0;k < each_j;k++){
					*y = x[CX(i,j,nrx)];
					y++;
				}
			}
		}
		return;
	}else if(each > 0){
		for(int j = 0;j < ncx;j++){
			for(int k = 0;k < each;k++){
				memcpy(y,x,nrx*sizeof(double));
				y+=nrx;
			}
			x += nrx;
		}
		return;
	}
	if(times > 0){
		int size_x = nrx * ncx;
		for(int k = 0;k < times;k++){
			memcpy(y,x,size_x*sizeof(double));
			y+=size_x;
		}
	}
	return;
}
Ejemplo n.º 8
0
Archivo: matrix.c Proyecto: cran/kyotil
// x = _{nrx,ncx} in column-major order
// y = rep-cbind(x)
// exactly one of times,each > 0, the other is 0
// times is integer >= 0
// each is integer >= 0
// each takes precedence
// vec_each is length nrx, takes precedence over each 
// y = rep-rbind(x) 
void rrbind(double* _x,int nrx,int ncx,int times,int _each,int* vec_each,double* _y){

	double* x = _x;
	double* y = _y;
	
	if((_each > 0) || vec_each){
		for(int j = 0;j < ncx;j++){
			for(int i = 0;i < nrx;i++){
				int each = vec_each ? vec_each[i] : _each;
				int ix = CX(i,j,nrx);
				for(int k = 0;k < each;k++){
					*y = x[ix]; // with nesting order i(j(k)) we fill out y in column order automatically 
					y++;
				}
			}
		}
		return;
	}
	
	if(times > 0){
		for(int j = 0;j < ncx;j++){
			for(int k = 0;k < times;k++){
				memcpy(y,x,nrx*sizeof(double));
				y+=nrx;
			}
			x += nrx;
		}
	}
	return;		
}
Ejemplo n.º 9
0
void on_paint( object painter ) {
   int point, ix, iy;
   mapping sp;

   sp = query_spots();

   foreach( point : sp ) {
      if( CX(point) > environment()->query_map_xdim() ||
         CY(point) > environment()->query_map_ydim() ) {
         remove_spot(point);
         continue;
      }

      painter->paint( CX(point), CY(point), '*', query_active()?11:8, LAYER_TERRAIN );
   }
}
Ejemplo n.º 10
0
/** Draw the exit. This adds the capability of drawing a closed (+) door.
 */
void on_paint( object painter ) {
   int p;
   mapping draw_shape = MCALL(exit_shape());

   if( !draw_shape ) return;
   foreach( p : draw_shape )
      painter->paint( CX(p)-4096, CY(p)-4096, query_dir()=="up"?'<':'>', 0x0F, LAYER_ROUGH );
}
Ejemplo n.º 11
0
int check_direction( int dir ) {
   int pos, tile;

   if( !dir ) {
      msg("You have to specify a direction when building a mine (i.e. 'build mine to the north').");
      return -1;
   }

   set_direction(SINVERT_C(dir));

   // Multiply up.
   dir = SMAKE_C(SCX(dir)*5, SCY(dir)*3, 0);
   pos = OFFSET_C(this_player()->query_coord(), dir);

   // Snap to grid
   pos = MAKE_C(((CX(pos)-1) / 5) * 5 + 1, ((CY(pos)-1) / 3) * 3 + 1, 0);
   // Now check to see if the tiletype is valid. Query the center of the tile
   // to make life a bit easier.
   tile = environment(this_player())->get_tiletype(CX(pos)+2, CY(pos)+1);
   if( !tile ) {
      msg("You can't build off the edge of the map.");
      return -1;
   }
   tile -= '0'; // get_tiletype uses the zbuffer, which offsets by '0' ...

   if( tile != LAYER_MOUNTAIN ) {
      //debug("tile=="+as_string(tile)+", pos = "+MAKE_CSTR(pos));
      msg( "Mines must be built against a mountain face. Find a mountainous place." );
      return -1;
   }

   // Offset horizontally a bit to make the entrance stick out...
   if( SCX(dir) )
      pos = OFFSET_C(pos, SMAKE_C(-SCX(dir) / 5,0,0));

   // If facing south, adjust to find the entrance.
   // The mountain tiles have funny patterns, and this helps
   // to compensate.
   if( query_direction() == SMAKE_C(0,1,0) ) {
      pos = MAKE_C(CX(pos), CY(pos)-1, CZ(pos) );
      while( environment(this_player())->get_tiletype(CX(pos)+2, CY(pos)+3) == '0' + LAYER_MOUNTAIN ) {
         pos = MAKE_C(CX(pos),CY(pos)+1,CZ(pos));
      }
   }
   // This is a north-facing version to snug the mine up as close as it can go.
   if( query_direction() == SMAKE_C(0,-1,0) ) {
      pos = MAKE_C(CX(pos), CY(pos)-1, CZ(pos) );
      while( environment(this_player())->get_tiletype(CX(pos)+2, CY(pos)) != '0' + LAYER_MOUNTAIN ) {
         pos = MAKE_C(CX(pos),CY(pos)+1,CZ(pos));
      }
   }
   set_coord( pos );

   return 0;
}
Ejemplo n.º 12
0
Archivo: matrix.c Proyecto: cran/kyotil
// x in column major order
void print_matrix(int m,int n,double* x){
    if(!x) return;
//    double (*x)[n] = (double (*)[n])_x;
    for(int i = 0;i < m;i++){
        for(int j = 0;j < n;j++)
			Rprintf("%+.4e ",x[CX(i,j,m)]);
        Rprintf("\n");
    } 
}
Ejemplo n.º 13
0
void MouseInt (struct rminfo *prmi)
{
   memset (&sregs, 0, sizeof (sregs));
   AX (regs) = 0x0300;                    // DPMI: simulate interrupt
   BX (regs) = MOUSE_INT;
   CX (regs) = 0;
   DI (regs) = FP_OFF (prmi);
   sregs.es = FP_SEG (prmi);
   int386x( DPMI_INT, &regs, &regs, &sregs );
}
Ejemplo n.º 14
0
void on_map_paint( object painter ) {
   int point;
   mapping wallmap;

   wallmap = query_spots();

   foreach( point : wallmap ) {
      painter->paint_shape( CX(point), CY(point), ">--->\n>--->\n>--->", 0x70, LAYER_TERRAIN );
   }
}
Ejemplo n.º 15
0
void on_map_paint( object painter ) {
   int ipos;

   foreach( ipos : query_spots() ) {
      painter->paint( query_x() + CX(ipos),
         query_y() + CY(ipos),
         '#',
         0x03,
         LAYER_WALL );
   }
}
Ejemplo n.º 16
0
void Demos::CK_logo(Adafruit_SSD1306& d)
{
	#define K 1024  // wave																		// scale ofs
	#define CX(x) {  x = w-cx;  x = ( (x*(K +ax*Cos(8*w      +tt[0])/SY*Sin(7*w      +tt[1])/SY) /K) +cx)/8 +6;  }
	#define CY(y) {  y = w-cy;  y = ( (y*(K +ay*Cos(9*w+ x*73+tt[2])/SY*Sin(6*w+ x*52+tt[3])/SY) /K) +cy)/9 -1;  }

	const uint tt[4] = {t*7,t*5,t*8,t*5};
	for (int w2=0; w2<2; ++w2)
	{
		const int cx = cw[ckCur][w2], cy = cw[ckCur][2+w2],
				ax = cw[ckCur][4+w2], ay = cw[ckCur][6+w2];
		int a=0,w, i=0,rst=1,
			x1=0,y1=0,x=0,y=0;
		do
		{	w = w2 ? word2[a++] : word1[a++];
			if (w<=0) {  rst=1;  i=0;  }
			else
			if (rst)  switch(i)
			{	case 0:  CX(x)  ++i;  break;
				case 1:  CY(y)  rst=0; i=0;  break;  }
			else  switch(i)
			{	case 0:  x1=x;  CX(x)  ++i;  break;
				case 1:  y1=y;  CY(y)  i=2;  break;  }

			if (i==2)
			{	i=0;  d.drawLine(x1,y1, x,y, WHITE);  }
		}
		while (w >= 0);
	}

	if (iInfo > 0)
	{
		d.setCursor(0,8);
		d.print("Cur ");  d.println(ckCur);
		d.print("Spd ");  d.println(ckSpeed);
	}

	t += ckSpeed;
	delay(6);
}
Ejemplo n.º 17
0
PolyBase &PolyBase::operator*=(const PolyBase &A)
/**
  Self multiplication value
  @param A :: PolyBase to add
  @return *this*=A;
 */
{
  const int iD = iDegree + A.iDegree;
  std::vector<double> CX(iD + 1, 0.0); // all set to zero
  for (int i = 0; i <= iDegree; i++)
    for (int j = 0; j <= A.iDegree; j++) {
      const int cIndex = i + j;
      CX[cIndex] += afCoeff[i] * A.afCoeff[j];
    }
  afCoeff = CX;
  return *this;
}
Ejemplo n.º 18
0
/* Subroutine */ int zdrot_(integer *n, doublecomplex *cx, integer *incx, 
	doublecomplex *cy, integer *incy, doublereal *c, doublereal *s)
{
    /* System generated locals */
    integer i__1, i__2, i__3, i__4;
    doublecomplex z__1, z__2, z__3;
    /* Local variables */
    static integer i;
    static doublecomplex ctemp;
    static integer ix, iy;
/*     applies a plane rotation, where the cos and sin (c and s) are real 
  
       and the vectors cx and cy are complex.   
       jack dongarra, linpack, 3/11/78.   
   ===================================================================== 
  
    
   Parameter adjustments   
       Function Body */
#define CY(I) cy[(I)-1]
#define CX(I) cx[(I)-1]
    if (*n <= 0) {
	return 0;
    }
    if (*incx == 1 && *incy == 1) {
	goto L20;
    }
/*        code for unequal increments or equal increments not equal   
            to 1 */
    ix = 1;
    iy = 1;
    if (*incx < 0) {
	ix = (-(*n) + 1) * *incx + 1;
    }
    if (*incy < 0) {
	iy = (-(*n) + 1) * *incy + 1;
    }
    i__1 = *n;
    for (i = 1; i <= *n; ++i) {
	i__2 = ix;
	z__2.r = *c * CX(ix).r, z__2.i = *c * CX(ix).i;
	i__3 = iy;
	z__3.r = *s * CY(iy).r, z__3.i = *s * CY(iy).i;
	z__1.r = z__2.r + z__3.r, z__1.i = z__2.i + z__3.i;
	ctemp.r = z__1.r, ctemp.i = z__1.i;
	i__2 = iy;
	i__3 = iy;
	z__2.r = *c * CY(iy).r, z__2.i = *c * CY(iy).i;
	i__4 = ix;
	z__3.r = *s * CX(ix).r, z__3.i = *s * CX(ix).i;
	z__1.r = z__2.r - z__3.r, z__1.i = z__2.i - z__3.i;
	CY(iy).r = z__1.r, CY(iy).i = z__1.i;
	i__2 = ix;
	CX(ix).r = ctemp.r, CX(ix).i = ctemp.i;
	ix += *incx;
	iy += *incy;
/* L10: */
    }
    return 0;
/*        code for both increments equal to 1 */
L20:
    i__1 = *n;
    for (i = 1; i <= *n; ++i) {
	i__2 = i;
	z__2.r = *c * CX(i).r, z__2.i = *c * CX(i).i;
	i__3 = i;
	z__3.r = *s * CY(i).r, z__3.i = *s * CY(i).i;
	z__1.r = z__2.r + z__3.r, z__1.i = z__2.i + z__3.i;
	ctemp.r = z__1.r, ctemp.i = z__1.i;
	i__2 = i;
	i__3 = i;
	z__2.r = *c * CY(i).r, z__2.i = *c * CY(i).i;
	i__4 = i;
	z__3.r = *s * CX(i).r, z__3.i = *s * CX(i).i;
	z__1.r = z__2.r - z__3.r, z__1.i = z__2.i - z__3.i;
	CY(i).r = z__1.r, CY(i).i = z__1.i;
	i__2 = i;
	CX(i).r = ctemp.r, CX(i).i = ctemp.i;
/* L30: */
    }
    return 0;
} /* zdrot_ */
Ejemplo n.º 19
0
double scsum1_(int *n, complex *cx, int *incx)
{
/*  -- LAPACK auxiliary routine (version 2.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       October 31, 1992   


    Purpose   
    =======   

    SCSUM1 takes the sum of the absolute values of a complex   
    vector and returns a single precision result.   

    Based on SCASUM from the Level 1 BLAS.   
    The change is to use the 'genuine' absolute value.   

    Contributed by Nick Higham for use with CLACON.   

    Arguments   
    =========   

    N       (input) INT
            The number of elements in the vector CX.   

    CX      (input) COMPLEX array, dimension (N)   
            The vector whose elements will be summed.   

    INCX    (input) INT
            The spacing between successive values of CX.  INCX > 0.   

    ===================================================================== 
  


    
   Parameter adjustments   
       Function Body */
    /* System generated locals */
    int i__1, i__2;
    float ret_val;
    /* Builtin functions */
    double slu_c_abs(complex *);
    /* Local variables */
    static int i, nincx;
    static float stemp;


#define CX(I) cx[(I)-1]


    ret_val = 0.f;
    stemp = 0.f;
    if (*n <= 0) {
	return ret_val;
    }
    if (*incx == 1) {
	goto L20;
    }

/*     CODE FOR INCREMENT NOT EQUAL TO 1 */

    nincx = *n * *incx;
    i__1 = nincx;
    i__2 = *incx;
    for (i = 1; *incx < 0 ? i >= nincx : i <= nincx; i += *incx) {

/*        NEXT LINE MODIFIED. */

	stemp += slu_c_abs(&CX(i));
/* L10: */
    }
    ret_val = stemp;
    return ret_val;

/*     CODE FOR INCREMENT EQUAL TO 1 */

L20:
    i__2 = *n;
    for (i = 1; i <= *n; ++i) {

/*        NEXT LINE MODIFIED. */

	stemp += slu_c_abs(&CX(i));
/* L30: */
    }
    ret_val = stemp;
    return ret_val;

/*     End of SCSUM1 */

} /* scsum1_ */
Ejemplo n.º 20
0
int
izmax1_(int *n, doublecomplex *cx, int *incx)
{
/*  -- LAPACK auxiliary routine (version 2.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       September 30, 1994   


    Purpose   
    =======   

    IZMAX1 finds the index of the element whose real part has maximum   
    absolute value.   

    Based on IZAMAX from Level 1 BLAS.   
    The change is to use the 'genuine' absolute value.   

    Contributed by Nick Higham for use with ZLACON.   

    Arguments   
    =========   

    N       (input) INT   
            The number of elements in the vector CX.   

    CX      (input) COMPLEX*16 array, dimension (N)   
            The vector whose elements will be summed.   

    INCX    (input) INT   
            The spacing between successive values of CX.  INCX >= 1.   

   ===================================================================== 
*/  

    /* System generated locals */
    int ret_val, i__1, i__2;
    double d__1;
    
    /* Local variables */
    double smax;
    int i, ix;

#define CX(I) cx[(I)-1]

    ret_val = 0;
    if (*n < 1) {
	return ret_val;
    }
    ret_val = 1;
    if (*n == 1) {
	return ret_val;
    }
    if (*incx == 1) {
	goto L30;
    }

/*     CODE FOR INCREMENT NOT EQUAL TO 1 */

    ix = 1;
    smax = (d__1 = CX(1).r, fabs(d__1));
    ix += *incx;
    i__1 = *n;
    for (i = 2; i <= *n; ++i) {
	i__2 = ix;
	if ((d__1 = CX(ix).r, fabs(d__1)) <= smax) {
	    goto L10;
	}
	ret_val = i;
	i__2 = ix;
	smax = (d__1 = CX(ix).r, fabs(d__1));
L10:
	ix += *incx;
/* L20: */
    }
    return ret_val;

/*     CODE FOR INCREMENT EQUAL TO 1 */

L30:
    smax = (d__1 = CX(1).r, fabs(d__1));
    i__1 = *n;
    for (i = 2; i <= *n; ++i) {
	i__2 = i;
	if ((d__1 = CX(i).r, fabs(d__1)) <= smax) {
	    goto L40;
	}
	ret_val = i;
	i__2 = i;
	smax = (d__1 = CX(i).r, fabs(d__1));
L40:
	;
    }
    return ret_val;

/*     End of IZMAX1 */

} /* izmax1_ */
Ejemplo n.º 21
0
int
izmax1_(int *n, doublecomplex *cx, int *incx)
{


    /* System generated locals */
    int ret_val, i__1, i__2;
    double d__1;

    /* Local variables */
    double smax;
    int i, ix;

#define CX(I) cx[(I)-1]

    ret_val = 0;
    if (*n < 1) {
        return ret_val;
    }
    ret_val = 1;
    if (*n == 1) {
        return ret_val;
    }
    if (*incx == 1) {
        goto L30;
    }

/*     CODE FOR INCREMENT NOT EQUAL TO 1 */

    ix = 1;
    smax = (d__1 = CX(1).r, fabs(d__1));
    ix += *incx;
    i__1 = *n;
    for (i = 2; i <= *n; ++i) {
        i__2 = ix;
        if ((d__1 = CX(ix).r, fabs(d__1)) <= smax) {
            goto L10;
        }
        ret_val = i;
        i__2 = ix;
        smax = (d__1 = CX(ix).r, fabs(d__1));
L10:
        ix += *incx;
/* L20: */
    }
    return ret_val;

/*     CODE FOR INCREMENT EQUAL TO 1 */

L30:
    smax = (d__1 = CX(1).r, fabs(d__1));
    i__1 = *n;
    for (i = 2; i <= *n; ++i) {
        i__2 = i;
        if ((d__1 = CX(i).r, fabs(d__1)) <= smax) {
            goto L40;
        }
        ret_val = i;
        i__2 = i;
        smax = (d__1 = CX(i).r, fabs(d__1));
L40:
        ;
    }
    return ret_val;

/*     End of IZMAX1 */

} /* izmax1_ */
Ejemplo n.º 22
0
void FifthCKF::FifthCKFfiltering(double *z, UINT m_length)
{
	CMatrix Pplus(4, 4);
	Pplus = glb.Pplus;

    CMatrix xhat(4, 1);
	xhat = glb.xhat;
	
	StoreData *fifthckf = new StoreData(xhat(1, 1), xhat(2, 1), xhat(3, 1), xhat(4, 1));
	X.Add(fifthckf);

	CMatrix Shat(dim, dim);
	CMatrix rjpoint1(dim, 1);
	CMatrix rjpoint2(dim, cpoints);
	CMatrix rjpoint3(dim, hcpoints - cpoints - 1);
	CMatrix Xminus1(dim, 1);
	CMatrix Xminus2(dim, cpoints);
	CMatrix Repmat2(dim, cpoints);
	CMatrix Xminus3(dim, hcpoints - cpoints - 1);
	CMatrix Repmat3(dim, hcpoints - cpoints - 1);
	CMatrix jtemp(dim, 1);
	CMatrix Zhat1(1, 1);
	CMatrix Zhat2(1, cpoints);
	CMatrix RepmatZ2(1, cpoints);
	CMatrix Zhat3(1, hcpoints - cpoints - 1);
	CMatrix RepmatZ3(1, hcpoints - cpoints - 1);
	CMatrix W(dim, 1);
	CMatrix Pz(1, 1);
	CMatrix Xtemp(dim, 1);
	CMatrix Pxz(4, 1);

	int num = 1;//第0个未知存放的是占位符0,并不是真正的测量值,因此应当从下标1开始取测量值
	for (UINT count = TimeInterval; count <= m_length; count += TimeInterval)
	{
		//Time Update
		//Evaluate the Cholesky factor
		Shat = Pplus.Cholesky();

		//Evaluate the cubature points and the propagated cubature points//Estimate the predicted state
		CMatrix CX(4, 1);
		 
		for (int i = 1; i <= hcpoints; ++i)
		{
			 
			for (int j = 1; j <= dim; ++j)
			{
				jtemp(j, 1) = glb.kesi_FifthCKF(j, i);
			}
			jtemp = Shat * jtemp + xhat;
			Xtemp = glb.fai * jtemp;

			if ( 1 == i)
			{
				 
				for (int j = 1; j <= dim; ++j)
				{
					Xminus1(j, 1) = Xtemp(j, 1);
				}
				CX = CX + c5_w2 * Xtemp;
			}
			else if (i > 1 && i <= cpoints + 1)//此编程风格会提高代码的冗余度,但提高了程序的运行效率,下同
			{
				 
				for (int j = 1; j <= dim; ++j)
				{
					Xminus2(j, i - 1) = Xtemp(j, 1);
				}
				CX = CX + c5_w1 * Xtemp;
			}
			else
			{
				 
				for (int j = 1; j <= dim; ++j)
				{
					Xminus3(j, i - cpoints - 1) = Xtemp(j, 1);
				}
				CX = CX + c5_w4 * Xtemp;
			}
		}


		//xhat = CX;

		//Estimate the predicted error covariance
		 
		for (int i = 1; i <= cpoints; ++i)
		{
			#pragma omp parallel for
			for (int j = 1; j <= dim; ++j)
			{
				Repmat2(j, i) = CX(j, 1);
			}
		}

		 
		for (int i = 1; i <= hcpoints - cpoints - 1; ++i)
		{
			#pragma omp parallel for
			for(int j = 1; j <= dim; ++j)
			{
				Repmat3(j, i) = CX(j, 1);
			}
		}

		Pplus = c5_w2 * ((Xminus1 - CX) * (~(Xminus1 - CX))) + 
			c5_w1 * (Xminus2 - Repmat2) * (~(Xminus2 - Repmat2)) + 
			c5_w4 * (Xminus3 - Repmat3) * (~(Xminus3 - Repmat3)) + glb.gama * glb.Im * (~glb.gama);

		//Measurement Update
		//Evaluate the Cholesky factor
		Shat = Pplus.Cholesky();

		//Evaluate the cubature points and the propagated cubature points//Estimate the predicted measurement
		CMatrix Z(1, 1);
		 
		for (int i = 1; i <= hcpoints; ++i)
		{
			 
			for (int j = 1; j <= dim; ++j)
			{
				jtemp(j, 1) = glb.kesi_FifthCKF(j, i);
			}
			jtemp = Shat * jtemp + CX;

			if (1 == i)
			{
				Zhat1(1, 1) = atan(jtemp(3, 1) / jtemp(1, 1));
				Z(1, 1) = Z(1, 1) + c5_w2 * Zhat1(1, 1);

				#pragma omp parallel for
				for (int j = 1; j<= dim; ++j)
				{
					rjpoint1(j, 1) = jtemp(j, 1);
				}
			}
			else if (i > 1 && i <= cpoints + 1)
			{
				Zhat2(1, i - 1) = atan(jtemp(3, 1) / jtemp(1, 1));
			    Z(1, 1) = Z(1, 1) + c5_w1 * Zhat2(1, i - 1);

				#pragma omp parallel for
				for (int j = 1; j <= dim; ++j)
				{
					rjpoint2(j, i - 1) = jtemp(j, 1);
				}
			}
			else
			{
				Zhat3(1, i - cpoints - 1) = atan(jtemp(3, 1) / jtemp(1, 1));
				Z(1, 1) = Z(1, 1) + c5_w4 * Zhat3(1, i - cpoints - 1);

				#pragma omp parallel for
				for (int j = 1; j <= dim; ++j)
				{
					rjpoint3(j, i - cpoints - 1) = jtemp(j, 1);
				}
			}
		}

		//Estimate the innovation covariance matrix
		Pz(1, 1) = Rn;//For saving memory

		#pragma omp parallel for
		for (int i = 1; i <= cpoints; ++i)
		{
			RepmatZ2(1, i) = Z(1, 1);
		}

		#pragma omp parallel for
		for (int i = 1; i <= hcpoints - cpoints - 1; ++i)
		{
			RepmatZ3(1, i) = Z(1, 1);
		}

		Pz = c5_w2 * (Zhat1 - Z) * (~(Zhat1 - Z)) + 
			c5_w1 * (Zhat2 - RepmatZ2)* (~(Zhat2 - RepmatZ2)) + 
			c5_w4 * (Zhat3 - RepmatZ3) * (~(Zhat3 - RepmatZ3)) + Pz;

		//Estimate the cross-covariance matrix 
		Pxz = c5_w2 * (rjpoint1 - CX) * (~(Zhat1 - Z)) + 
			c5_w1 *(rjpoint2 - Repmat2) * (~(Zhat2 - RepmatZ2)) + 
			c5_w4 * (rjpoint3 - Repmat3) * (~(Zhat3 - RepmatZ3));

		//Estimate the Kalman gain
		W = ((double)1 / Pz(1, 1)) * Pxz;

		//Estimate the updated state
		//Znum(1, 1) = z[num];
		
		xhat = CX + W * (z[num] - Z(1, 1));
		++num;

		Pplus = Pplus - Pz(1, 1) * W * (~W);

		StoreData *fifthckf = new StoreData(xhat(1, 1), xhat(2, 1), xhat(3, 1), xhat(4, 1));
		X.Add(fifthckf);
	}
}
Ejemplo n.º 23
0
/* Subroutine */ int zlacrt_(integer *n, doublecomplex *cx, integer *incx, 
	doublecomplex *cy, integer *incy, doublecomplex *c, doublecomplex *s)
{
/*  -- LAPACK auxiliary routine (version 2.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       October 31, 1992   


    Purpose   
    =======   

    ZLACRT applies a plane rotation, where the cos and sin (C and S) are 
  
    complex and the vectors CX and CY are complex.   

    Arguments   
    =========   

    N       (input) INTEGER   
            The number of elements in the vectors CX and CY.   

    CX      (input/output) COMPLEX*16 array, dimension (N)   
            On input, the vector X.   
            On output, CX is overwritten with C*X + S*Y.   

    INCX    (input) INTEGER   
            The increment between successive values of CY.  INCX <> 0.   

    CY      (input/output) COMPLEX*16 array, dimension (N)   
            On input, the vector Y.   
            On output, CY is overwritten with -S*X + C*Y.   

    INCY    (input) INTEGER   
            The increment between successive values of CY.  INCX <> 0.   

    C       (input) COMPLEX*16   
    S       (input) COMPLEX*16   
            C and S define a complex rotation   
               [  C   S  ]   
               [ -S   C  ]   
            where C*C + S*S = 1.0.   

   ===================================================================== 
  


    
   Parameter adjustments   
       Function Body */
    /* System generated locals */
    integer i__1, i__2, i__3, i__4;
    doublecomplex z__1, z__2, z__3;
    /* Local variables */
    static integer i;
    static doublecomplex ctemp;
    static integer ix, iy;


#define CY(I) cy[(I)-1]
#define CX(I) cx[(I)-1]


    if (*n <= 0) {
	return 0;
    }
    if (*incx == 1 && *incy == 1) {
	goto L20;
    }

/*     Code for unequal increments or equal increments not equal to 1 */

    ix = 1;
    iy = 1;
    if (*incx < 0) {
	ix = (-(*n) + 1) * *incx + 1;
    }
    if (*incy < 0) {
	iy = (-(*n) + 1) * *incy + 1;
    }
    i__1 = *n;
    for (i = 1; i <= *n; ++i) {
	i__2 = ix;
	z__2.r = c->r * CX(ix).r - c->i * CX(ix).i, z__2.i = c->r * CX(
		ix).i + c->i * CX(ix).r;
	i__3 = iy;
	z__3.r = s->r * CY(iy).r - s->i * CY(iy).i, z__3.i = s->r * CY(
		iy).i + s->i * CY(iy).r;
	z__1.r = z__2.r + z__3.r, z__1.i = z__2.i + z__3.i;
	ctemp.r = z__1.r, ctemp.i = z__1.i;
	i__2 = iy;
	i__3 = iy;
	z__2.r = c->r * CY(iy).r - c->i * CY(iy).i, z__2.i = c->r * CY(
		iy).i + c->i * CY(iy).r;
	i__4 = ix;
	z__3.r = s->r * CX(ix).r - s->i * CX(ix).i, z__3.i = s->r * CX(
		ix).i + s->i * CX(ix).r;
	z__1.r = z__2.r - z__3.r, z__1.i = z__2.i - z__3.i;
	CY(iy).r = z__1.r, CY(iy).i = z__1.i;
	i__2 = ix;
	CX(ix).r = ctemp.r, CX(ix).i = ctemp.i;
	ix += *incx;
	iy += *incy;
/* L10: */
    }
    return 0;

/*     Code for both increments equal to 1 */

L20:
    i__1 = *n;
    for (i = 1; i <= *n; ++i) {
	i__2 = i;
	z__2.r = c->r * CX(i).r - c->i * CX(i).i, z__2.i = c->r * CX(
		i).i + c->i * CX(i).r;
	i__3 = i;
	z__3.r = s->r * CY(i).r - s->i * CY(i).i, z__3.i = s->r * CY(
		i).i + s->i * CY(i).r;
	z__1.r = z__2.r + z__3.r, z__1.i = z__2.i + z__3.i;
	ctemp.r = z__1.r, ctemp.i = z__1.i;
	i__2 = i;
	i__3 = i;
	z__2.r = c->r * CY(i).r - c->i * CY(i).i, z__2.i = c->r * CY(
		i).i + c->i * CY(i).r;
	i__4 = i;
	z__3.r = s->r * CX(i).r - s->i * CX(i).i, z__3.i = s->r * CX(
		i).i + s->i * CX(i).r;
	z__1.r = z__2.r - z__3.r, z__1.i = z__2.i - z__3.i;
	CY(i).r = z__1.r, CY(i).i = z__1.i;
	i__2 = i;
	CX(i).r = ctemp.r, CX(i).i = ctemp.i;
/* L30: */
    }
    return 0;
} /* zlacrt_ */
Ejemplo n.º 24
0
int SWIFT_Initialize (void)
{
   SWIFT_StaticData sdBuf;
   int fSwift = 0;

   if (fActive)                     // SWIFT extensions already active
   {
#ifdef DEGUB
      SoftError( "SWIFT_Initialize: Already active.\n");
      SoftError( "SWIFT_Initialize: returns TRUE\n");
#endif
      return (1);
   }

   nAttached = SWIFT_DEV_NONE;


   if (_dos_getvect(0x33) == NULL)  // No mouse driver loaded
   {
#ifdef DBUG
      SoftError( "SWIFT_Initialize: No mouse driver loaded.\n");
      SoftError( "SWIFT_Initialize: returns FALSE\n");
#endif
      return (0);
   }


   // Reset the mouse and driver
   AX (regs) = 0;
   int386( 0x33, &regs, &regs);

   if (AX (regs) == 0)
   {                                // no mouse
#ifdef DBUG
      SoftError( "SWIFT_Initialize: No pointing device attached.\n");
      SoftError( "SWIFT_Initialize: returns FALSE\n");
#endif
      return (0);
   }

#ifdef DBUG
   AX (regs) = 36;   // Get Mouse Information
   BX (regs) = 0xffff;
   CX (regs) = 0xffff;
   DX (regs) = 0xffff;
   int386 (0x33, &regs, &regs);
   SoftError( "SWIFT_Initialize: driver version %d.%02d\n", regs.h.bh, regs.h.bl);
   SoftError( "SWIFT_Initialize: %s mouse using IRQ %d\n",
          (regs.h.ch==1) ? "bus" :
          (regs.h.ch==2) ? "serial" :
          (regs.h.ch==3) ? "inport" :
          (regs.h.ch==4) ? "PS/2" :
                           "unknown", regs.h.cl);
#endif


   // allocate a DOS real-mode buffer
   pdosmem = allocDOS(DOSMEMSIZE, &segment, &selector);
   if (!pdosmem)
   {
#ifdef DBUG
      SoftError( "SWIFT_Initialize: DOS Alloc failed!\n");
      SoftError( "SWIFT_Initialize: returns FALSE\n");
#endif
      return (0);
   }

//
// SWIFT device supported and attached
//
   if (SWIFT_GetStaticDeviceInfo (&sdBuf))
      fSwift = 1;


   if (!fSwift)
   {  // SWIFT functions not present
#ifdef DBUG
      SoftError( "SWIFT_Initialize: no SWIFT support in mouse driver.\n");
#endif
   }
   else
      if (sdBuf.deviceType == SWIFT_DEV_NONE)
      {
#ifdef DBUG
         SoftError( "SWIFT_Initialize: no SWIFT device connected.\n");
#endif
      }
      else
      {
         nAttached = sdBuf.deviceType;
#ifdef DBUG
         SoftError( "SWIFT_Initialize: ");

         switch (nAttached)
         {
            case SWIFT_DEV_CYBERMAN:
               SoftError( "CyberMan %d.%02d connected.\n",
                                sdBuf.majorVersion, sdBuf.minorVersion);
            break;

            default:
               SoftError( "Unknown SWIFT device (type %d) connected.\n",
                                nAttached);
            break;
         }
#endif
      fActive = 1;
   }

   if (!fActive)
   {                    // activation of SWIFT module failed for some reason
      if (pdosmem)
      {                 // if DOS buffer was allocated, free it
         freeDOS(selector);
         pdosmem = 0;
      }
   }

#ifdef DBUG
   SoftError( "SWIFT_Initialize: returns %s.\n", (fActive ? "TRUE" : "FALSE"));
#endif
   return fActive;
}
Ejemplo n.º 25
0
/* Subroutine */ int crot_(integer *n, complex *cx, integer *incx, complex *
	cy, integer *incy, real *c, complex *s)
{
/*  -- LAPACK auxiliary routine (version 2.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       October 31, 1992   


    Purpose   
    =======   

    CROT   applies a plane rotation, where the cos (C) is real and the   
    sin (S) is complex, and the vectors CX and CY are complex.   

    Arguments   
    =========   

    N       (input) INTEGER   
            The number of elements in the vectors CX and CY.   

    CX      (input/output) COMPLEX array, dimension (N)   
            On input, the vector X.   
            On output, CX is overwritten with C*X + S*Y.   

    INCX    (input) INTEGER   
            The increment between successive values of CY.  INCX <> 0.   

    CY      (input/output) COMPLEX array, dimension (N)   
            On input, the vector Y.   
            On output, CY is overwritten with -CONJG(S)*X + C*Y.   

    INCY    (input) INTEGER   
            The increment between successive values of CY.  INCX <> 0.   

    C       (input) REAL   
    S       (input) COMPLEX   
            C and S define a rotation   
               [  C          S  ]   
               [ -conjg(S)   C  ]   
            where C*C + S*CONJG(S) = 1.0.   

   ===================================================================== 
  


    
   Parameter adjustments   
       Function Body */
    /* System generated locals */
    integer i__1, i__2, i__3, i__4;
    complex q__1, q__2, q__3, q__4;
    /* Builtin functions */
    void r_cnjg(complex *, complex *);
    /* Local variables */
    static integer i;
    static complex stemp;
    static integer ix, iy;


#define CY(I) cy[(I)-1]
#define CX(I) cx[(I)-1]


    if (*n <= 0) {
	return 0;
    }
    if (*incx == 1 && *incy == 1) {
	goto L20;
    }

/*     Code for unequal increments or equal increments not equal to 1 */

    ix = 1;
    iy = 1;
    if (*incx < 0) {
	ix = (-(*n) + 1) * *incx + 1;
    }
    if (*incy < 0) {
	iy = (-(*n) + 1) * *incy + 1;
    }
    i__1 = *n;
    for (i = 1; i <= *n; ++i) {
	i__2 = ix;
	q__2.r = *c * CX(ix).r, q__2.i = *c * CX(ix).i;
	i__3 = iy;
	q__3.r = s->r * CY(iy).r - s->i * CY(iy).i, q__3.i = s->r * CY(
		iy).i + s->i * CY(iy).r;
	q__1.r = q__2.r + q__3.r, q__1.i = q__2.i + q__3.i;
	stemp.r = q__1.r, stemp.i = q__1.i;
	i__2 = iy;
	i__3 = iy;
	q__2.r = *c * CY(iy).r, q__2.i = *c * CY(iy).i;
	r_cnjg(&q__4, s);
	i__4 = ix;
	q__3.r = q__4.r * CX(ix).r - q__4.i * CX(ix).i, q__3.i = q__4.r * 
		CX(ix).i + q__4.i * CX(ix).r;
	q__1.r = q__2.r - q__3.r, q__1.i = q__2.i - q__3.i;
	CY(iy).r = q__1.r, CY(iy).i = q__1.i;
	i__2 = ix;
	CX(ix).r = stemp.r, CX(ix).i = stemp.i;
	ix += *incx;
	iy += *incy;
/* L10: */
    }
    return 0;

/*     Code for both increments equal to 1 */

L20:
    i__1 = *n;
    for (i = 1; i <= *n; ++i) {
	i__2 = i;
	q__2.r = *c * CX(i).r, q__2.i = *c * CX(i).i;
	i__3 = i;
	q__3.r = s->r * CY(i).r - s->i * CY(i).i, q__3.i = s->r * CY(
		i).i + s->i * CY(i).r;
	q__1.r = q__2.r + q__3.r, q__1.i = q__2.i + q__3.i;
	stemp.r = q__1.r, stemp.i = q__1.i;
	i__2 = i;
	i__3 = i;
	q__2.r = *c * CY(i).r, q__2.i = *c * CY(i).i;
	r_cnjg(&q__4, s);
	i__4 = i;
	q__3.r = q__4.r * CX(i).r - q__4.i * CX(i).i, q__3.i = q__4.r * 
		CX(i).i + q__4.i * CX(i).r;
	q__1.r = q__2.r - q__3.r, q__1.i = q__2.i - q__3.i;
	CY(i).r = q__1.r, CY(i).i = q__1.i;
	i__2 = i;
	CX(i).r = stemp.r, CX(i).i = stemp.i;
/* L30: */
    }
    return 0;
} /* crot_ */
Ejemplo n.º 26
0
/* Subroutine */ int cscal_(integer *n, complex *ca, complex *cx, integer *
	incx)
{


    /* System generated locals */
    integer i__1, i__2, i__3, i__4;
    complex q__1;

    /* Local variables */
    integer i, nincx;


/*     scales a vector by a constant.   
       jack dongarra, linpack,  3/11/78.   
       modified 3/93 to return if incx .le. 0.   
       modified 12/3/93, array(1) declarations changed to array(*)   


    
   Parameter adjustments   
       Function Body */
#define CX(I) cx[(I)-1]


    if (*n <= 0 || *incx <= 0) {
	return 0;
    }
    if (*incx == 1) {
	goto L20;
    }

/*        code for increment not equal to 1 */

    nincx = *n * *incx;
    i__1 = nincx;
    i__2 = *incx;
    for (i = 1; *incx < 0 ? i >= nincx : i <= nincx; i += *incx) {
	i__3 = i;
	i__4 = i;
	q__1.r = ca->r * CX(i).r - ca->i * CX(i).i, q__1.i = ca->r * CX(
		i).i + ca->i * CX(i).r;
	CX(i).r = q__1.r, CX(i).i = q__1.i;
/* L10: */
    }
    return 0;

/*        code for increment equal to 1 */

L20:
    i__2 = *n;
    for (i = 1; i <= *n; ++i) {
	i__1 = i;
	i__3 = i;
	q__1.r = ca->r * CX(i).r - ca->i * CX(i).i, q__1.i = ca->r * CX(
		i).i + ca->i * CX(i).r;
	CX(i).r = q__1.r, CX(i).i = q__1.i;
/* L30: */
    }
    return 0;
} /* cscal_ */
Ejemplo n.º 27
0
integer icamax_(integer *n, complex *cx, integer *incx)
{
    /* System generated locals */
    integer ret_val, i__1, i__2;
    real r__1, r__2;
    /* Builtin functions */
    double r_imag(complex *);
    /* Local variables */
    real smax;
    integer i, ix;
/*     finds the index of element having max. absolute value.   
       jack dongarra, linpack, 3/11/78.   
       modified 3/93 to return if incx .le. 0.   
       modified 12/3/93, array(1) declarations changed to array(*)   
    
   Parameter adjustments   
       Function Body */
#define CX(I) cx[(I)-1]
    ret_val = 0;
    if (*n < 1 || *incx <= 0) {
	return ret_val;
    }
    ret_val = 1;
    if (*n == 1) {
	return ret_val;
    }
    if (*incx == 1) {
	goto L20;
    }
/*        code for increment not equal to 1 */
    ix = 1;
    smax = (r__1 = CX(1).r, dabs(r__1)) + (r__2 = r_imag(&CX(1)), dabs(r__2));
    ix += *incx;
    i__1 = *n;
    for (i = 2; i <= *n; ++i) {
	i__2 = ix;
	if ((r__1 = CX(ix).r, dabs(r__1)) + (r__2 = r_imag(&CX(ix)), dabs(
		r__2)) <= smax) {
	    goto L5;
	}
	ret_val = i;
	i__2 = ix;
	smax = (r__1 = CX(ix).r, dabs(r__1)) + (r__2 = r_imag(&CX(ix)), 
		dabs(r__2));
L5:
	ix += *incx;
/* L10: */
    }
    return ret_val;
/*        code for increment equal to 1 */
L20:
    smax = (r__1 = CX(1).r, dabs(r__1)) + (r__2 = r_imag(&CX(1)), dabs(r__2));
    i__1 = *n;
    for (i = 2; i <= *n; ++i) {
	i__2 = i;
	if ((r__1 = CX(i).r, dabs(r__1)) + (r__2 = r_imag(&CX(i)), dabs(
		r__2)) <= smax) {
	    goto L30;
	}
	ret_val = i;
	i__2 = i;
	smax = (r__1 = CX(i).r, dabs(r__1)) + (r__2 = r_imag(&CX(i)), dabs(
		r__2));
L30:
	;
    }
    return ret_val;
} /* icamax_ */
Ejemplo n.º 28
0
static void
play(void)
/* play the game */
{
    bool keyhelp;		/* TRUE if keystroke help is up */
    int i, j, count;
    int lastcol = 0;		/* last location visited */
    int lastrow = 0;
    int ny = 0, nx = 0;
    int review = 0;		/* review history */
    int rw = 0, col = 0;	/* current row and column */

    do {
	/* clear screen and draw board */
	werase(boardwin);
	werase(helpwin);
	werase(msgwin);
	dosquares();
	help1();
	wnoutrefresh(stdscr);
	wnoutrefresh(helpwin);
	wnoutrefresh(msgwin);
	wnoutrefresh(boardwin);
	doupdate();

	movecount = 0;
	for (i = 0; i < BDEPTH; i++) {
	    for (j = 0; j < BWIDTH; j++) {
		board[i][j] = FALSE;
		unmarkcell(i, j);
	    }
	}
	memset(history, 0, sizeof(history));
	history[0].y = history[0].x = -1;
	history[1].y = history[1].x = -1;
	lastrow = lastcol = -2;
	movecount = 1;
	trialcount = 1;
	keyhelp = FALSE;
	show_help(&keyhelp);

	for (;;) {
	    if (rw != lastrow || col != lastcol) {
		if (lastrow >= 0 && lastcol >= 0) {
		    cellmove(lastrow, lastcol);
		    if (board[lastrow][lastcol])
			waddch(boardwin, trail);
		    else
			waddch(boardwin, oldch);
		}

		cellmove(rw, col);
		oldch = winch(boardwin);

		lastrow = rw;
		lastcol = col;
	    }
	    cellmove(rw, col);
	    waddch(boardwin, plus);
	    cellmove(rw, col);

	    wrefresh(msgwin);

	    switch (wgetch(boardwin)) {
	    case 'k':
	    case '8':
	    case KEY_UP:
		ny = rw + BDEPTH - 1;
		nx = col;
		break;
	    case 'j':
	    case '2':
	    case KEY_DOWN:
		ny = rw + 1;
		nx = col;
		break;
	    case 'h':
	    case '4':
	    case KEY_LEFT:
		ny = rw;
		nx = col + BWIDTH - 1;
		break;
	    case 'l':
	    case '6':
	    case KEY_RIGHT:
		ny = rw;
		nx = col + 1;
		break;
	    case 'y':
	    case '7':
	    case KEY_A1:
		ny = rw + BDEPTH - 1;
		nx = col + BWIDTH - 1;
		break;
	    case 'b':
	    case '1':
	    case KEY_C1:
		ny = rw + 1;
		nx = col + BWIDTH - 1;
		break;
	    case 'u':
	    case '9':
	    case KEY_A3:
		ny = rw + BDEPTH - 1;
		nx = col + 1;
		break;
	    case 'n':
	    case '3':
	    case KEY_C3:
		ny = rw + 1;
		nx = col + 1;
		break;

#ifdef NCURSES_MOUSE_VERSION
	    case KEY_MOUSE:
		{
		    MEVENT myevent;

		    getmouse(&myevent);
		    if (myevent.y >= CY(0) && myevent.y <= CY(BDEPTH)
			&& myevent.x >= CX(0) && myevent.x <= CX(BWIDTH)) {
			nx = CXINV(myevent.x);
			ny = CYINV(myevent.y);
			ungetch('\n');
			break;
		    } else {
			beep();
			continue;
		    }
		}
#endif /* NCURSES_MOUSE_VERSION */

	    case KEY_B2:
	    case '\n':
	    case ' ':
		review = 0;
		if (evalmove(rw, col)) {
		    drawmove(trail,
			     history[movecount - 1].y,
			     history[movecount - 1].x,
			     rw, col);
		    history[movecount].y = (short) rw;
		    history[movecount].x = (short) col;
		    movecount++;
		    trialcount++;

		    if (!chkmoves(rw, col)) {
			if (completed() < 0) {
			    waddstr(msgwin, "\nYou won.");
			} else {
			    waddstr(msgwin,
				    "\nNo further moves are possible.");
			}
		    }
		} else {
		    beep();
		}
		break;

	    case KEY_UNDO:
	    case KEY_BACKSPACE:
	    case '\b':
		review = 0;
		if (movecount <= 0) {
		    no_previous_move();
		} else if (movecount <= 1) {
		    ny = history[movecount].y;
		    nx = history[movecount].x;
		    if (nx < 0 || ny < 0) {
			ny = lastrow;
			nx = lastcol;
		    }
		    movecount = 0;
		    board[ny][nx] = FALSE;
		    oldch = minus;
		    drawmove(' ', ny, nx, -1, -1);
		    movecount = 1;
		    trialcount = 1;
		    no_previous_move();
		} else {
		    int oldy = history[movecount - 1].y;
		    int oldx = history[movecount - 1].x;

		    if (!board[rw][col]) {
			cellmove(rw, col);
			waddch(boardwin, ' ');
		    }

		    board[oldy][oldx] = FALSE;
		    --movecount;
		    ny = history[movecount - 1].y;
		    nx = history[movecount - 1].x;
		    if (nx < 0 || ny < 0) {
			ny = oldy;
			nx = oldx;
		    }
		    drawmove(' ', oldy, oldx, ny, nx);

		    /* avoid problems if we just changed the current cell */
		    cellmove(lastrow, lastcol);
		    oldch = winch(boardwin);
		}
		break;

	    case 'a':
		nx = col;
		ny = rw;
		find_next_move(&ny, &nx);
		break;

	    case 'F':
		if (review > 0) {
		    review--;
		    ny = history[movecount - review - 1].y;
		    nx = history[movecount - review - 1].x;
		} else {
		    beep();
		}
		break;

	    case 'B':
		if (review < movecount - 2) {
		    review++;
		    ny = history[movecount - review - 1].y;
		    nx = history[movecount - review - 1].x;
		} else {
		    beep();
		}
		break;

	    case KEY_REDO:
	    case '\f':
	    case 'r':
		clearok(curscr, TRUE);
		wnoutrefresh(stdscr);
		wnoutrefresh(boardwin);
		wnoutrefresh(msgwin);
		wnoutrefresh(helpwin);
		doupdate();
		break;

	    case 'q':
	    case 'x':
		goto dropout;

	    case '?':
		show_help(&keyhelp);
		break;

	    default:
		beep();
		break;
	    }

	    col = nx % BWIDTH;
	    rw = ny % BDEPTH;
	}

      dropout:
	if ((count = completed()) < 0)
	    wprintw(msgwin, "\nYou won.  Care to try again? ");
	else
	    wprintw(msgwin, "\n%d squares filled.  Try again? ", count);
	wclrtoeol(msgwin);
    } while
	(tolower(wgetch(msgwin)) == 'y');
}
Ejemplo n.º 29
0
static int
getcoord(int atcpu)
{
    int ny, nx, c;

    if (atcpu)
	cgoto(cury, curx);
    else
	pgoto(cury, curx);
    (void) refresh();
    for (;;) {
	if (atcpu) {
	    (void) mvprintw(CYBASE + BDEPTH + 1, CXBASE + 11, "(%d, %c)",
			    curx, 'A' + cury);
	    cgoto(cury, curx);
	} else {
	    (void) mvprintw(PYBASE + BDEPTH + 1, PXBASE + 11, "(%d, %c)",
			    curx, 'A' + cury);
	    pgoto(cury, curx);
	}

	switch (c = getch()) {
	case 'k':
	case '8':
	case KEY_UP:
	    ny = cury + BDEPTH - 1;
	    nx = curx;
	    break;
	case 'j':
	case '2':
	case KEY_DOWN:
	    ny = cury + 1;
	    nx = curx;
	    break;
	case 'h':
	case '4':
	case KEY_LEFT:
	    ny = cury;
	    nx = curx + BWIDTH - 1;
	    break;
	case 'l':
	case '6':
	case KEY_RIGHT:
	    ny = cury;
	    nx = curx + 1;
	    break;
	case 'y':
	case '7':
	case KEY_A1:
	    ny = cury + BDEPTH - 1;
	    nx = curx + BWIDTH - 1;
	    break;
	case 'b':
	case '1':
	case KEY_C1:
	    ny = cury + 1;
	    nx = curx + BWIDTH - 1;
	    break;
	case 'u':
	case '9':
	case KEY_A3:
	    ny = cury + BDEPTH - 1;
	    nx = curx + 1;
	    break;
	case 'n':
	case '3':
	case KEY_C3:
	    ny = cury + 1;
	    nx = curx + 1;
	    break;
	case FF:
	    nx = curx;
	    ny = cury;
	    (void) clearok(stdscr, TRUE);
	    (void) refresh();
	    break;
#ifdef NCURSES_MOUSE_VERSION
	case KEY_MOUSE:
	    {
		MEVENT myevent;

		getmouse(&myevent);
		if (atcpu
		    && myevent.y >= CY(0) && myevent.y <= CY(BDEPTH)
		    && myevent.x >= CX(0) && myevent.x <= CX(BDEPTH)) {
		    curx = CXINV(myevent.x);
		    cury = CYINV(myevent.y);
		    return (' ');
		} else {
		    beep();
		    continue;
		}
	    }
	    /* no fall through */
#endif /* NCURSES_MOUSE_VERSION */

	default:
	    if (atcpu)
		(void) mvaddstr(CYBASE + BDEPTH + 1, CXBASE + 11, "      ");
	    else
		(void) mvaddstr(PYBASE + BDEPTH + 1, PXBASE + 11, "      ");
	    return (c);
	}

	curx = nx % BWIDTH;
	cury = ny % BDEPTH;
    }
}
Ejemplo n.º 30
0
/* ======================================================= *\ 
 * PIE
 * 
 * Notes:
 *  always drawn from 12:00 position clockwise
 *  'missing' slices don't get labels
 *  sum(val[0], ... val[num_points-1]) is assumed to be 100%
\* ======================================================= */
void
GDC_out_pie( short			IMGWIDTH,
			 short			IMGHEIGHT,
			 FILE			*img_fptr,			/* open file pointer */
			 GDCPIE_TYPE	type,
			 int			num_points,
			 char			*lbl[],				/* data labels */
			 float			val[] )				/* data */
{
	int			i;

	gdImagePtr	im;
	int			BGColor,
				LineColor,
				PlotColor,
				EdgeColor,
				EdgeColorShd;
	CREATE_ARRAY1( SliceColor, int, num_points );		/* int SliceColor[num_points] */
	CREATE_ARRAY1( SliceColorShd, int, num_points );	/* int SliceColorShd[num_points] */

	float		rad = 0.0;					/* radius */
	float		ellipsex = 1.0;
	float		ellipsey = 1.0 - (float)GDCPIE_perspective/100.0;
	float		tot_val = 0.0;
	float		pscl;
	int			cx,							/* affects PX() */
				cy;							/* affects PY() */
								/* ~ 1% for a size of 100 pixs */
								/* label sizes will more dictate this */
	float		min_grphable = ( GDCPIE_other_threshold < 0?
								  100.0/(float)MIN(IMGWIDTH,IMGHEIGHT):
								  (float)GDCPIE_other_threshold )/100.0;
	short		num_slices1 = 0,
				num_slices2 = 0;
	char		any_too_small = FALSE;
	CREATE_ARRAY1( others, char, num_points );			/* char others[num_points] */
	CREATE_ARRAY2( slice_angle, float, 3, num_points );	/* float slice_angle[3][num_points] */
														/* must be used with others[] */
	char		threeD = ( type == GDC_3DPIE );

	int			xdepth_3D      = 0,			/* affects PX() */
				ydepth_3D      = 0;			/* affects PY() */
	int			do3Dx = 0,					/* reserved for macro use */
				do3Dy = 0;

	CREATE_ARRAY2( pct_lbl, char, num_points, 16 );			/* sizeof or strlen (GDCPIE_percent_fmt)? */
	CREATE_ARRAY1( pct_ftsz, struct fnt_sz_t, num_points );	/* struct fnt_sz_t lbl_ftsz[num_points] */
	CREATE_ARRAY1( lbl_ftsz, struct fnt_sz_t, num_points );	/* struct fnt_sz_t lbl_ftsz[num_points] */


#ifdef HAVE_LIBFREETYPE
	char			*gdcpie_title_font  = GDCPIE_title_font;
	char			*gdcpie_label_font  = GDCPIE_label_font;
	double			gdcpie_title_ptsize = GDCPIE_title_ptsize;
	double			gdcpie_label_ptsize = GDCPIE_label_ptsize;
#else
	char			*gdcpie_title_font  = NULL;
	char			*gdcpie_label_font  = NULL;
	double			gdcpie_title_ptsize = 0.0;
	double			gdcpie_label_ptsize = 0.0;
#endif

/*	GDCPIE_3d_angle = MOD_360(90-GDCPIE_3d_angle+360); */
	pie_3D_rad = TO_RAD( GDCPIE_3d_angle );

	xdepth_3D      = threeD? (int)( cos((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0;
	ydepth_3D      = threeD? (int)( sin((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0;
/*	xdepth_3D      = threeD? (int)( cos(pie_3D_rad) * GDCPIE_3d_depth ): 0; */
/*	ydepth_3D      = threeD? (int)( sin(pie_3D_rad) * GDCPIE_3d_depth ): 0; */

	load_font_conversions();

	/* ----- get total value ----- */
	for( i=0; i<num_points; ++i )
		tot_val += val[i];

	/* ----- pie sizing ----- */
	/* ----- make width room for labels, depth, etc.: ----- */
	/* ----- determine pie's radius ----- */
	{
	int		title_hgt  = GDCPIE_title? 1			/*  title? horizontal text line */
									   + GDCfnt_sz( GDCPIE_title,
													GDCPIE_title_size,
													gdcpie_title_font, gdcpie_title_ptsize, 0.0, NULL ).h

									   + 2:
									   0;
	float	last = 0.0;
	float	label_explode_limit = 0.0;
	int		cheight,
			cwidth;

	/* maximum: no labels, explosions */
	/* gotta start somewhere */
	rad = (float)MIN( (IMGWIDTH/2)/ellipsex-(1+ABS(xdepth_3D)), (IMGHEIGHT/2)/ellipsey-(1+ABS(ydepth_3D))-title_hgt );

	/* ok fix center, i.e., no floating re labels, explosion, etc. */
	cx = IMGWIDTH/2 /* - xdepth_3D */ ;
	cy = (IMGHEIGHT-title_hgt)/2 + title_hgt /* + ydepth_3D */ ;

	cheight = (IMGHEIGHT- title_hgt)/2 /* - ydepth_3D */ ;
	cwidth  = cx;

	/* walk around pie. determine spacing to edge */
	for( i=0; i<num_points; ++i )
		{
		float	this_pct = val[i]/tot_val;						/* should never be > 100% */
		float	this = this_pct*(2.0*M_PI);						/* pie-portion */
		if( (this_pct > min_grphable) ||						/* too small */
			(!GDCPIE_missing || !GDCPIE_missing[i]) )			/* still want angles */
			{
			int this_explode = GDCPIE_explode? GDCPIE_explode[i]: 0;
			double	this_sin;
			double	this_cos;
			slice_angle[0][i] = this/2.0+last;				/* mid-point on full pie */
			slice_angle[1][i] = last;						/* 1st on full pie */
			slice_angle[2][i] = this+last;					/* 2nd on full pie */
			this_sin        = ellipsex*sin( (double)slice_angle[0][i] );
			this_cos        = ellipsey*cos( (double)slice_angle[0][i] );

			if( !GDCPIE_missing || !(GDCPIE_missing[i]) )
				{
				short	lbl_wdth = 0,
						lbl_hgt  = 0;
				float	this_y_explode_limit,
						this_x_explode_limit;

				/* start slice label height, width     */
				/*  accounting for PCT placement, font */
				pct_ftsz[i].h = 0;
				pct_ftsz[i].w = 0;
				if( GDCPIE_percent_fmt &&
					GDCPIE_percent_labels != GDCPIE_PCT_NONE )
					{
					sprintf( pct_lbl[i], GDCPIE_percent_fmt, this_pct * 100.0 );
					pct_ftsz[i] = GDCfnt_sz( pct_lbl[i],
											 GDCPIE_label_size,
											 gdcpie_label_font, gdcpie_label_ptsize, 0.0, NULL );
					lbl_wdth = pct_ftsz[i].w;
					lbl_hgt  = pct_ftsz[i].h;
					}

				if( lbl && lbl[i] )
					{
					lbl_ftsz[i] = GDCfnt_sz( lbl[i],
											 GDCPIE_label_size,
											 gdcpie_label_font, gdcpie_label_ptsize, 0.0, NULL );

					if( GDCPIE_percent_labels == GDCPIE_PCT_ABOVE ||
						GDCPIE_percent_labels == GDCPIE_PCT_BELOW )
						{
						lbl_wdth = MAX( pct_ftsz[i].w, lbl_ftsz[i].w );
						lbl_hgt  = pct_ftsz[i].h + lbl_ftsz[i].h + 1;
						}
					else
					if( GDCPIE_percent_labels == GDCPIE_PCT_RIGHT ||
						GDCPIE_percent_labels == GDCPIE_PCT_LEFT )
						{
						lbl_wdth = pct_ftsz[i].w + lbl_ftsz[i].w + 1;
						lbl_hgt  = MAX( pct_ftsz[i].h, lbl_ftsz[i].h );
						}
					else /* GDCPIE_PCT_NONE */
						{
						lbl_wdth = lbl_ftsz[i].w;
						lbl_hgt  = lbl_ftsz[i].h;
						}
					}
				else
					lbl_wdth = lbl_hgt = 0;
				/* end label height, width */
				
				/* diamiter limited by this point's: explosion, label                 */
				/* (radius to box @ slice_angle) - (explode) - (projected label size) */
				/* radius constraint due to labels */
				this_y_explode_limit = (float)this_cos==0.0? FLT_MAX:
										(	(float)( (double)cheight/ABS(this_cos) ) - 
											(float)( this_explode + (lbl&&lbl[i]? GDCPIE_label_dist: 0) ) -
											(float)( lbl_hgt/2 ) / (float)ABS(this_cos)	);
				this_x_explode_limit = (float)this_sin==0.0? FLT_MAX:
										(	(float)( (double)cwidth/ABS(this_sin) ) - 
											(float)( this_explode + (lbl&&lbl[i]? GDCPIE_label_dist: 0) ) -
											(float)( lbl_wdth ) / (float)ABS(this_sin)	);

				rad = MIN( rad, this_y_explode_limit );
				rad = MIN( rad, this_x_explode_limit );

				/* ok at this radius (which is most likely larger than final) */
				/* adjust for inter-label spacing */
/*				if( lbl[i] && *lbl[i] ) */
/*					{ */
/*					char which_edge = slice_angle[0][i] > M_PI? +1: -1;		// which semi */
/*					last_label_yedge = cheight - (int)( (rad +				// top or bottom of label */
/*														(float)(this_explode + */
/*														(float)GDCPIE_label_dist)) * (float)this_cos ) + */
/*											     ( (GDC_fontc[GDCPIE_label_size].h+1)/2 + */
/*													GDC_label_spacing )*which_edge; */
/*					} */

				/* radius constriant due to exploded depth */
				/* at each edge of the slice, and the middle */
				/* this is really stupid */
				/*  this section uses a different algorithm then above, but does the same thing */
				/*  could be combined, but each is ugly enough! */
/* PROTECT /0 */
				if( threeD )
					{
					short	j;
					int		this_y_explode_pos;
					int		this_x_explode_pos;

					/* first N E S W (actually no need for N) */
					if( (slice_angle[1][i] < M_PI_2 && M_PI_2 < slice_angle[2][i]) &&				/* E */
						(this_x_explode_pos=OX(i,M_PI_2,1)) > cx+cwidth )
						rad -= (float)ABS( (double)(1+this_x_explode_pos-(cx+cwidth))/sin(M_PI_2) );
					if( (slice_angle[1][i] < 3.0*M_PI_2 && 3.0*M_PI_2 < slice_angle[2][i]) &&		/* W */
						(this_x_explode_pos=OX(i,3.0*M_PI_2,1)) < cx-cwidth )
						rad -= (float)ABS( (double)(this_x_explode_pos-(cx+cwidth))/sin(3.0*M_PI_2) );
					if( (slice_angle[1][i] < M_PI && M_PI < slice_angle[2][i]) &&					/* S */
						(this_y_explode_pos=OY(i,M_PI,1)) > cy+cheight )
						rad -= (float)ABS( (double)(1+this_y_explode_pos-(cy+cheight))/cos(M_PI) );

					for( j=0; j<3; ++j )
						{
						this_y_explode_pos = IY(i,j,1);
						if( this_y_explode_pos < cy-cheight )
							rad -= (float)ABS( (double)((cy-cheight)-this_y_explode_pos)/cos((double)slice_angle[j][i]) );
						if( this_y_explode_pos > cy+cheight )
							rad -= (float)ABS( (double)(1+this_y_explode_pos-(cy+cheight))/cos((double)slice_angle[j][i]) );

						this_x_explode_pos = IX(i,j,1);
						if( this_x_explode_pos < cx-cwidth )
							rad -= (float)ABS( (double)((cx-cwidth)-this_x_explode_pos)/sin((double)slice_angle[j][i]) );
						if( this_x_explode_pos > cx+cwidth )
							rad -= (float)ABS( (double)(1+this_x_explode_pos-(cx+cwidth))/sin((double)slice_angle[j][i]) );
						}
					}
				}
			others[i] = FALSE;
			}
		else
			{
			others[i] = TRUE;
			slice_angle[0][i] = -FLT_MAX;
			}
		last += this;
		}
	}

	/* ----- go ahead and start the image ----- */
	im = gdImageCreate( IMGWIDTH, IMGHEIGHT );

	/* --- allocate the requested colors --- */
	BGColor   = clrallocate( im, GDCPIE_BGColor );
	LineColor = clrallocate( im, GDCPIE_LineColor );
	PlotColor = clrallocate( im, GDCPIE_PlotColor );
	if( GDCPIE_EdgeColor != GDC_NOCOLOR )
	 {
	 EdgeColor = clrallocate( im, GDCPIE_EdgeColor );
	 if( threeD )
	  EdgeColorShd = clrshdallocate( im, GDCPIE_EdgeColor );
	 }

	/* --- set color for each slice --- */
	for( i=0; i<num_points; ++i )
		if( GDCPIE_Color )
			{
			unsigned long	slc_clr = GDCPIE_Color[i];

			SliceColor[i]     = clrallocate( im, slc_clr );
			if( threeD )
			 SliceColorShd[i] = clrshdallocate( im, slc_clr );
			}
		else
			{
			SliceColor[i]     = PlotColor;
			if( threeD )
			 SliceColorShd[i] = clrshdallocate( im, GDCPIE_PlotColor );
			}

	pscl = (2.0*M_PI)/tot_val;
	
	/* ----- calc: smallest a slice can be ----- */
	/* 1/2 circum / num slices per side. */
	/*              determined by number of labels that'll fit (height) */
	/* scale to user values */
	/* ( M_PI / (IMGHEIGHT / (SFONTHGT+1)) ) */
/*	min_grphable = tot_val / */
/*				   ( 2.0 * (float)IMGHEIGHT / (float)(SFONTHGT+1+TFONTHGT+2) ); */


	if( threeD )
		{
		/* draw background shaded pie */
		{
		float	rad1 = rad * 3.0/4.0;
		for( i=0; i<num_points; ++i )
			if( !(others[i]) &&
				(!GDCPIE_missing || !GDCPIE_missing[i]) )
				{
				int		edge_color = GDCPIE_EdgeColor == GDC_NOCOLOR? SliceColorShd[i]:
				                                                      EdgeColorShd;

				gdImageLine( im, CX(i,1), CY(i,1), IX(i,1,1), IY(i,1,1), edge_color );
				gdImageLine( im, CX(i,1), CY(i,1), IX(i,2,1), IY(i,2,1), edge_color );
				gdImageArc( im, CX(i,1), CY(i,1),
								(int)(rad*ellipsex*2.0), (int)(rad*ellipsey*2.0),
								TO_INT_DEG_FLOOR(slice_angle[1][i])+270,
								TO_INT_DEG_CEIL(slice_angle[2][i])+270,
								edge_color );
					
/*				gdImageFilledArc( im, CX(i,1), CY(i,1), */
/*									  rad*ellipsex*2, rad*ellipsey*2, */
/*									  TO_INT_DEG_FLOOR(slice_angle[1][i])+270, */
/*									  TO_INT_DEG_CEIL(slice_angle[2][i])+270, */
/*									  SliceColorShd[i], */
/*									  gdPie ); */
				/* attempt to fill, if slice is wide enough */
				if( (ABS(IX(i,1,1)-IX(i,2,1)) + ABS(IY(i,1,1)-IY(i,2,1))) > 2 )
					{
					float	rad = rad1;										/* local override */
					gdImageFillToBorder( im, IX(i,0,1), IY(i,0,1), edge_color, SliceColorShd[i] );
					}
				}
		}
		/* fill in connection to foreground pie */
		/* this is where we earn our keep */
		{
		int					t,
							num_slice_angles = 0;
		CREATE_ARRAY1( tmp_slice, struct tmp_slice_t, 4*num_points+4 );		/* should only need 2*num_points+2 */

		for( i=0; i<num_points; ++i )
			if( !GDCPIE_missing || !GDCPIE_missing[i] )
				{
				if( RAD_DIST1(slice_angle[1][i]) < RAD_DIST2(slice_angle[0][i]) )
					tmp_slice[num_slice_angles].hidden = FALSE;
				else
					tmp_slice[num_slice_angles].hidden = TRUE;
				tmp_slice[num_slice_angles].i       = i;
				tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
				tmp_slice[num_slice_angles++].angle = slice_angle[1][i];
				if( RAD_DIST1(slice_angle[2][i]) < RAD_DIST2(slice_angle[0][i]) )
					tmp_slice[num_slice_angles].hidden = FALSE;
				else
					tmp_slice[num_slice_angles].hidden = TRUE;
				tmp_slice[num_slice_angles].i       = i;
				tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
				tmp_slice[num_slice_angles++].angle = slice_angle[2][i];
				/* identify which 2 slices (i) have a tangent parallel to depth angle  */
				if( slice_angle[1][i]<MOD_2PI(pie_3D_rad+M_PI_2) && slice_angle[2][i]>MOD_2PI(pie_3D_rad+M_PI_2) )
					{
					tmp_slice[num_slice_angles].i       = i;
					tmp_slice[num_slice_angles].hidden  = FALSE;
					tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
					tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+M_PI_2 );
					}
				if( slice_angle[1][i]<MOD_2PI(pie_3D_rad+3.0*M_PI_2) && slice_angle[2][i]>MOD_2PI(pie_3D_rad+3.0*M_PI_2) )
					{
					tmp_slice[num_slice_angles].i       = i;
					tmp_slice[num_slice_angles].hidden  = FALSE;
					tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
					tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+3.0*M_PI_2 );
					}
				}

		qsort( tmp_slice, num_slice_angles, sizeof(struct tmp_slice_t), ocmpr );
		for( t=0; t<num_slice_angles; ++t )
			{
			gdPoint	gdp[4];

			i = tmp_slice[t].i;

			gdp[0].x  = CX(i,0);					gdp[0].y = CY(i,0);
			gdp[1].x  = CX(i,1);					gdp[1].y = CY(i,1);
			gdp[2].x  = OX(i,tmp_slice[t].angle,1);	gdp[2].y = OY(i,tmp_slice[t].angle,1);
			gdp[3].x  = OX(i,tmp_slice[t].angle,0);	gdp[3].y = OY(i,tmp_slice[t].angle,0);

			if( !(tmp_slice[t].hidden) )
				gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
			else
				{
				rad -= 2.0;										/* no peeking */
				gdp[0].x  = OX(i,slice_angle[0][i],0);	gdp[0].y = OY(i,slice_angle[0][i],0);
				gdp[1].x  = OX(i,slice_angle[0][i],1);	gdp[1].y = OY(i,slice_angle[0][i],1);
				rad += 2.0;
				gdp[2].x  = OX(i,slice_angle[1][i],1);	gdp[2].y = OY(i,slice_angle[1][i],1);
				gdp[3].x  = OX(i,slice_angle[1][i],0);	gdp[3].y = OY(i,slice_angle[1][i],0);
				gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
				gdp[2].x  = OX(i,slice_angle[2][i],1);	gdp[2].y = OY(i,slice_angle[2][i],1);
				gdp[3].x  = OX(i,slice_angle[2][i],0);	gdp[3].y = OY(i,slice_angle[2][i],0);
				gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
				}
				

			if( GDCPIE_EdgeColor != GDC_NOCOLOR )
				{
				gdImageLine( im, CX(i,0), CY(i,0), CX(i,1), CY(i,1), EdgeColorShd );
				gdImageLine( im, OX(i,tmp_slice[t].angle,0), OY(i,tmp_slice[t].angle,0),
								 OX(i,tmp_slice[t].angle,1), OY(i,tmp_slice[t].angle,1),
								 EdgeColorShd );
				}
			}
		FREE_ARRAY1( tmp_slice );
		}
		}


	/* ----- pie face ----- */
	{
	/* float	last = 0.0; */
	float	rad1 = rad * 3.0/4.0;
	for( i=0; i<num_points; ++i )
		if( !others[i] &&
			(!GDCPIE_missing || !GDCPIE_missing[i]) )
			{
			int		edge_color = GDCPIE_EdgeColor == GDC_NOCOLOR? SliceColor[i]:
																  EdgeColorShd;
			/* last += val[i]; */
			/* EXPLODE_CX_CY( slice_angle[0][i], i ); */
			gdImageLine( im, CX(i,0), CY(i,0), IX(i,1,0), IY(i,1,0), edge_color );
			gdImageLine( im, CX(i,0), CY(i,0), IX(i,2,0), IY(i,2,0), edge_color );
			gdImageArc( im, CX(i,0), CY(i,0), 
							(int)(rad*ellipsex*2.0), (int)(rad*ellipsey*2.0),
							(TO_INT_DEG_FLOOR(slice_angle[1][i])+270)%360,
							(TO_INT_DEG_CEIL(slice_angle[2][i])+270)%360,
							edge_color );
			/* antialiasing here */
			/* likely only on the face? */
/* bugs in gd2.0.0 */
/*	arc doesn't honor deg>360 */
/*	arcs from gdImageFilledArc() don't match with gdImageArc() */
/*	angles are off */
/*	doesn't always fill completely */
/*			gdImageFilledArc( im, CX(i,0), CY(i,0),  */
/*								  (int)(rad*ellipsex*2.0), (int)(rad*ellipsey*2.0), */
/*								  (TO_INT_DEG_FLOOR(slice_angle[1][i])+270)%360, */
/*								  (TO_INT_DEG_CEIL(slice_angle[2][i])+270)%360, */
/*								  SliceColor[i], */
/*								  gdPie ); */
			/* attempt to fill, if slice is wide enough */
			{
			float	rad = rad1;										/* local override */
			if( (ABS(IX(i,1,1)-IX(i,2,1)) + ABS(IY(i,1,1)-IY(i,2,1))) > 2 )
				{
				gdImageFillToBorder( im, IX(i,0,0), IY(i,0,0), edge_color, SliceColor[i] );
				}
			/* catch missed pixels on narrow slices */
			gdImageLine( im, CX(i,0), CY(i,0), IX(i,0,0), IY(i,0,0), SliceColor[i] );
			}
			}
	}

	if( GDCPIE_title )
		{
		struct fnt_sz_t	tftsz      = GDCfnt_sz( GDCPIE_title,
												GDCPIE_title_size,
												gdcpie_title_font, gdcpie_title_ptsize, 0.0, NULL );
		GDCImageStringNL( im,
						  &GDC_fontc[GDCPIE_title_size],
						  gdcpie_title_font, gdcpie_title_ptsize,
						  0.0,
						  IMGWIDTH/2 - tftsz.w/2,
						  1,
						  GDCPIE_title,
						  LineColor,
						  GDC_JUSTIFY_CENTER,
						  NULL );
		}

	/* labels */
	if( lbl )
		{
		float	liner = rad;

		rad += GDCPIE_label_dist;
		for( i=0; i<num_points; ++i )
			{
			if( !others[i] &&
				(!GDCPIE_missing || !GDCPIE_missing[i]) )
				{
				int		lblx,  pctx,
						lbly,  pcty,
						linex, liney;

				lbly = (liney = IY(i,0,0))-lbl_ftsz[i].h / 2;
				lblx = pctx = linex = IX(i,0,0);

				if( slice_angle[0][i] > M_PI )								/* which semicircle */
					{
					lblx -= lbl_ftsz[i].w;
					pctx = lblx;
					++linex;
					}
				else
					--linex;

				switch( GDCPIE_percent_labels )
					{
					case GDCPIE_PCT_LEFT:	if( slice_angle[0][i] > M_PI )
												pctx -= lbl_ftsz[i].w-1;
											else
												lblx += pct_ftsz[i].w+1;
											pcty = IY(i,0,0) - ( 1+pct_ftsz[i].h ) / 2;
											break;
					case GDCPIE_PCT_RIGHT:	if( slice_angle[0][i] > M_PI )
												lblx -= pct_ftsz[i].w-1;
											else
												pctx += lbl_ftsz[i].w+1;
											pcty = IY(i,0,0) - ( 1+pct_ftsz[i].h ) / 2;
											break;
					case GDCPIE_PCT_ABOVE:	lbly += (1+pct_ftsz[i].h) / 2;
											pcty = lbly - pct_ftsz[i].h;
											break;
					case GDCPIE_PCT_BELOW:	lbly -= (1+pct_ftsz[i].h) / 2;
											pcty = lbly + lbl_ftsz[i].h;
											break;
					case GDCPIE_PCT_NONE:
					default:;
					}

				if( GDCPIE_percent_labels != GDCPIE_PCT_NONE )
					GDCImageStringNL( im,
									  &GDC_fontc[GDCPIE_label_size],
									  gdcpie_label_font, gdcpie_label_ptsize,
									  0.0,
									  slice_angle[0][i] <= M_PI? pctx:
																 pctx+lbl_ftsz[i].w-pct_ftsz[i].w,
									  pcty,
									  pct_lbl[i],
									  LineColor,
									  GDC_JUSTIFY_CENTER,
									  NULL );
				if( lbl[i] )
					GDCImageStringNL( im,
									  &GDC_fontc[GDCPIE_label_size],
									  gdcpie_label_font, gdcpie_label_ptsize,
									  0.0,
									  lblx,
									  lbly,
									  lbl[i],
									  LineColor,
									  slice_angle[0][i] <= M_PI? GDC_JUSTIFY_LEFT:
																 GDC_JUSTIFY_RIGHT,
									  NULL );
				if( GDCPIE_label_line )
					{
					float	rad = liner;
					gdImageLine( im, linex, liney, IX(i,0,0), IY(i,0,0), LineColor );
					}
				}
			}
		rad -= GDCPIE_label_dist;
		}

		fflush( img_fptr );
		switch( GDC_image_type )
			{
#ifdef HAVE_JPEG
			case GDC_JPEG:	gdImageJpeg( im, img_fptr, GDC_jpeg_quality );	break;
#endif
			case GDC_WBMP:	gdImageWBMP( im, PlotColor, img_fptr );			break;
			case GDC_GIF:	gdImageGif( im, img_fptr);						break;
			case GDC_PNG:
			default:		gdImagePng( im, img_fptr );
			}

	FREE_ARRAY1( lbl_ftsz );
	FREE_ARRAY1( pct_ftsz );
	FREE_ARRAY2( pct_lbl );

	FREE_ARRAY2( slice_angle );
	FREE_ARRAY1( others );

	FREE_ARRAY1( SliceColorShd );
	FREE_ARRAY1( SliceColor );
	gdImageDestroy(im);
	return;
}