Offset a vector by another vector

I have a vector in space. I want to make a ring of vectors that are offset from the original by a certain angle, so that they form a cone shape. I realize this can have multiple solutions. That’s okay, as long as the resulting vectors form a cone around the original. How can this be done?

I’ve got it mostly working by converting one vector to a mat3 and multiplying the other vector by this matrix. Can anyone see anything wrong with this function?:

mat3 vec3tomat3( in vec3 z ) {
	mat3 mat;
	mat[2]=z;
	vec3 v=vec3(z.y,z.z,z.x);//make a random vector that isn't the same as vector z
	mat[0]=cross(z,v);//cross product is the x axis
	mat[1]=cross(mat[0],z);//cross product is the y axis
	return mat;
}

It’ll fail if

z.x == z.y == z.z

CatDog

yep, try something like z=abs(z); vec3 zz = vec3(z.z, -z.x, z.y).

I think this will work for all cases:

vec3 v=vec3(z.z,z.x,-z.y);

Got it working, in any case:
http://vimeo.com/9507240

99.9% of the time that’ll do just fine.

Here’s what I was getting at above. I think the trick is in creating a 2nd intermediate vector to escape equality in the first.


void TangentBasis(vec3 normal, out vec3 tangent, out vec3 bitangent)
{
	vec3 a = abs(normal);
	vec3 p = vec3(a.z, -a.x, a.y};
	vec3 q = cross(p, a);
	tangent = normalize(cross(q, normal));
	bitangent = normalize(cross(normal, tangent));

	// det([normal tangent bitangent]) = +1 => right handed, orthonormal
}