Angle Vector2D::getAngleTo(const Vector2D& other) const { // A·B = |A| * |B| * cos θ, θ = arccos (A·B / (|A| * |B|)) // NB that A·B / (|A| * |B|) cannot generate an invalid value for Math::acos // because of the Cauchy-Schwarz inequality return Radian(Math::acos(dot(other) / (getLength() * other.getLength()))); }
Steering* DynamicArriveSteering::getSteering() { Vector2D direction = mpTarget->getPosition() - mpMover->getPosition(); float distance = direction.getLength(); //are we there? if( distance < mTargetRadius ) { mLinear = gZeroVector2D; mAngular = 0.0f; return this; } float targetSpeed = 0.0f; //are we outside slow radius? if( distance > mSlowRadius ) { targetSpeed = mpMover->getMaxVelocity(); } else { targetSpeed = ( mpMover->getMaxVelocity() * distance ) / mSlowRadius; } //combine speed and direction to get targetVelocity Vector2D targetVelocity = direction; targetVelocity.normalize(); targetVelocity *= targetSpeed; //set acceleration mLinear = targetVelocity - mpMover->getVelocity(); mLinear /= mTimeToTarget; //check if too fast if( mLinear.getLength() > mpMover->getMaxAcceleration() ) { //cut down to max mLinear.normalize(); mLinear*= mpMover->getMaxAcceleration(); } mAngular = 0.0f; return this; }
Steering* WanderAndSeekOrFlee::getSteering() { Vector2D direction = mpTarget->getPosition() - mpMover->getPosition(); float distance = direction.getLength(); ALLEGRO_COLOR color; if (mShouldFlee) color = al_map_rgb(0, 0, 0); else color = al_map_rgb(0, 191, 255); if (debugOn) al_draw_circle(mpMover->getPosition().getX(), mpMover->getPosition().getY(), mRadius, color, 2.0f); if (distance > mRadius) return mpDynamicWanderSteering->getSteering(); else return mpDynamicSeekSteering->getSteering(); }