• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Mr Awesome

Finding the Quaternion Betwee Two Vectors

10 posts in this topic

I have two 3d vectors, and I would like to find the quaternion such that v0 * q yields v1. I tried taking the cross product and the inverse cosine of the dot product and constructing a quaternion based on the axis and angle of the rotation, but the result was not even a unit quaternion. Here is the relevant code; perhaps someone can find the error or point me in the right direction.
Quaternion::Quaternion(const Vector& axis, float angle)
{
	if (abs(angle) < 1e-6)
	{
		w = 1.0;
		x = y = z = 0.0;
		return;
	}

	angle *= 0.5;
	float sinAngle = sin(angle);

	w = cos(angle);
	x = axis.x * sinAngle;
	y = axis.y * sinAngle;
	z = axis.z * sinAngle;
}

float Vector::dot(const Vector& vector) const
{
	return x * vector.x + y * vector.y + z * vector.z;
}

Vector Vector::cross(const Vector& vector) const
{
	return Vector(y * vector.z - z * vector.y, z * vector.x - x * vector.z, x * vector.y - y * vector.x);
}

Quaternion Vector::rotationTo(const Vector& vector) const
{
	if (*this == vector)
		return Quaternion::IDENTITY;
	else
	{
		Vector a = this->normalize();
		Vector b = vector.normalize();

		return Quaternion(a.cross(b), acos(a.dot(b)));
	}
}
0

Share this post


Link to post
Share on other sites
When I had these situations I tried to find a third vector "vc" that was able to find the second vector.

So vb = va + vc
??? = (0, 1, 2) + (0, 3, 6)
(0, 4, 8) = (0, 1, 2) + (0, 3, 6)
Considering vc = vb - va
finding vc was straightforward.

Now two questions. Are both vectors normalized? Would additional normalization of elements yield the desired result?

You should know I side with Diana, when someone talks about that four element monstrosity.
0

Share this post


Link to post
Share on other sites
Your quaternion construction looks correct. Did you convert the vector v0 to a quaternion first, and are you performing the rotation using q*v0*conj(q)?
0

Share this post


Link to post
Share on other sites
The magnitude of a cross product of two vectors is equal to the product of the magnitudes of the vectors times the sine of the angle between them. Unless the normalized vectors were perpendicular to each other, the cross product will have a magnitude of less than one.

Instead of normalizing the two vectors and then finding the cross product, you should just calculate and then normalize the cross product.
Vector v = (this->cross(vector)).normalize();
return Quaternion(v, acos(a.dot(b)));
There are actually infinitely many rotations that will rotate the first vector to be in the direction of the second vector, but this method does find the rotation that is in some sense the shortest, and probably the one which you are thinking of. To get the longer rotations you can multiply this quaternion by one that uses the original vector as the direction of the axis, with an arbitrary angle of rotation.

[Edited by - Vorpy on December 21, 2006 8:54:00 PM]
0

Share this post


Link to post
Share on other sites
Quote:
Original post by Raghar
You should know I side with Diana, when someone talks about that four element monstrosity.
IMO rejecting quaternions as unuseful (or, conversely, touting them as a panacea for all rotation-related ills) is not very well informed.

Also, don't believe everything you read online about quaternions: much of it is confused, misguided, or simply incorrect.

@The OP: There's actually a very nice algorithm for finding the quaternion that rotates one vector onto another that has a couple of advantages over the 'standard' method, namely that it works with vectors of arbitrary length, and that it handles uniformly (and robustly) the case where the vectors are aligned and nearly parallel.

Here's the algorithm in pseudocode:
quaternion q;
vector3 c = cross(v1,v2);
q.v = c;
if ( vectors are known to be unit length ) {
q.w = 1 + dot(v1,v2);
} else {
q.w = sqrt(v1.length_squared() * v2.length_squared()) + dot(v1,v2);
}
q.normalize();
return q;
2

Share this post


Link to post
Share on other sites
Interestingly, it does not necessarily mean anything to say that you have a quaternion that rotates from one vector to another, because you are forgetting to say anything about the orienation of that new vector. Think of it like this, you have a plus sign shape of 5 points that you rotate with the generated quaternion. Is the new + oriented how you expected? There are actually an infinite number of quaternions that satisfy the constraint of rotating a vector to a new vector. There is only one quaternion that does that but also satisfies the additional constraint. Think about it in terms of rotating a coordinate frame, and it might make more sense. Sorry I couldn't explain it better.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by pTymN
Interestingly, it does not necessarily mean anything to say that you have a quaternion that rotates from one vector to another, because you are forgetting to say anything about the orienation of that new vector.
Just to clarify/defend my previous post, I didn't address the non-uniqueness of the rotation since it had already been addressed by Vorpy earlier:
Quote:
Original post by Vorpy
There are actually infinitely many rotations that will rotate the first vector to be in the direction of the second vector, but this method does find the rotation that is in some sense the shortest, and probably the one which you are thinking of.
It seemed clear that the topic of the thread was the 'shortest arc' problem, so I didn't restate it in my post (although perhaps I should have).
0

Share this post


Link to post
Share on other sites
That other way of finding the quaternion is pretty neat. I spent a while just trying to prove to myself that the w coordinate comes out the same in either method. I think the best part about it is how it eliminates the trig functions, which do look almost redundant in the axis/angle method but require some tricky manipulations to eliminate.
0

Share this post


Link to post
Share on other sites
Whoops I guess I skimmed over the code a bit too quickly [grin]

But yeah, those half-angles just scream "trig identity", and since the dot product and cross product already contain trig functions you might as well find some clever way to manipulate them.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by Vorpy
That other way of finding the quaternion is pretty neat.
Yeah, it's pretty slick.

I originally picked it up from Martin Baker's site, here.
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0