示例#1
0
  Vec2f VertexOrientation2DF0D::operator()(Interface0DIterator& iter) {
    Vec2f A,C;
    Vec2f B(iter->getProjectedX(), iter->getProjectedY());
    if(iter.isBegin())
      A = Vec2f(iter->getProjectedX(), iter->getProjectedY());
    else
      {
	Interface0DIterator previous = iter;
	--previous ;
	A = Vec2f(previous->getProjectedX(), previous->getProjectedY());
      }
    Interface0DIterator next = iter;
    ++next ;
    if(next.isEnd())
      C = Vec2f(iter->getProjectedX(), iter->getProjectedY());
    else
      C = Vec2f(next->getProjectedX(), next->getProjectedY());

    Vec2f AB(B-A);
    if(AB.norm() != 0)
      AB.normalize();
    Vec2f BC(C-B);
    if(BC.norm() != 0)
      BC.normalize();
    Vec2f res (AB + BC);
    if(res.norm() != 0)
      res.normalize();
    return res;
  }
示例#2
0
//==============================================================
Vec2f FishEyesScreen::project(const Vec2f &p) const {
  Vec2f dir = p - fisheyesCenter;
  float rho_s = fabs(dir.norm());

  if (rho_s > 1E-6) {
    dir /= rho_s;
    float rho = projectRho(rho_s, R, k);
    dir *= rho;
  }

  Vec2f result = fisheyesCenter + dir;
  return result;
}
示例#3
0
//==============================================================
Vec2f FishEyesScreen::unproject(const Vec2f &p) const {
  Vec2f dir = p - fisheyesCenter;
  double rho_s = fabs(dir.norm());

  if (rho_s > 1E-6) {
    dir /= rho_s;
    double rho = unprojectRho(rho_s, R, k);

    if (fabs(rho - rho_s) < 1E-6)
      return p;

    dir *= rho;
  }

  Vec2f result = fisheyesCenter + dir;
  return result;
}
// Handle obstacles in a generic way by post-adjusting a set of commanded game vars
bool WAKGameShared::obstacleBallHandling(GameVars& GV) const
{
	// Plot that obstacle ball handling is not active for the case that this function returns early
	if(config.plotData())
		PM.plotScalar(false * PMSCALE_LEGAL, PM_OBH_ACTIVE);

	// Don't do anything if obstacle avoidance is disabled or we don't have a ball
	if(!config.sEnableObstacles() || !config.obhEnableObstBallHandling() || !SV.haveBall)
		return false;

	// Don't do anything if the closest obstacle is not valid
	if(!SV.obstClosest.valid())
		return false;

	// Calculate the ball to target unit vector
	Vec2f ballToTargetVec = GV.ballTargetDir - SV.ballDir;
	float ballToTargetDist = ballToTargetVec.norm();
	if(ballToTargetDist <= 0.0f)
		return false;
	Vec2f txhat = ballToTargetVec / ballToTargetDist;

	// Calculate the ball to obstacle unit vectors
	Vec2f ballToObstVec = SV.obstClosest.vec - SV.ballDir;
	float ballToObstDist = ballToObstVec.norm();
	if(ballToObstDist <= 0.0f || ballToObstDist >= std::min(config.kickMaxDist(), ballToTargetDist + config.obhObstBeyondTargetBuf()))
		return false;
	Vec2f oxhat = ballToObstVec / ballToObstDist;
	Vec2f oyhat = eigenRotatedCCW90(oxhat);

	// Calculate the angle at the ball from the obstacle to the ball target
	float angleAtBall = atan2(txhat.dot(oyhat), txhat.dot(oxhat));
	bool ballBehindObst = (fabs(angleAtBall) > M_PI_2);
	if(ballBehindObst && ballToObstDist > config.obhObstBeforeBallBuf())
		return false;

	// Wrap the angle at the ball to (-pi/2, pi/2] by factors of pi and adjust for the sign
	float angleAtBallStd = angleAtBall;
	if(angleAtBallStd > M_PI_2)
		angleAtBallStd -= M_PI;
	if(angleAtBallStd <= -M_PI_2)
		angleAtBallStd += M_PI;
	int angleAtBallStdSign = sign(angleAtBallStd);
	angleAtBallStd = fabs(angleAtBallStd);

	// Calculate the high and low angles at the ball, and the appropriate difference
	float angleAtBallHigh = coerce<float>(asin(coerceAbs(config.obhObstClearanceHigh() / ballToObstDist, 1.0f)), 0.0f, config.obhClearanceAngleHighMax());
	float angleAtBallLow = coerce<float>(asin(coerceAbs(config.obhObstClearanceLow() / ballToObstDist, 1.0f)), 0.0f, std::min(angleAtBallHigh, config.obhClearanceAngleLowMax()));

	// Calculate the angle to adjust the target angle by
	float angleAtBallDiff = angleAtBallHigh - angleAtBallLow;
	float targetAngleAdjust = 0.0f;
	if(angleAtBallStd < angleAtBallLow)
		targetAngleAdjust = angleAtBallStdSign * interpolateCoerced(0.0f, angleAtBallLow, 0.0f, angleAtBallDiff, angleAtBallStd);
	else if(angleAtBallStd < angleAtBallHigh)
		targetAngleAdjust = angleAtBallStdSign * interpolateCoerced(angleAtBallLow, angleAtBallHigh, angleAtBallDiff, 0.0f, angleAtBallStd);
	float targetAngleAdjustAbs = fabs(targetAngleAdjust);

	// Calculate the angle adjust limits for dribbling and foot selection
	float angleAdjustForDribble = coerceMin(0.5f * GV.ballTargetWedge * config.obhAngleAdjustWedgeRatio(), 0.0f);
	float angleAdjustForFootSel = config.obhAngleAdjustForFootSel();

	// See whether the obstacle is blocking
	bool obstMightBlock = (angleAtBallDiff > angleAdjustForDribble);
	bool obstIsBlocking = (obstMightBlock && (angleAtBallStd < angleAtBallLow || targetAngleAdjustAbs > angleAdjustForDribble));

	// Disable kick and suggest a foot to use if the obstacle is blocking
	bool kickIfPossible = !obstIsBlocking;
	GameVars::FootSelection suggestFoot = GameVars::FS_EITHER_FOOT;
	if(obstIsBlocking && ballToObstDist < config.obhFootSelObstBallDistMax())
	{
		if(targetAngleAdjust > angleAdjustForFootSel)
			suggestFoot = (ballBehindObst ? GameVars::FS_LEFT_FOOT : GameVars::FS_RIGHT_FOOT);
		else if(targetAngleAdjust < -angleAdjustForFootSel)
			suggestFoot = (ballBehindObst ? GameVars::FS_RIGHT_FOOT : GameVars::FS_LEFT_FOOT);
	}

	// Decide whether the obstacle ball handling has to make an adjustment to the game variables
	bool adjustNotNeeded = (targetAngleAdjustAbs <= 0.0f && kickIfPossible && suggestFoot == GameVars::FS_EITHER_FOOT);

	// Plotting
	if(config.plotData())
	{
		PM.plotScalar(!adjustNotNeeded * PMSCALE_LEGAL, PM_OBH_ACTIVE);
		PM.plotScalar(ballToObstDist, PM_OBH_BALLTOOBSTDIST);
		PM.plotScalar(angleAtBallLow, PM_OBH_ANGLEATBALLLOW);
		PM.plotScalar(angleAtBallHigh, PM_OBH_ANGLEATBALLHIGH);
		PM.plotScalar(angleAtBallStd, PM_OBH_ANGLEATBALLSTD);
		PM.plotScalar(targetAngleAdjust, PM_OBH_TARGETANGLEADJUST);
		PM.plotScalar(angleAdjustForDribble, PM_OBH_ANGLEADJUSTFORDRIBBLE);
		PM.plotScalar(angleAdjustForFootSel, PM_OBH_ANGLEADJUSTFORFOOTSEL);
		PM.plotScalar(kickIfPossible * PMSCALE_KICK, PM_OBH_KICKIFPOSSIBLE);
		PM.plotScalar(suggestFoot, PM_OBH_SUGGESTFOOT);
	}

	// If no adjustment is required then we are fine
	if(adjustNotNeeded)
		return false;

	// Calculate the new ball target as a rotation of the nominal ball target
	Vec2f ballToTargetVecDes = eigenRotatedCCW(ballToTargetVec, targetAngleAdjust);
	Vec2f ballTargetVec = SV.ballDir + ballToTargetVecDes;

	// Update the game variables
	GV.ballTargetDir = ballTargetVec;
	if(GV.kickIfPossible)
		GV.kickIfPossible = kickIfPossible;
	if(GV.suggestFoot == GameVars::FS_EITHER_FOOT)
		GV.suggestFoot = suggestFoot;

	// Return that the game variables were modified
	return true;
}