File indexing completed on 2024-04-06 12:28:36
0001
0002
0003
0004
0005 #include <cmath>
0006 #include <algorithm>
0007 #include <numeric>
0008 #include <cassert>
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 template <typename T>
0029 class FastCircle {
0030 public:
0031 FastCircle() {}
0032 FastCircle(T x1, T y1, T x2, T y2, T x3, T y3) { compute(x1, y1, x2, y2, x3, y3); }
0033
0034 void compute(T x1, T y1, T x2, T y2, T x3, T y3);
0035
0036 T m_xp;
0037 T m_yp;
0038 T m_c;
0039 T m_alpha;
0040 T m_beta;
0041 };
0042
0043 template <typename T>
0044 void FastCircle<T>::compute(T x1, T y1, T x2, T y2, T x3, T y3) {
0045 bool flip = std::abs(x3 - x1) > std::abs(y3 - y1);
0046
0047 auto x1p = x1 - x2;
0048 auto y1p = y1 - y2;
0049 auto d12 = x1p * x1p + y1p * y1p;
0050 auto x3p = x3 - x2;
0051 auto y3p = y3 - y2;
0052 auto d32 = x3p * x3p + y3p * y3p;
0053
0054 if (flip) {
0055 std::swap(x1p, y1p);
0056 std::swap(x3p, y3p);
0057 }
0058
0059 auto num = x1p * y3p - y1p * x3p;
0060 auto det = d12 * y3p - d32 * y1p;
0061 if (std::abs(det) == 0) {
0062
0063 }
0064 auto ct = num / det;
0065 auto sn = det > 0 ? T(1.) : T(-1.);
0066 auto st2 = (d12 * x3p - d32 * x1p) / det;
0067 auto seq = T(1.) + st2 * st2;
0068 auto al2 = sn / std::sqrt(seq);
0069 auto be2 = -st2 * al2;
0070 ct *= T(2.) * al2;
0071
0072 if (flip) {
0073 std::swap(x1p, y1p);
0074 std::swap(al2, be2);
0075 al2 = -al2;
0076 be2 = -be2;
0077 ct = -ct;
0078 }
0079
0080 m_xp = x1;
0081 m_yp = y1;
0082 m_c = ct;
0083 m_alpha = al2 - ct * x1p;
0084 m_beta = be2 - ct * y1p;
0085 }
0086
0087
0088 float fastDPHI(float ri, float ro, float dphi) {
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 auto r2 = (ro - ri) * (ro - ri) / (dphi * dphi) + ri * ro;
0125
0126
0127
0128
0129 return -1.f / std::sqrt(r2 / 4.f);
0130 }
0131
0132 #include <iostream>
0133
0134 template <typename T>
0135 bool equal(T a, T b) {
0136
0137 return std::abs(float(a - b)) < std::abs(0.01f * a);
0138 }
0139
0140 int n = 0;
0141 void go(float ri, float ro, float dphi, bool print = false) {
0142 ++n;
0143 float x3 = 0.f, y3 = ro;
0144 float x2 = ri * sin(dphi);
0145 float y2 = ri * cos(dphi);
0146
0147 FastCircle<float> c(0, 0, x2, y2, x3, y3);
0148
0149 auto cc = fastDPHI(ri, ro, dphi);
0150 if (print)
0151 std::cout << c.m_c << ' ' << cc << std::endl;
0152 assert(equal(c.m_c, cc));
0153 }
0154
0155 int main() {
0156 go(4., 7., 0.1, true);
0157
0158 for (float r1 = 2; r1 < 15; r1 += 1)
0159 for (float dr = 0.5; dr < 10; dr += 0.5)
0160 for (float dphi = 0.02; dphi < 0.2; dphi += 0.2)
0161 go(r1, r1 + dr, dphi);
0162
0163 std::cout << "done " << n << std::endl;
0164 return 0;
0165 };