Tatooine
critical_points_bilinear.h
Go to the documentation of this file.
1#include <tatooine/tensor.h>
2
3#include <cmath>
4#include <vector>
5//==============================================================================
6namespace tatooine {
7namespace detail {
8//==============================================================================
9template <typename Real, typename T0, typename T1, typename T2, typename T3>
10constexpr auto eval_bilinear(base_tensor<T0, Real, 2> const& v00,
11 base_tensor<T1, Real, 2> const& v10,
12 base_tensor<T2, Real, 2> const& v01,
13 base_tensor<T3, Real, 2> const& v11, Real const s,
14 Real const t) {
15 return vec<Real, 2>{
16 (1 - s) * (1 - t) * v00(0) + s * (1 - t) * v10(0) + (1 - s) * t * v01(0) +
17 s * t * v11(0),
18 (1 - s) * (1 - t) * v00(1) + s * (1 - t) * v10(1) + (1 - s) * t * v01(1) +
19 s * t * v11(1),
20 };
21}
22//------------------------------------------------------------------------------
23template <typename Real, typename T0, typename T1, typename T2, typename T3>
25 base_tensor<T1, Real, 2> const& v10,
26 base_tensor<T2, Real, 2> const& v01,
27 base_tensor<T3, Real, 2> const& v11) {
28 auto const a = v01(0) * v10(1);
29 auto const b = v10(0) * v01(1);
30 auto const c = 2 * v00(0);
31 auto const d = 2 * v01(0);
32 auto const e = 2 * v10(0);
33 auto const f = 2 * v11(0);
34 auto const g = std::sqrt(
35 v00(0) * v00(0) * v11(1) * v11(1) +
36 (-c * a - c * b + (4 * v01(0) * v10(0) - c * v11(0)) * v00(1)) * v11(1) +
37 v01(0) * a * v10(1) +
38 ((4 * v00(0) * v11(0) - d * v10(0)) * v01(1) - d * v11(0) * v00(1)) *
39 v10(1) +
40 v10(0) * b * v01(1) - e * v11(0) * v00(1) * v01(1) +
41 v11(0) * v11(0) * v00(1) * v00(1));
42 auto const h = v00(0) * v11(1);
43 auto const i = 1 / ((e - c) * v11(1) + (d - f) * v10(1) + (c - e) * v01(1) +
44 (f - d) * v00(1));
45 auto const j = 1 / ((d - c) * v11(1) + (c - d) * v10(1) + (e - f) * v01(1) +
46 (f - e) * v00(1));
47
48 auto const s0 =
49 -(g + h - a + (v10(0) - c) * v01(1) + (d - v11(0)) * v00(1)) * i;
50 auto const s1 =
51 (g - h + a + (c - v10(0)) * v01(1) + (v11(0) - d) * v00(1)) * i;
52 auto const t0 =
53 -(g + h + (v01(0) - c) * v10(1) - b + (e - v11(0)) * v00(1)) * j;
54 auto const t1 =
55 (g - h + (c - v01(0)) * v10(1) + b + (v11(0) - e) * v00(1)) * j;
56
57 std::vector<vec<Real, 2>> solutions;
58 if (s0 > -1e-7 && s0 < 1 + 1e-7) {
59 if (t0 > -1e-7 && t0 < 1 + 1e-7) {
60 if (auto [x, y] = eval_bilinear(v00, v10, v01, v11, s0, t0).internal_container();
61 std::abs(x) < 1e-7 && std::abs(y) < 1e-7) {
62 solutions.push_back({s0, t0});
63 }
64 }
65 if (t1 > -1e-7 && t1 < 1 + 1e-7) {
66 if (auto [x, y] = eval_bilinear(v00, v10, v01, v11, s0, t1).internal_container();
67 std::abs(x) < 1e-7 && std::abs(y) < 1e-7) {
68 solutions.push_back({s0, t1});
69 }
70 }
71 }
72 if (s1 > -1e-7 && s1 < 1 + 1e-7) {
73 if (t0 > -1e-7 && t0 < 1 + 1e-7) {
74 if (auto [x, y] = eval_bilinear(v00, v10, v01, v11, s1, t0).internal_container();
75 std::abs(x) < 1e-7 && std::abs(y) < 1e-7) {
76 solutions.push_back({s1, t0});
77 }
78 }
79 if (t1 > -1e-7 && t1 < 1 + 1e-7) {
80 if (auto [x, y] = eval_bilinear(v00, v10, v01, v11, s1, t1).internal_container();
81 std::abs(x) < 1e-7 && std::abs(y) < 1e-7) {
82 solutions.push_back({s1, t1});
83 }
84 }
85 }
86 return solutions;
87}
88//==============================================================================
89} // namespace detail
90} // namespace tatooine
91//==============================================================================
Definition: vtp_writer.h:3
constexpr auto eval_bilinear(base_tensor< T0, Real, 2 > const &v00, base_tensor< T1, Real, 2 > const &v10, base_tensor< T2, Real, 2 > const &v01, base_tensor< T3, Real, 2 > const &v11, Real const s, Real const t)
Definition: critical_points_bilinear.h:10
auto solve_bilinear(base_tensor< T0, Real, 2 > const &v00, base_tensor< T1, Real, 2 > const &v10, base_tensor< T2, Real, 2 > const &v01, base_tensor< T3, Real, 2 > const &v11)
Definition: critical_points_bilinear.h:24
Definition: algorithm.h:6
Definition: base_tensor.h:23
Definition: vec.h:12