コード例 #1
0
ファイル: MinimizerBase.cpp プロジェクト: ykimbiology/smm
double CMinimizerBase::LineMinimizer(CNumVec &position, double dist0, const CNumVec &direction, bool roughly)
{
	LM_direction=&direction;
	LM_start_pos=&position;

	double pleft, pmin, pright, pnext;
	double dleft, dmin, dright, dnext;

	pleft=0;
	dleft=dist0;
	pnext=1;
	dnext=LineDistance(pnext);

	if(dleft<dnext) // minimum is less than precision (= gradient norm) deep
		return(dist0);

	// try to bracket a minimum along "direction" 
	pmin=pleft;
	dmin=dleft;
	do
	{
		pleft=pmin;
		dleft=dmin;

		pmin=pnext;
		dmin=dnext;

		pnext*=2;
		dnext=LineDistance(pnext);
	}
	while(dmin>dnext);

	if(roughly && pmin>50) // stops exact determination if minimum is far from optimal value
	{
		CNumVec p=direction;
		p*=pleft;
		position+=p;
		return(dmin);
	}
	pright=pnext;
	dright=dnext;

	// Further bracket minimum using "GoldenCut"
	// Ideally this should be replaced by some function taking into account the
	// pretty good reproducible function along the line minimization

	bool longer_interval_right=true;

	while(pright-pleft>1.0)
	{
		if(longer_interval_right)
		{
			pnext=pmin+(pright-pmin)*0.38;
			dnext=LineDistance(pnext);

			if(dnext<dmin)
			{
				pleft=pmin;
				dleft=dmin;
				
				pmin=pnext;
				dmin=dnext;
			}
			else
			{
				pright=pnext;
				dright=dnext;
				longer_interval_right=false;
			}
		}
		else
		{
			pnext=pmin+(pleft-pmin)*0.38;
			dnext=LineDistance(pnext);

			if(dnext<dmin)
			{
				pright=pmin;
				dright=dmin;

				pmin=pnext;
				dmin=dnext;
			}
			else
			{
				pleft=pnext;
				dleft=dnext;
				longer_interval_right=true;
			}
		}
	}
	// Change 'position to Minimum position 
	CNumVec p=direction;
	p*=pmin;
	position+=p;
	return(dmin);
}
コード例 #2
0
int
checkwalls( World *w, View *v  )
{
  extern fixed view_height;
  Wall   *wall = (Wall *) w->walls->table, *mem_wall;
  double  x1, y1, tmp, min = 512.0;
  int i;

  x1 = FIXED_TO_FLOAT(v->x);
  y1 = FIXED_TO_FLOAT(v->y);

  if ( x1 == x && y1 == y )
    return DONT_INTERSECT;

  for (i = 0; i < TABLE_SIZE(w->walls); i++, wall++ ) {

    /* Check Distance */
    tmp = LineDistance( x1, y1, 
	    FIXED_TO_FLOAT(wall->vertex1->x ), 
	    FIXED_TO_FLOAT(wall->vertex1->y ), 
	    FIXED_TO_FLOAT(wall->vertex2->x ), 
	    FIXED_TO_FLOAT(wall->vertex2->y ) );

    if ( fabs(tmp) < fabs( min ) )
      {
	min      = tmp;
	mem_wall = wall; 
      }

  }

  /* is there any point in checking further. */
  if ( fabs( min ) < VECTOR_LEN  )  
    {
      /* start examine the wall */
      fixed ceiling, floor;

      /* Check the outher side of the object */
      if ( min > 0.0 )
	{
	  floor      = mem_wall->front->floor;
	  ceiling    = mem_wall->front->ceiling;
	}
      else
	{
	  floor      = mem_wall->back->floor;
	  ceiling    = mem_wall->back->ceiling;
	}

      /* if the stair is less than FIXED_ONE_QUARTER and the
	 head has goes free and there are enought room. */
      if ( FIXED_ONE_QUARTER >= (floor-v->height) && ( ceiling > v->height ) &&
	  ( MAN_SIZE <= (ceiling-floor) ) ) {
	if ( s_wall != mem_wall || ( min > 0.0 && side <= 0.0 ) ||
	    (min <= 0.0 && side > 0.0 ) )
	  {
	    if ( min < 0.0 )
	      view_height = mem_wall->front->floor+MAN_SIZE;
	    else
	      view_height = mem_wall->back->floor+MAN_SIZE;

	    s_wall       = mem_wall;
	  }
        }
      else
	/* am i running towards the wall? */
	if ( fabs( min ) < fabs( side ) )
	  {

	     s_wall = mem_wall;
	     slide_wall( &x, &y, x1, y1, side, min );

	     v->x   = FLOAT_TO_FIXED( x );
	     v->y   = FLOAT_TO_FIXED( y );

	     return 0;
	  }  
    }

  side = min;
  x    = x1;
  y    = y1;

  return 0;
}