Given two vectors u=(ux,uy,uz)
and v=(vx,vy,vz),
what is the computationally cheapest way of checking whether they are parallel or nearly parallel (given some threshold to approximate), assuming the vectors are not normalized?
Regarding nearly parallel: for instance we assume a threshold up to first decimal part, e.g., if their cross product is 0.01
we can safely assume them to be parallel. We can similarly relax the condition for other methods we may want to use.
If it is preferred to adhere to a programming language to answer, let us assume we want to do this in c++.
Short answer: Theoretically, it doesn't matter at all. Practically: measure it
Long answer:
Agreeing that the inverse trigonometric functions are out of the question, let's compare the most efficient ways of calculating the last two options.
Since you allow for the vectors to be nearly parallel, you need to calculate
crossx := uy * vz + uz * vy;
crossy := ...;
crossz := ...;
crossNorm = crossx * crossx + crossy * crossy + crossz * crossz;
which involves 9 multiplications and 5 additions. If the vectors are (nearly) parallel then crossNorm
should be (nearly) zero.
However, as correctly noted by Baum mit Augen, it is sufficient to check that crossx
, crossy
and crossz
are almost zero, reducing this to 6 multiplications and 3 additions, at the expense of up to two more comparisons. Which is more efficient, depends on the details of your language and definition of "nearly" equal – e.g. if nearly equals means that fabs(...) < 1E-6
it may be worth only having to do it once.
The scalar product is
scalar = ux * vx + uy * vy + uz * vz;
If the vectors are (nearly) parallel then
scalar * scalar
should (nearly) equal
(ux * ux + uy * uy + uz * uz) * (vx * vx + vy * vy + vz * vz).
This comes down to 10 multiplications and 6 additions.
This is just the above calculation but with two extra double
divisions. This does not add any value, in fact it may just introduce rounding problems.
The number of double operations is nearly the same for both options. If you really want to know, you can compare the assembly https://godbolt.org/z/nJ9CXl but the difference is going to be minimal for all practical purposes. In fact, if you only count the "expensive" instructions (mulsd
, addsd
, subsd
) and the comparisons (ucomisd
) both options have five of them. However, again, if you must know exactly, measure it!