Random vector inside cone

I will preface this question with, I wish I understood quaternions better. Any great visual explanations on how to use quaternions please post :slight_smile:

I want to figure out the right way to solve this. The goal is to create a random vector in a cone with a direction, or a vector from with a limited range. I think the illustration will help. Also this d3 example kinda explains it.

I made something cool but not right at all.

basically doing this (note I know this is wrong):

int n = 10;
for(int i=0; i<n; i++) {
	for(int j=0; j<n; j++) {
		float rx = ofMap(i, 0, n-1, -x, x);
		float ry = ofMap(j, 0, n-1, -y, y);
		ofVec3f v = normal; // a - b
		v.rotate(rx, ofVec3f(1, 0, 0));
		v.rotate(ry, ofVec3f(0, 1, 0));
		samples.addVertex(pos - v);

Any thoughts on a direction (haha) to solve this?

Hey Todd!
Quaternions are quite elusive.
I put together an example that hopefully will help.
The idea is to create your local rotations first.
For example:

ofQuaternion xquat;
xquat.makeRotate( cos( ofGetElapsedTimef() ) * 15.f, 1, 0, 0 );
ofQuaternion yquat;
yquat.makeRotate( sin( ofGetElapsedTimef() ) * 15.f, 0, 1, 0 );

// now create the rotation that will align the vector
// we are going to use z as the forward axis
// gets the rotation from local forward axis (ofVec3f(0,0,1) to the vector we want to align with.

ofQuaternion rquat;
rquat.makeRotate( ofVec3f(0,0,1), alignVec );

// now lets apply the rotations, the order of multiplication is important.
// for OF, multiply the quaternion first and then the vector for local axis rotation
for example:

// apply rotation around the x axis locally //
drawVectors[0].direction = ( (xquat) * ofVec3f(0,0,1) );
// now apply the rotation globally ( order of multiplication is important! )
drawVectors[0].direction = drawVectors[0].direction * rquat;

to apply both of the local rotations to the vector, use:

drawVectors[2].direction = ((xquat * yquat) * ofVec3f(0,0,1));
// the vector has been rotated around the local x and y axis, now we need to align it to the vector we want it to point //
// multiply the vector * quaternion for global transformation //
drawVectors[2].direction = drawVectors[2].direction * rquat;

I made an example to better illustrate whatโ€™s going on. (ofApp.h and .cpp attached as .zip).

Quats.zip (4.7 KB)

How did you get that code formatting? I tried the Preformatted Text button, but no luck. :slight_smile:

Fenced code blocks: https://help.github.com/articles/creating-and-highlighting-code-blocks/ :slight_smile:

Thanks @hamoid! Now it looks pretty. :slight_smile:

Nick this is great, I love the explaination. I ended up making this function gave me some decent results.

static ofVec3f getConeVector(ofVec3f a, ofVec3f b, float deg) {
	// get the direction from a -> b
	ofVec3f direction = b - a;
	// normalize this direction
	// create a circle
	// float rad = 0.1;
	float theta = ofDegToRad(deg);
	float x = cos(theta);
	float y = sin(theta);
	float z = 0;
	ofVec3f dir(x, y, z);
	// make a rotation on the z axis
	ofQuaternion rotation;
	rotation.makeRotate(ofVec3f(0, 0, 1), direction);
	// align the circle with the quaternion rotation
	float angle;
	ofVec3f vec;
	rotation.getRotate(angle, vec);
	// now rotate the vector based on the quaternion
	dir.rotate(angle, vec);
	return dir;