/**
	this method is used to return the current heading of the character, specified as an angle measured in radians
*/
double Character::getHeadingAngle(){
	//first we need to get the current heading of the character. Also, note that q and -q represent the same rotation
	Quaternion q = getHeading();
	if (q.s<0){
		q.s = -q.s;
		q.v = -q.v;
	}
	double currentHeading = 2 * safeACOS(q.s);
	if (q.v.dotProductWith(PhysicsGlobals::up) < 0)
		currentHeading = -currentHeading;
	return currentHeading;
}
Ejemplo n.º 2
0
Quaternion2 Quaternion2::DecomposeRotation2(const VectorR3 vB) const {
    //we need to compute v in A's coordinates
    VectorR3 vA = this->rotate(vB);
    vA.Normalize();

    double temp = 0;

    //compute the rotation that aligns the vector v in the two coordinate frames (A and T)
    VectorR3 rotAxis = vA * vB;
    rotAxis.Normalize();
    double rotAngle = -safeACOS(vA.Dot(vB));

    Quaternion2 TqA = getRotationQuaternion2(rotAngle, rotAxis*(-1));
    return TqA * (*this);
}
Ejemplo n.º 3
0
/**
	Assume that the current quaternion represents the relative orientation between two coordinate frames A and B.
	This method decomposes the current relative rotation into a twist of frame B around the axis v passed in as a
	parameter, and another more arbitrary rotation.

	AqB = AqT * TqB, where T is a frame that is obtained by rotating frame B around the axis v by the angle
	that is returned by this function.

	In the T coordinate frame, v is the same as in B, and AqT is a rotation that aligns v from A to that
	from T.

	It is assumed that vB is a unit vector!! This method returns TqB, which represents a twist about
	the axis vB.
*/
Quaternion Quaternion::decomposeRotation(const Vector3d vB) const{
	//we need to compute v in A's coordinates
	Vector3d vA = this->rotate(vB);
	vA.toUnit();

	double temp = 0;

	//compute the rotation that aligns the vector v in the two coordinate frames (A and T)
	Vector3d rotAxis = vA.crossProductWith(vB);
	rotAxis.toUnit();
	double rotAngle = -safeACOS(vA.dotProductWith(vB));

	Quaternion TqA = Quaternion::getRotationQuaternion(rotAngle, rotAxis*(-1));
	return TqA * (*this);
}
Ejemplo n.º 4
0
/**
	Assume that the current quaternion represents the relative orientation between two coordinate frames P and C (i.e. q
	rotates vectors from the child/local frame C into the parent/global frame P).

	With v specified in frame C's coordinates, this method decomposes the current relative rotation, such that:

	PqC = qA * qB, where qB represents a rotation about axis v.
	
	This can be thought of us as a twist about axis v - qB - and a more general rotation, and swing
	- qA - decomposition. Note that qB can be thought of as a rotation from the C frame into a tmp trame T,
	and qA a rotation from T into P.

	In the T coordinate frame, v is the same as in C, and qA is a rotation that aligns v from P to that
	from T.
*/
void Quaternion::decomposeRotation(Quaternion* qA, Quaternion* qB, const Vector3d& vC) const{
	//we need to compute v in P's coordinates
	Vector3d vP;
	this->fastRotate(vC, &vP);

	//compute the rotation that alligns the vector v in the two coordinate frames (P and T - remember that v has the same coordinates in C and in T)
	Vector3d rotAxis;
	rotAxis.setToCrossProduct(vP, vC);
	rotAxis.toUnit();
	double rotAngle = -safeACOS(vP.dotProductWith(vC));

	qA->setToRotationQuaternion(rotAngle, rotAxis);
	//now qB = qAinv * PqC
	qB->setToProductOf(*qA, *this, true, false);

	*qB = (*qA).getComplexConjugate() * (*this);
}
Ejemplo n.º 5
0
/**
	This method returns a quaternion that is the result of spherically interpolating between the current quaternion and the one provided as a parameter.
	The value of the parameter t indicates the progress: if t = 0, the result will be *this. If it is 1, it will be other. If it is inbetween, then
	the result will be a combination of the two initial quaternions.
	Both quaternions that are used for the interpolation are assumed to have unit length!!!
*/
Quaternion Quaternion::sphericallyInterpolateWith(const Quaternion &other, double t) const{

	//make sure that we return the same value if either of the quaternions involved is q or -q 
	if (this->dotProductWith(other) < 0){
		Quaternion temp;
		temp.s = -other.s;
		temp.v = other.v * (-1);
		return this->sphericallyInterpolateWith(temp, t);
	}

	if (t<0) t = 0;
	if (t>1) t = 1;
	double dotProduct = this->dotProductWith(other);
	double sinTheta = sqrt(MAX(0,1-dotProduct*dotProduct));
	double theta = safeACOS(dotProduct);
	if (sinTheta == 0)
		return (*this);
	return ((*this) * sin(theta * (1-t)) + other * sin(theta * t)) * (1/sin(theta));
}
Ejemplo n.º 6
0
Quaternion2 Quaternion2::SlerpWith(const Quaternion2 &other, double t) const
{
    //make sure that we return the same value if either of the Quaternion2s involved is q or -q
    if (this->DotProductWith(other) < 0) {
        Quaternion2 temp;
        temp.w = -other.w;
        temp.x = other.x * (-1);
        temp.y = other.y * (-1);
        temp.z = other.z * (-1);
        return this->SlerpWith(temp, t);
    }

    if (t<0) t = 0;
    if (t>1) t = 1;
    double dotProduct = this->DotProductWith(other);
    double sinTheta = sqrt(max(0,1-dotProduct*dotProduct));
    double theta = safeACOS(dotProduct);
    if (sinTheta == 0)
        return (*this);
    return ((*this) * sin(theta * (1-t)) + other * sin(theta * t)) * (1/sin(theta));
}