Better way to calculate angle between lines?
This passed all test cases, I think:
anglecalc[vec1_, vec2_] := Mod[(ArcTan @@ vec2) - (ArcTan @@ vec1), 2 π]
For a start, you can use this signed-angle function, which involves the two-argument version of ArcTan
:
myVectorAngle[{x1_, x2_}, {y1_, y2_}] := Evaluate[
With[{code = ReIm[(y1 + I y2)/(x1 + I x2)] // ComplexExpand // Simplify},
ArcTan @@ code]
]
Some usage example:
{a, b} = {{{4, 3}, {3, 0}}, {{3, 0}, {10, 1}}} // N;
Pi - myVectorAngle @@ (a - b)
1.10715
If you have to use that a lot, you may switch to the following compiled function:
cf = Block[{P, PP},
PP = Table[Compile`GetElement[P, i, j, k], {i, 1, 2}, {j, 1, 2}, {k, 1, 2}];
With[{code =
N[Pi] - myVectorAngle[PP[[1, 1]] - PP[[1, 2]], PP[[2, 1]] - PP[[2, 2]]]},
Compile[{{P, _Real, 3}},
code,
CompilationTarget -> "C",
RuntimeAttributes -> {Listable},
Parallelization -> True,
RuntimeOptions -> "Speed"
]
]
];
cf[{a, b}]
1.10715
kek[x_] := 2 \[Pi] - If[x > 0, x, 2 \[Pi] + x]
anglecalc2[u_, v_] := kek[(ToPolarCoordinates[RotationMatrix[{v, {1, 0}}].(u)][[2]])]