Example #1
0
// Wall2D의 노말벡터가 블럭의 바깥을 바라보게 한다
void CBlock::CalculateNormal()
{
	// 중점을 구한다
	Vector2D center(0,0);
	list<Wall2D*>::iterator itor = m_WallList.begin();
	while (itor != m_WallList.end())
	{
		center += (*itor)->From();
		++itor;
	}

	center /= (float)m_WallList.size();

	// 중점과 노말벡터가 마주본다면 반전시킨다
	itor = m_WallList.begin();
	while (itor != m_WallList.end())
	{
		Vector2D line = (*itor)->From() + (*itor)->To();
		line /= 2.f;
		const Vector2D centerToLine = line - center;
		const double dot = centerToLine.Dot((*itor)->Normal());

		if (dot <= 0.f)
		{
			Vector2D to = (*itor)->To();
			(*itor)->SetTo((*itor)->From());
			(*itor)->SetFrom(to);
		}
		++itor;
	}

}
//------------------------------ Pursuit ---------------------------------
//
//  this behavior creates a force that steers the agent towards the 
//  evader
//------------------------------------------------------------------------
Vector2D SteeringBehavior::Pursuit(const Vehicle* evader)
{
	//if the evader is ahead and facing the agent then we can just seek
	//for the evader's current position.
	Vector2D ToEvader = evader->Pos() - m_pVehicle->Pos();

	double RelativeHeading = m_pVehicle->Heading().Dot(evader->Heading());

	if ((ToEvader.Dot(m_pVehicle->Heading()) > 0) &&
		(RelativeHeading < -0.95))  //acos(0.95)=18 degs
	{
		return Seek(evader->Pos());
	}

	//Not considered ahead so we predict where the evader will be.

	//the lookahead time is propotional to the distance between the evader
	//and the pursuer; and is inversely proportional to the sum of the
	//agent's velocities
	double LookAheadTime = ToEvader.Length() /
		(m_pVehicle->MaxSpeed() + evader->Speed());

	//now seek to the predicted future position of the evader
	return Seek(evader->Pos() + evader->Velocity() * LookAheadTime);
}
Example #3
0
Vector2D Vector2D::Reflect(const Vector2D & v, const Vector2D &a) {
	Vector2D n = Normal(a);
	float co = -2 * ((float)v.Dot(n) / (n.Magnitude() * n.Magnitude()));
	Vector2D r = {};
	r.x = v.x + co * n.x;
	r.y = r.y + co * n.y;
	return r;
}
Example #4
0
//------------------------- WithinFieldOfView ---------------------------
//
//  returns true if subject is within field of view of this player
//-----------------------------------------------------------------------
bool PlayerBase::PositionInFrontOfPlayer(Vector2D position)const
{
  Vector2D ToSubject = position - Pos();

  if (ToSubject.Dot(Heading()) > 0) 
    
    return true;

  else

    return false;
}
Vector2D B020612E_Steering::PointToLocalSpace(const Vector2D &point, Vector2D &AgentHeading, Vector2D &AgentSide, Vector2D &AgentPosition)
{
	//make a copy of the point
	Vector2D TransPoint = point;

	//create a transformation matrix
	C2DMatrix matTransform;

	double Tx = -AgentPosition.Dot(AgentHeading);
	double Ty = -AgentPosition.Dot(AgentSide);

	//create the transformation matrix
	matTransform._11(AgentHeading.x); matTransform._12(AgentSide.x);
	matTransform._21(AgentHeading.y); matTransform._22(AgentSide.y);
	matTransform._31(Tx);           matTransform._32(Ty);

	//now transform the vertices
	matTransform.TransformVector2Ds(TransPoint);

	return TransPoint;
}
Vector2D B020612E_Steering::Pursuit(Vector2D target, Vector2D velocity)
{
	Vector2D targetPos = _pTank->mTargetPosition;
	double relative = _pTank->GetHeading().Dot(_pTank->mEnHeading);

	if ((targetPos.Dot(_pTank->GetHeading()) > 0) && (relative < -0.95))
		return Seek(targetPos);
	else
	{
		double lookAheadTime = targetPos.Length() / (_pTank->GetMaxSpeed() + _pTank->mEnSpeed);
		return Seek(targetPos + _pTank->mEnVel * lookAheadTime);
	}
}
Example #7
0
void DumbTank::Update(float deltaTime, SDL_Event e)
{
	//This is a dumb tank. Do NOT copy this approach.

	//Did we see a tank?
	if(mTanksICanSee.size() == 0)
	{
		ChangeState(TANKSTATE_IDLE);

		//If there are no visible tanks, then keep moving.

		//Check if we reached position before turning.
		if(mPosition.y < mPosition1.y && mHeading.y != -1.0f)
		{
			mHeading = Vector2D(0.0f, -1.0f);
			mRotationAngle = 180.0f;
			mVelocity = Vector2D();
			return;
		}
		else if(mPosition.y > mPosition2.y && mHeading.y != 1.0f)
		{
			mHeading = Vector2D(0.0f, 1.0f);
			mRotationAngle = 0.0f;
			mVelocity = Vector2D();
			return;
		}
		else
		{
			//Move if we are facing the correct direction.
			mCurrentSpeed -= kSpeedIncrement*deltaTime;
			if(mCurrentSpeed < -GetMaxSpeed())
				mCurrentSpeed = -GetMaxSpeed();
		}
	}
	else
	{
		//Rotate man to face enemy tank.
		Vector2D toTarget = mTanksICanSee[0]->GetCentralPosition()-GetCentralPosition();
		toTarget.Normalize();
		double dot = toTarget.Dot(mManFireDirection);
		if(dot < 0.95f)
			RotateManByRadian(kManTurnRate, -1, deltaTime);

		//Otherwise stop moving and fire at the visible tank.
		mVelocity = Vector2D();
		ChangeState(TANKSTATE_MANFIRE);
	}

	BaseTank::Update(deltaTime, e);
}
double YawStrafeMaxAngle(PlayerData& player, const MovementVars& vars, bool onground, double wishspeed, const StrafeButtons& strafeButtons, bool useGivenButtons, Button& usedButton,
	double vel_yaw, double yaw)
{
	bool safeguard_yaw;
	double theta = MaxAngleTheta(player, vars, onground, wishspeed, safeguard_yaw);
	if (!player.Velocity.AsVector2D().IsZero(0.0f))
		vel_yaw = Atan2(player.Velocity[1], player.Velocity[0]);

	Vector2D newvel;
	double resulting_yaw;
	SideStrafeGeneral(player, vars, onground, wishspeed, strafeButtons, useGivenButtons, usedButton, vel_yaw, theta, (NormalizeRad(yaw - vel_yaw) < 0), newvel, resulting_yaw);

	if (safeguard_yaw) {
		Vector2D test_vel1, test_vel2;
		double test_yaw1, test_yaw2;

		SideStrafeGeneral(player, vars, onground, wishspeed, strafeButtons, useGivenButtons, usedButton, vel_yaw, min(theta - SAFEGUARD_THETA_DIFFERENCE_RAD, 0.0), (NormalizeRad(yaw - vel_yaw) < 0), test_vel1, test_yaw1);
		SideStrafeGeneral(player, vars, onground, wishspeed, strafeButtons, useGivenButtons, usedButton, vel_yaw, std::max(theta + SAFEGUARD_THETA_DIFFERENCE_RAD, 0.0), (NormalizeRad(yaw - vel_yaw) < 0), test_vel2, test_yaw2);

		double cos_test1 = test_vel1.Dot(player.Velocity.AsVector2D()) / (player.Velocity.Length2D() * test_vel1.Length());
		double cos_test2 = test_vel2.Dot(player.Velocity.AsVector2D()) / (player.Velocity.Length2D() * test_vel2.Length());
		double cos_newvel = newvel.Dot(player.Velocity.AsVector2D()) / (player.Velocity.Length2D() * newvel.Length());

		//DevMsg("cos_newvel = %.8f; cos_test1 = %.8f; cos_test2 = %.8f\n", cos_newvel, cos_test1, cos_test2);

		if (cos_test1 < cos_newvel) {
			if (cos_test2 < cos_test1) {
				newvel = test_vel2;
				resulting_yaw = test_yaw2;
				cos_newvel = cos_test2;
			} else {
				newvel = test_vel1;
				resulting_yaw = test_yaw1;
				cos_newvel = cos_test1;
			}
		} else if (cos_test2 < cos_newvel) {
			newvel = test_vel2;
			resulting_yaw = test_yaw2;
			cos_newvel = cos_test2;
		}
	} else {
		//DevMsg("theta = %.08f, yaw = %.08f, vel_yaw = %.08f, speed = %.08f\n", theta, yaw, vel_yaw, player.Velocity.Length2D());
	}

	player.Velocity.AsVector2D() = newvel;
	return resulting_yaw;
}
Vector2D S013010C_Aaron_Smith_Steering::Pursuing()
{
	
	Vector2D enemyTankPos = mTank->GetTarget();

	double relativeHeading = mTank->GetHeading().Dot(mTank->GetEnemyHeading());

	if (enemyTankPos.Dot(mTank->GetHeading()) > 0 &&
		(relativeHeading < -0.95))
		return Seek(enemyTankPos);
	else
	{
		//not ahead of player so need to predict enemy position
		
		double lookAheadTime = enemyTankPos.Length() / (mTank->GetMaxSpeed() + mTank->GetEnemySpeed());
		return Seek(enemyTankPos + mTank->GetEnemyVelocity() * lookAheadTime);
	}

}
Example #10
0
float CAI_PlaneSolver::AdjustRegulationWeight( CBaseEntity *pEntity, float weight )
{
	if ( pEntity->MyNPCPointer() != NULL )
	{
		// @TODO (toml 10-03-02): How to do this with non-NPC entities. Should be using intended solve velocity...
		Vector2D velOwner = GetNpc()->GetMotor()->GetCurVel().AsVector2D();
		Vector2D velBlocker = ((CAI_BaseNPC *)pEntity)->GetMotor()->GetCurVel().AsVector2D();

		Vector2D velOwnerNorm = velOwner;
		Vector2D velBlockerNorm = velBlocker;

		float speedOwner   = Vector2DNormalize( velOwnerNorm );
		float speedBlocker = Vector2DNormalize( velBlockerNorm );

		float dot = velOwnerNorm.Dot( velBlockerNorm );

		if ( speedBlocker > 0 )
		{
			if ( dot > 0 && speedBlocker >= speedOwner * 0.9 )
			{
				if ( dot > 0.86 )
				{
					// @Note (toml 10-10-02): Even in the case of no obstacle, we generate
					// a suggestion in because we still want to continue sweeping the
					// search
					weight = 0;
				}
				else if ( dot > 0.7 )
				{
					weight *= sq( weight );
				}
				else 
					weight *= weight;
			}
		}
	}

	return weight;
}
Example #11
0
int HitOutline::Raycast(Point2D p, Vector2D v, Scalar maxTime, 
    Hit* hitArr, int hitArrSize, Scalar sense)
{
	//local data: Bart
	Hit localHitArr[100];
	int localHitArrSize=100;

    int hitCount = 0;

    // TODO: Currently very slow, brute force!
    int lineVertexCount = m_Lines.size();
	int quadVertexCount = m_Quads.size();

    Scalar epsilon = 1e-6;

	Point2D p1 = p;
	Point2D p2 = p+v;
    Point2D orig(0,0);
	Scalar vDv = v.Dot(v);
    Vector2D n = v.Orthogonal();

	// Line-line intersections.
	if( lineVertexCount > 0 )
	{
		Point2D* lines = &m_Lines[0];

		for( int i=0; i<lineVertexCount && hitCount<localHitArrSize; i += 2 )
		{
			Point2D q1 = lines[i+0];
			Point2D q2 = lines[i+1];

			Vector2D ortho = (q2-q1).Orthogonal();
			if( (dot(ortho, v) * sense < 0) || sense==0)
			{
				Scalar time1;
				Scalar time2;
				if( IntersectLines(p1, p2, q1, q2, time1, time2) )
				{
					if( time1 >= 0 && time1 < maxTime &&
						time2 >= 0 && time2 <= 1 )
					{
						Hit hit;
                        hit.Time = time1;
						hit.Point = p + time1 * v;
						hit.Normal = ortho.Normalized();
                        localHitArr[hitCount++] = hit;
					}
				}
			}
		}
	}

	// Line-quadratic intersections.
	if( quadVertexCount > 0 )
	{
		Point2D* quads = &m_Quads[0];
		for( int i=0; i<quadVertexCount && hitCount<localHitArrSize; i += 3 )
		{
			Vector2D q0 = quads[i+0] - p;
			Vector2D q1 = quads[i+1] - p;
			Vector2D q2 = quads[i+2] - p;

            // Hit only possible if:
            // (1) not all points are on same side of ray,
            //     
            // (2) and some points are in front of ray (currently not checked, handled by abc formula)

            Scalar dot_n_q0 = dot(n,q0);
            Scalar dot_n_q1 = dot(n,q1);
            Scalar dot_n_q2 = dot(n,q2);

            if( dot_n_q0 <= 0 && dot_n_q1 <= 0 && dot_n_q2 <= 0 )
                continue;

            if( dot_n_q0 >= 0 && dot_n_q1 >= 0 && dot_n_q2 >= 0 )
                continue;

            Scalar ts[2];
            Scalar a = 2*dot_n_q1-dot_n_q0-dot_n_q2;
            Scalar b = 2*dot_n_q0-2*dot_n_q1;
            Scalar c = -dot_n_q0;
			int n = solveQuadratic(a,b,c,ts);

			for( int j=0; j<n && hitCount < localHitArrSize; ++j )
			{
				Scalar t = ts[j];
				if( t >= 0 && t <= 1 )
				{
					Vector2D diff = (2*(q2-q1)+2*(q0-q1))*t+2*(q1-q0);
					Vector2D ortho = diff.Orthogonal();
					if( (dot(ortho, v) * sense < 0) || sense==0)
					{
						Vector2D h = lerp( lerp(q0,q1,t), lerp(q1,q2,t), t);
						Scalar time = h.Dot(v) / vDv;
						//time >= -maxTime
                        if( time >= 0 && time < maxTime )
                        {
						    Hit hit;
						    hit.Point = p+h;
						    hit.Time = time;
						    hit.Normal = ortho.Normalized();
                            localHitArr[hitCount++] = hit;
                        }
					}
				}
			}
		}
	}

    std::sort(localHitArr, localHitArr+hitCount, sortHitOnTime);
	//Bart
	for( int i=0; i<hitCount && i < hitArrSize; ++i )
	{
		hitArr[i]=localHitArr[i];
	}
    return hitCount;
}