We know that the cross product of two vectors in 3-dimensional space is another vector which is orthogonal to both original vectors.
Given a vector which starts at the origin, we can just pick any random vector which starts at the origin to do the cross-product against.
Since the cross-product produces a vector which is orthogonal to both, and we picked a random vector as the second input, we have a vector which is both in a random direction and orthogonal to the original input vector.
NOTE: As DMGregory points out in the comments, you can sometimes select a random vector that is parallel to the original one. For this case, check if the result of the cross-product is a zero vector. If it is, then picking a random offset from the input vector should suffice.
Example (JavaScript and THREE.js). The red arrow is the original direction vector, the green arrow the random orthogonal one. The blue circle is the plane orthogonal to the red arrow:
var con = document.getElementById('container');
var renderer, scene, camera;
renderer = new THREE.WebGLRenderer();
renderer.setSize(320, 240);
con.appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, 4 / 3, 0.1, 1000);
camera.position.set(2, 1, 10);
camera.lookAt(0, 0, 0);
function randPoint(){
return Math.random() * 2 - 1;
}
// == Example ==
var vec1, vec2, vec3;
// Direction Vector
vec1 = new THREE.Vector3(2, 2, -2);
vec1.normalize();
// Random Vector
vec2 = new THREE.Vector3(randPoint(), randPoint(), randPoint());
vec2.normalize();
// Resultant Random Orthogonal Vector
// ===================================
vec3 = new THREE.Vector3();
vec3.crossVectors(vec1, vec2);
// Modify if needed. Offset vec1
// to ensure a vector which is not parallel.
if (vec3.x == 0 && vec3.y == 0 && vec3.z == 0){
vec2 = new THREE.Vector3(
vec1.x + Math.random() + 0.001,
vec1.y + Math.random() + 1.001,
vec1.z + Math.random() + 2.001
);
vec2.normalize();
vec3.crossVectors(vec1, vec2);
}
vec3.normalize();
// ===================================
var origin = new THREE.Vector3(0, 0, 0);
var cGeo = new THREE.CircleGeometry(5, 32);
var cMesh = new THREE.Mesh(cGeo, new THREE.MeshBasicMaterial({color: 0x0000ff, wireframe: true}));
cMesh.position.set(0, 0, 0);
cMesh.lookAt(vec1);
scene.add(cMesh);
scene.add(new THREE.ArrowHelper(vec1, origin, 5, 0xff0000));
scene.add(new THREE.ArrowHelper(vec3, origin, 5, 0x00ff00));
renderer.render(scene, camera);
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.min.js"></script>
<div id='container'></div>