19 #ifndef __UT_CovarianceMatrix__
20 #define __UT_CovarianceMatrix__
32 namespace UT_CovarianceMatrix
40 template <
typename T,
typename PT_POS>
46 auto ¢roid = calculated_centroid ? *calculated_centroid : our_centroid;
50 for (
int i = 0, ie = num_pts; i < ie; i++)
53 centroid = ctr.
sum() / num_pts;
57 for (
int i = 0, ie = num_pts; i < ie; i++)
59 auto p = pt_pos(i) - centroid;
65 return { cxx.
sum(), cxy.sum(), cxy.sum(), cyy.
sum() };
73 template <
typename T,
typename PT_POS>
79 auto ¢roid = calculated_centroid ? *calculated_centroid : our_centroid;
83 for (
int i = 0, ie = num_pts; i < ie; i++)
86 centroid = ctr.
sum() / num_pts;
91 for (
int i = 0, ie = num_pts; i < ie; i++)
93 auto p = pt_pos(i) - centroid;
100 czz += p.z() * p.z();
103 return { cxx.
sum(), cxy.sum(), cyy.sum(), cxz.
sum(), cyz.sum(), czz.
sum() };
110 template <
typename T,
typename PT_POS>
114 T *calculated_length =
nullptr)
117 auto ¢roid = calculated_centroid ? *calculated_centroid : our_centroid;
128 for (
int s = 0, se = num_segs;
s < se;
s++)
130 auto p = seg_pt_pos(2 *
s);
131 auto q = seg_pt_pos(2 *
s + 1);
133 seg_centroid_x2(
s) = p +
q;
136 ctr += (seg_len(
s) * seg_centroid_x2(
s));
140 if (calculated_length)
141 *calculated_length = l;
143 auto centroid_x2 = ctr.
sum() / l;
146 return {
T(0),
T(0),
T(0),
T(0) };
149 centroid =
T(0.5) * centroid_x2;
152 for (
int s = 0, se = num_segs;
s < se;
s++)
154 auto p = seg_pt_pos(2 *
s) - centroid;
155 auto q = seg_pt_pos(2 *
s + 1) - centroid;
156 auto scx2 = seg_centroid_x2(
s) - centroid_x2;
158 auto sl = seg_len(
s);
161 cxx += sl * (scx2.x() * scx2.x() + p.x() * p.x() +
q.x() *
q.x());
162 cxy += sl * (scx2.x() * scx2.y() + p.x() * p.y() +
q.x() *
q.y());
163 cyy += sl * (scx2.y() * scx2.y() + p.y() * p.y() +
q.y() *
q.y());
167 auto lscx2 = sl * scx2;
169 cxx += lscx2.x() * scx2.x();
170 cxx += lp.x() * p.x();
171 cxx += lq.x() * q.x();
173 cxy += lscx2.x() * scx2.y();
174 cxy += lp.x() * p.y();
175 cxy += lq.x() * q.y();
177 cyy += lscx2.y() * scx2.y();
178 cyy += lp.y() * p.y();
179 cyy += lq.y() * q.y();
185 return { cxx.sum() / l, cxy.sum() / l, cxy.sum() / l, cyy.
sum() / l };
192 template <
typename T,
typename PT_POS>
196 T * calculated_length =
nullptr)
199 auto ¢roid = calculated_centroid ? *calculated_centroid : our_centroid;
210 for (
int s = 0, se = num_segs;
s < se;
s++)
212 auto p = seg_pt_pos(2 *
s);
213 auto q = seg_pt_pos(2 *
s + 1);
215 seg_centroid_x2(
s) = p +
q;
218 ctr += (seg_len(
s) * seg_centroid_x2(
s));
222 if (calculated_length)
223 *calculated_length = l;
226 return {
T(0),
T(0),
T(0),
T(0),
T(0),
T(0) };
228 auto centroid_x2 = ctr.
sum() / l;
231 centroid =
T(0.5) * centroid_x2;
236 for (
int s = 0, se = num_segs;
s < se;
s++)
238 auto p = seg_pt_pos(2 *
s) - centroid;
239 auto q = seg_pt_pos(2 *
s + 1) - centroid;
241 auto scx2 = seg_centroid_x2(
s) - centroid_x2;
242 auto sl = seg_len(
s);
245 cxx += sl * (scx2.x() * scx2.x() + p.x() * p.x() +
q.x() *
q.x());
246 cxy += sl * (scx2.x() * scx2.y() + p.x() * p.y() +
q.x() *
q.y());
247 cxz += sl * (scx2.x() * scx2.z() + p.x() * p.z() +
q.x() *
q.z());
248 cyy += sl * (scx2.y() * scx2.y() + p.y() * p.y() +
q.y() *
q.y());
249 cyz += sl * (scx2.y() * scx2.z() + p.y() * p.z() +
q.y() *
q.z());
250 czz += sl * (scx2.z() * scx2.z() + p.z() * p.z() +
q.z() *
q.z());
254 auto lscx2 = sl * scx2;
256 cxx += lscx2.x() * scx2.x();
257 cxx += lp.x() * p.x();
258 cxx += lq.x() * q.x();
260 cxy += lscx2.x() * scx2.y();
261 cxy += lp.x() * p.y();
262 cxy += lq.x() * q.y();
264 cxy += lscx2.x() * scx2.z();
265 cxy += lp.x() * p.z();
266 cxy += lq.x() * q.z();
268 cyy += lscx2.y() * scx2.y();
269 cyy += lp.y() * p.y();
270 cyy += lq.y() * q.y();
272 cyz += lscx2.y() * scx2.z();
273 cyz += lp.y() * p.z();
274 cyz += lq.y() * q.z();
276 czz += lscx2.z() * scx2.z();
277 czz += lp.z() * p.z();
278 czz += lq.z() * q.z();
284 return { cxx.sum() / l, cxy.sum() / l, cyy.sum() / l,
285 cxz.
sum() / l, cyz.sum() / l, czz.
sum() / l };
292 template <
typename T,
typename PT_POS>
296 T *calculated_area =
nullptr)
299 auto ¢roid = calculated_centroid ? *calculated_centroid : our_centroid;
310 for (
int t = 0, te = num_tris;
t < te;
t++)
313 auto p = tri_pt_pos(t0);
314 auto q = tri_pt_pos(t0 + 1);
315 auto r = tri_pt_pos(t0 + 2);
317 tri_centroid_x3(
t) = (p +
q) +
r;
318 tri_area_x2(
t) =
SYSabs((
q.x() - p.x()) * (
r.y() - p.y())
319 - (
q.y() - p.y()) * (
r.x() - p.x()));
321 area_x2 += tri_area_x2(
t);
322 ctr += (tri_area_x2(
t) * tri_centroid_x3(
t));
325 auto a = area_x2.
sum();
327 *calculated_area =
a *
T(0.5);
330 return { T(0), T(0), T(0), T(0) };
332 auto centroid_x3 = ctr.
sum() /
a;
335 centroid = centroid_x3 / 3.0;
339 for (
int t = 0, te = num_tris;
t < te;
t++)
342 auto p = tri_pt_pos(t0) - centroid;
343 auto q = tri_pt_pos(t0 + 1) - centroid;
344 auto r = tri_pt_pos(t0 + 2) - centroid;
346 auto tcx3 = tri_centroid_x3(
t) - centroid_x3;
347 auto tax2 = tri_area_x2(
t);
350 cxx += tax2 * (tcx3.x() * tcx3.x()
351 + p.x() * p.x() +
q.x() *
q.x() +
r.x() *
r.x());
352 cxy += tax2 * (tcx3.x() * tcx3.y()
353 + p.x() * p.y() +
q.x() *
q.y() +
r.x() *
r.y());
354 cyy += tax2 * (tcx3.y() * tcx3.y()
355 + p.y() * p.y() +
q.y() *
q.y() +
r.y() *
r.y());
360 auto atcx3 = tax2 * tcx3;
362 cxx += atcx3.x() * tcx3.x();
363 cxx += ap.x() * p.x();
364 cxx += aq.x() * q.x();
365 cxx += ar.x() * r.x();
367 cxy += atcx3.x() * tcx3.y();
368 cxy += ap.x() * p.y();
369 cxy += aq.x() * q.y();
370 cxy += ar.x() * r.y();
372 cyy += atcx3.y() * tcx3.y();
373 cyy += ap.y() * p.y();
374 cyy += aq.y() * q.y();
375 cyy += ar.y() * r.y();
381 return { cxx.sum() /
a, cxy.sum() /
a, cxy.sum() /
a, cyy.
sum() /
a };
388 template <
typename T,
typename PT_POS>
393 T *calculated_area =
nullptr)
396 auto ¢roid = calculated_centroid ? *calculated_centroid : our_centroid;
399 auto &average_normal =
400 calculated_average_normal ? *calculated_average_normal
401 : our_average_normal;
414 for (
int t = 0, te = num_tris;
t < te;
t++)
417 auto p = tri_pt_pos(t0);
418 auto q = tri_pt_pos(t0 + 1);
419 auto r = tri_pt_pos(t0 + 2);
421 tri_centroid_x3(
t) = (p +
q) +
r;
428 tri_area_x2(
t) =
n.length();
429 area_x2 += tri_area_x2(
t);
431 ctr += (tri_area_x2(
t) * tri_centroid_x3(
t));
437 *calculated_area = a *
T(0.5);
440 return { T(0), T(0), T(0), T(0), T(0), T(0) };
442 auto centroid_x3 = ctr.
sum() /
a;
445 centroid = centroid_x3 / 3.0;
446 average_normal = nml.
sum() /
a;
451 for (
int t = 0, te = num_tris;
t < te;
t++)
454 auto p = tri_pt_pos(t0) - centroid;
455 auto q = tri_pt_pos(t0 + 1) - centroid;
456 auto r = tri_pt_pos(t0 + 2) - centroid;
458 auto tcx3 = tri_centroid_x3(
t) - centroid_x3;
459 auto tax2 = tri_area_x2(
t);
462 cxx += tax2 * (tcx3.x() * tcx3.x()
463 + p.x() * p.x() +
q.x() *
q.x() +
r.x() *
r.x());
464 cxy += tax2 * (tcx3.x() * tcx3.y()
465 + p.x() * p.y() +
q.x() *
q.y() +
r.x() *
r.y());
466 cxz += tax2 * (tcx3.x() * tcx3.z()
467 + p.x() * p.z() +
q.x() *
q.z() +
r.x() *
r.z());
468 cyy += tax2 * (tcx3.y() * tcx3.y()
469 + p.y() * p.y() +
q.y() *
q.y() +
r.y() *
r.y());
470 cyz += tax2 * (tcx3.y() * tcx3.z()
471 + p.y() * p.z() +
q.y() *
q.z() +
r.y() *
r.z());
472 czz += tax2 * (tcx3.z() * tcx3.z()
473 + p.z() * p.z() +
q.z() *
q.z() +
r.z() *
r.z());
479 auto atcx3 = tax2 * tcx3;
481 cxx += atcx3.x() * tcx3.x();
482 cxx += ap.x() * p.x();
483 cxx += aq.x() * q.x();
484 cxx += ar.x() * r.x();
486 cxy += atcx3.x() * tcx3.y();
487 cxy += ap.x() * p.y();
488 cxy += aq.x() * q.y();
489 cxy += ar.x() * r.y();
491 cxz += atcx3.x() * tcx3.z();
492 cxz += ap.x() * p.z();
493 cxz += aq.x() * q.z();
494 cxz += ar.x() * r.z();
496 cyy += atcx3.y() * tcx3.y();
497 cyy += ap.y() * p.y();
498 cyy += aq.y() * q.y();
499 cyy += ar.y() * r.y();
501 cyz += atcx3.y() * tcx3.z();
502 cyz += ap.y() * p.z();
503 cyz += aq.y() * q.z();
504 cyz += ar.y() * r.z();
506 czz += atcx3.z() * tcx3.z();
507 czz += ap.z() * p.z();
508 czz += aq.z() * q.z();
509 czz += ar.z() * r.z();
516 return { cxx.sum() /
a, cxy.sum() /
a, cyy.sum() /
a,
517 cxz.
sum() /
a, cyz.sum() /
a, czz.
sum() / a };
UT_Matrix2T< T > pointCovariance2(int num_pts, PT_POS pt_pos, UT_Vector2T< T > *calculated_centroid=nullptr)
UT_SymMatrix3T< T > triangleCovariance3(int num_tris, PT_POS tri_pt_pos, UT_Vector3T< T > *calculated_centroid=nullptr, UT_Vector3T< T > *calculated_average_normal=nullptr, T *calculated_area=nullptr)
void setSizeNoInit(exint newsize)
GLboolean GLboolean GLboolean GLboolean a
GLuint GLsizei GLsizei * length
Generic symmetric 3x3 matrix.
UT_Matrix2T< T > triangleCovariance2(int num_tris, PT_POS tri_pt_pos, UT_Vector2T< T > *calculated_centroid=nullptr, T *calculated_area=nullptr)
GLdouble GLdouble GLdouble q
UT_SymMatrix3T< T > segmentCovariance3(int num_segs, PT_POS seg_pt_pos, UT_Vector3T< T > *calculated_centroid=nullptr, T *calculated_length=nullptr)
UT_Matrix2T< T > segmentCovariance2(int num_segs, PT_POS seg_pt_pos, UT_Vector2T< T > *calculated_centroid=nullptr, T *calculated_length=nullptr)
UT_SymMatrix3T< T > pointCovariance3(int num_pts, PT_POS pt_pos, UT_Vector3T< T > *calculated_centroid=nullptr)
SIM_DerVector3 cross(const SIM_DerVector3 &lhs, const SIM_DerVector3 &rhs)