173 float c1 = m.
data[0].x*m.
data[1].y -
182 if (std::abs(c0) < FLT_EPSILON)
186 const float s_inv3 = 1.0f/3.0f;
187 const float s_sqrt3 = sqrtf (3.0f);
190 float c2_over_3 = c2 * s_inv3;
191 float a_over_3 = (c1 - c2 * c2_over_3) * s_inv3;
195 float half_b = 0.5f * (c0 + c2_over_3 * (2.0f * c2_over_3 * c2_over_3 - c1));
197 float q = half_b * half_b + a_over_3 * a_over_3 * a_over_3;
202 float rho = sqrtf (-a_over_3);
203 float theta = std::atan2 (sqrtf (-q), half_b) * s_inv3;
204 float cos_theta = std::cos (theta);
205 float sin_theta = sin (theta);
206 roots.x = c2_over_3 + 2.f * rho * cos_theta;
207 roots.y = c2_over_3 - rho * (cos_theta + s_sqrt3 * sin_theta);
208 roots.z = c2_over_3 - rho * (cos_theta - s_sqrt3 * sin_theta);
211 if (roots.x >= roots.y)
212 swap (roots.x, roots.y);
213 if (roots.y >= roots.z)
215 swap (roots.y, roots.z);
216 if (roots.x >= roots.y)
217 swap (roots.x, roots.y);
228 evals = evecs.
data[0] = evecs.
data[1] = evecs.
data[2] = make_float3 (0.0f, 0.0f, 0.0f);
234 float3 scale_tmp = fmaxf (fmaxf (fabs (mat.
data[0]), fabs (mat.
data[1])), fabs (mat.
data[2]));
235 float scale = fmaxf (fmaxf (scale_tmp.x, scale_tmp.y), scale_tmp.z);
236 if (scale <= FLT_MIN)
240 scaledMat.
data[0] = mat.
data[0] / scale;
241 scaledMat.
data[1] = mat.
data[1] / scale;
242 scaledMat.
data[2] = mat.
data[2] / scale;
247 if ((evals.z-evals.x) <= FLT_EPSILON)
250 evecs.
data[0] = make_float3 (1.0f, 0.0f, 0.0f);
251 evecs.
data[1] = make_float3 (0.0f, 1.0f, 0.0f);
252 evecs.
data[2] = make_float3 (0.0f, 0.0f, 1.0f);
254 else if ((evals.y-evals.x) <= FLT_EPSILON)
262 tmp.
data[0].x -= evals.z;
263 tmp.
data[1].y -= evals.z;
264 tmp.
data[2].z -= evals.z;
266 float3 vec1 = cross (tmp.
data[0], tmp.
data[1]);
267 float3 vec2 = cross (tmp.
data[0], tmp.
data[2]);
268 float3 vec3 = cross (tmp.
data[1], tmp.
data[2]);
270 float len1 = dot (vec1, vec1);
271 float len2 = dot (vec2, vec2);
272 float len3 = dot (vec3, vec3);
274 if (len1 >= len2 && len1 >= len3)
275 evecs.
data[2] = vec1 / sqrtf (len1);
276 else if (len2 >= len1 && len2 >= len3)
277 evecs.
data[2] = vec2 / sqrtf (len2);
279 evecs.
data[2] = vec3 / sqrtf (len3);
284 else if ((evals.z-evals.y) <= FLT_EPSILON)
291 tmp.
data[0].x -= evals.x;
292 tmp.
data[1].y -= evals.x;
293 tmp.
data[2].z -= evals.x;
295 float3 vec1 = cross (tmp.
data[0], tmp.
data[1]);
296 float3 vec2 = cross (tmp.
data[0], tmp.
data[2]);
297 float3 vec3 = cross (tmp.
data[1], tmp.
data[2]);
299 float len1 = dot (vec1, vec1);
300 float len2 = dot (vec2, vec2);
301 float len3 = dot (vec3, vec3);
303 if (len1 >= len2 && len1 >= len3)
304 evecs.
data[0] = vec1 / sqrtf (len1);
305 else if (len2 >= len1 && len2 >= len3)
306 evecs.
data[0] = vec2 / sqrtf (len2);
308 evecs.
data[0] = vec3 / sqrtf (len3);
319 tmp.
data[0].x -= evals.z;
320 tmp.
data[1].y -= evals.z;
321 tmp.
data[2].z -= evals.z;
323 float3 vec1 = cross (tmp.
data[0], tmp.
data[1]);
324 float3 vec2 = cross (tmp.
data[0], tmp.
data[2]);
325 float3 vec3 = cross (tmp.
data[1], tmp.
data[2]);
327 float len1 = dot (vec1, vec1);
328 float len2 = dot (vec2, vec2);
329 float len3 = dot (vec3, vec3);
332 unsigned int min_el = 2;
333 unsigned int max_el = 2;
334 if (len1 >= len2 && len1 >= len3)
337 evecs.
data[2] = vec1 / sqrtf (len1);
339 else if (len2 >= len1 && len2 >= len3)
342 evecs.
data[2] = vec2 / sqrtf (len2);
347 evecs.
data[2] = vec3 / sqrtf (len3);
353 tmp.
data[0].x -= evals.y;
354 tmp.
data[1].y -= evals.y;
355 tmp.
data[2].z -= evals.y;
357 vec1 = cross (tmp.
data[0], tmp.
data[1]);
358 vec2 = cross (tmp.
data[0], tmp.
data[2]);
359 vec3 = cross (tmp.
data[1], tmp.
data[2]);
361 len1 = dot (vec1, vec1);
362 len2 = dot (vec2, vec2);
363 len3 = dot (vec3, vec3);
364 if (len1 >= len2 && len1 >= len3)
367 evecs.
data[1] = vec1 / sqrtf (len1);
368 min_el = len1 <= mmax[min_el]? 1: min_el;
369 max_el = len1 > mmax[max_el]? 1: max_el;
371 else if (len2 >= len1 && len2 >= len3)
374 evecs.
data[1] = vec2 / sqrtf (len2);
375 min_el = len2 <= mmax[min_el]? 1: min_el;
376 max_el = len2 > mmax[max_el]? 1: max_el;
381 evecs.
data[1] = vec3 / sqrtf (len3);
382 min_el = len3 <= mmax[min_el]? 1: min_el;
383 max_el = len3 > mmax[max_el]? 1: max_el;
389 tmp.
data[0].x -= evals.x;
390 tmp.
data[1].y -= evals.x;
391 tmp.
data[2].z -= evals.x;
393 vec1 = cross (tmp.
data[0], tmp.
data[1]);
394 vec2 = cross (tmp.
data[0], tmp.
data[2]);
395 vec3 = cross (tmp.
data[1], tmp.
data[2]);
397 len1 = dot (vec1, vec1);
398 len2 = dot (vec2, vec2);
399 len3 = dot (vec3, vec3);
400 if (len1 >= len2 && len1 >= len3)
403 evecs.
data[0] = vec1 / sqrtf (len1);
404 min_el = len3 <= mmax[min_el]? 0: min_el;
405 max_el = len3 > mmax[max_el]? 0: max_el;
407 else if (len2 >= len1 && len2 >= len3)
410 evecs.
data[0] = vec2 / sqrtf (len2);
411 min_el = len3 <= mmax[min_el]? 0: min_el;
412 max_el = len3 > mmax[max_el]? 0: max_el;
417 evecs.
data[0] = vec3 / sqrtf (len3);
418 min_el = len3 <= mmax[min_el]? 0: min_el;
419 max_el = len3 > mmax[max_el]? 0: max_el;
422 unsigned mid_el = 3 - min_el - max_el;
423 evecs.
data[min_el] = normalize (cross (evecs.
data[(min_el+1)%3], evecs.
data[(min_el+2)%3] ));
424 evecs.
data[mid_el] = normalize (cross (evecs.
data[(mid_el+1)%3], evecs.
data[(mid_el+2)%3] ));
501 cov.
data[0] = make_float3 (0.0f, 0.0f, 0.0f);
502 cov.
data[1] = make_float3 (0.0f, 0.0f, 0.0f);
503 cov.
data[2] = make_float3 (0.0f, 0.0f, 0.0f);
505 cov = transform_reduce (begin, end,
506 ComputeCovarianceForPoint (centroid),
516 cov.
data[0] /= (float) (end - begin);
517 cov.
data[1] /= (float) (end - begin);
518 cov.
data[2] /= (float) (end - begin);