| 226 | void Basis::pop() { --m; } |
| 227 | |
| 228 | bool Basis::push(const Fvector& p) |
| 229 | { |
| 230 | if (m == 0) |
| 231 | { |
| 232 | q0 = p; |
| 233 | c[0] = q0; |
| 234 | sqr_r[0] = 0; |
| 235 | } |
| 236 | else |
| 237 | { |
| 238 | int i; |
| 239 | const float eps = 1e-16f; |
| 240 | |
| 241 | // set v_m to Q_m |
| 242 | v[m].sub(p, q0); |
| 243 | |
| 244 | // compute the a_{m,i}, i< m |
| 245 | for (i = 1; i < m; ++i) |
| 246 | { |
| 247 | a[m][i] = v[i].dotproduct(v[m]); |
| 248 | a[m][i] *= (2.f / z[i]); |
| 249 | } |
| 250 | |
| 251 | // update v_m to Q_m-\bar{Q}_m |
| 252 | for (i = 1; i < m; ++i) |
| 253 | { |
| 254 | v[m].mad(v[m], v[i], -a[m][i]); |
| 255 | } |
| 256 | |
| 257 | // compute z_m |
| 258 | z[m] = 0; |
| 259 | z[m] += v[m].square_magnitude(); |
| 260 | z[m] *= 2; |
| 261 | |
| 262 | // reject push if z_m too small |
| 263 | if (z[m] < eps * current_sqr_r) |
| 264 | { |
| 265 | return false; |
| 266 | } |
| 267 | |
| 268 | // update c, sqr_r |
| 269 | float e = -sqr_r[m - 1]; |
| 270 | e += p.distance_to_sqr(c[m - 1]); |
| 271 | |
| 272 | f[m] = e / z[m]; |
| 273 | |
| 274 | c[m].mad(c[m - 1], v[m], f[m]); |
| 275 | |
| 276 | sqr_r[m] = sqr_r[m - 1] + e * f[m] / 2; |
| 277 | } |
| 278 | |
| 279 | current_c = c + m; |
| 280 | current_sqr_r = sqr_r[m]; |
| 281 | s = ++m; |
| 282 | return true; |
| 283 | } |
| 284 | |
| 285 | void Fsphere_compute(Fsphere& dest, const Fvector* verts, int count) |
no test coverage detected