2010-10-16 36 views
2

J'essaie de pointer une entité vers un vecteur 3D. (en définissant un angle d'entité de sorte qu'il pointe vers une position dans l'espace 3D). En ce moment, je suis coincé avec l'obtention d'un angle à partir d'un vecteur.Angle de direction ou pointant un angle 3D vers une position dans l'espace

//Vectors in the bracket are 3D, first is the entity position, second is a position in space where I want to point at. 
(myEntity.Pos - posToPointAt).Angle 

Je suis actuellement bloqué à la transformation du vecteur direction en un angle. L'aide est très appréciée.

Répondre

2

Ce n'est pas comme cela que cela fonctionne, il vous manque un élément d'information essentiel: au lieu d'utiliser la position de l'entité, vous devez comprendre comment votre entité pointe maintenant? Acquérir cette information peut être aussi simple que d'utiliser votre matrice de rotation actuelle et de la multiplier avec un vecteur unitaire sur l'axe z (ou quelle que soit la direction "neutre" de l'entité), mais tout dépend de votre configuration particulière.

Une fois que vous avez les deux vecteurs de direction (votre direction actuelle, et la direction vers le nouvel emplacement désiré ... la dernière étant les « normalisées myEntity.Pos - posToPointAt »), vous utilisez une fonction comme ci-dessous pour Calculer la rotation entre les directions. Remarquez que j'utilise des quaternions ici, vous pourriez avoir besoin d'une matrice de rotation.

function RotationBetweenVectors(const aV1, aV2: TVector3): TQuaternion; 
const 
    EPSILON = 0.000001; 

var 
    v1: TVector3; 
    v2: TVector3; 
    dot: FloatT; 
    s: FloatT; 
    invS: FloatT; 
    c: TVector3; 

begin 
    v1 := aV1.normalize; 
    v2 := aV2.normalize; 

    dot := VectorDotProduct(v1, v2); 

    if dot >= 1 then 
    begin 
     // INFO: DotProduct = 1 -> vectors are the same 
     result := QUATERNION_IDENTITY 
    end 
    else if (dot < EPSILON - 1) then 
    begin 
     raise Exception.create('180 degree rotation currently not supported.'); 
    end 
    else 
    begin 
     s := sqrt(2 * (1 + dot)); 
     invS := 1/s; 

     c := VectorCrossProduct(v1, v2); 

     result.x := c.x * invS; 
     result.y := c.y * invS; 
     result.z := c.z * invS; 
     result.w := 0.5 * s; 
     result := result.normalize; 
    end; 
end;