I'm building a tree generator and I'm at the point where I want to have sub branches branch off at right angles off the current branch, in random directions. I have a 3D vector defining the direction of the current branch but I can't for the life of me figure out how to transform that to a direction for the sub branch.
I have googled the problem and also searched here, but I can only find related problems and apparently I'm just not smart enough to figure out how to apply them to my problem.
So what needs to happen, given a certain 3D vector v, which can be pointing in any direction:
- Rotate v 90 degrees in some direction such that it ends up on the plane it defines; call that v'
- Rotate v' an arbitrary amount on that plane; in other words around the axis defined by v
Or put more simply:
- Rotate v 90 degrees in a random direction
I'm doing this in Java; the vector is stored in a javax.vecmath.Vector3f. I know about affine transforms, but as far as I understand they rotate around global axes, and I need to rotate my vector around the local axes defined by itself, if that makes sense.
Can someone hand hold me through this problem?
If you know the branch vector $\vec b = (x_0, y_0, z_0)$, then any vector perpendicular to it , say $\vec p = (x_1, y_1, z_1)$ will have dot product $0$.
So,
$$ \vec b . \vec p = x_0x_1 + y_0y_1 + z_0z_1 = \vec0 \\\text{dot product is zero as they are perpendicular} $$pick any $x_1, y_1$ you prefer, and set $z_1$ as
$$z_1 = - \frac{\left (x_0 x_1 + y_0 y_1\right)}{ z_0}$$
That seems to be the simplest approach to get "random" branches.
If you want to control the length of the vector, then you can always normalize your obtained vector $\vec p$ and get the result vector $\vec r$ by using
$$ \vec r = len \times\frac{\vec p}{\left | \vec p\right| } $$
where $len$ is the desired length of the vector.
If $z_0$ is $0$, then you'll get a singularity when you try to divide by $z_0$.
However, since $z_0$ is $0$, it does not impact the dot product at all, and therefore we can pick any $z_1$ we want to.
Solve for $y_1$ by picking some $x_1$, and then allowing $z_1$ to be "free" (that is, you can pick any $z_1 \in \mathbb{R}$). However, in doing so, you'll face a problem if $y_0$ is $0$ as well.
If both $z_0 = y_0 = 0$, then, you're forced to set $x_1 = 0$ (to maintain the dot product as $0$ for perpendicularity) while having $y_1, z_1 \in \mathbb{R}$ (that is, they are free).