Easy3D 2.5.3
types.h
1/********************************************************************
2 * Copyright (C) 2015-2021 by Liangliang Nan <liangliang.nan@gmail.com>
3 * Copyright (C) 2000-2005 INRIA - Project ALICE
4 *
5 * The code in this file is partly from OGF/Graphite (2.0 alpha-4) with
6 * modifications and enhancement:
7 * https://gforge.inria.fr/forum/forum.php?forum_id=11459
8 * The original code was distributed under the GNU GPL license.
9 ********************************************************************/
10
11#ifndef EASY3D_CORE_TYPES_H
12#define EASY3D_CORE_TYPES_H
13
14
15#include <cmath>
16#include <vector>
17#include <cstdint>
18
19#include <easy3d/core/vec.h>
20#include <easy3d/core/mat.h>
21#include <easy3d/core/rect.h>
22#include <easy3d/core/line.h>
23#include <easy3d/core/oriented_line.h>
24#include <easy3d/core/segment.h>
25#include <easy3d/core/plane.h>
26#include <easy3d/core/box.h>
27#include <easy3d/core/quat.h>
28#include <easy3d/core/polygon.h>
29#include <easy3d/core/constant.h>
30#include <easy3d/core/export.h>
31
38namespace easy3d {
39
40 //____________________ default types___________________
41
48
55
62
73
84
89
94
97
102
105
110
115
118
119
121 template <typename FT>
122 inline bool is_nan(FT v) {
123 return (std::isnan(v) || std::isinf(v));
124 }
125
129 template<class T>
130 inline T clamp(T x, T lower, T upper) {
131 return std::min(upper, std::max(x, lower));
132 }
133
143 inline int next_pow2(int a) {
144 int rval = 1;
145 while (rval < a) rval <<= 1;
146 return rval;
147 }
148
150 template<class FT>
151 inline FT truncate_digits(const FT &v, int num) {
152 FT tmp = std::pow(10.0, num);
153 auto des = static_cast<long long>((v < 0) ? (v * tmp - 0.5) : (v * tmp + 0.5));
154 return FT(des) / tmp;
155 }
156
157
160 namespace geom {
161
163 inline vec3 orthogonal(const vec3 &v) {
164 const float absx = std::fabs(v.x);
165 const float absy = std::fabs(v.y);
166 const float absz = std::fabs(v.z);
167 // Find smallest component. Keep equal case for null values.
168 if ((absy >= absx) && (absz >= absx))
169 return vec3(0.0f, -v.z, v.y);
170 else {
171 if ((absx >= absy) && (absz >= absy))
172 return vec3(-v.z, 0.0f, v.x);
173 else
174 return vec3(-v.y, v.x, 0.0f);
175 }
176 }
177
179 template<typename Box, typename Container>
180 inline Box bounding_box(const Container& points) {
181 Box result;
182 for (const auto& p : points) {
183 result.grow(p);
184 }
185 return result;
186 }
187
189 template<typename Vec, typename Container>
190 inline Vec centroid(const Container& points) {
191 Vec v(0);
192 for (const auto& p : points)
193 v += p;
194 return v / points.size();
195 }
196
198 template<typename Vec>
199 inline Vec barycenter(const Vec &p1, const Vec &p2) {
200 return (p1 + p2) * 0.5f;
201 }
202
204 template<typename Vec>
205 inline Vec barycenter(const Vec &p1, const Vec &p2, const Vec &p3) {
206 return (p1 + p2 + p3) / 3.0f;
207 }
208
210 template<typename Vec>
211 inline Vec barycenter(const Vec &p1, const Vec &p2, const Vec &p3, const Vec &p4) {
212 return (p1 + p2 + p3 + p4) * 0.25f;
213 }
214
217 template<typename FT>
219 const Vec<3, FT> &u,
220 const Vec<3, FT> &v,
221 const Vec<3, FT> &w);
222
227 inline bool point_in_polygon(const vec2 &p, const std::vector<vec2> &polygon);
228
230 inline double clamp_cot(const double v) {
231 const double bound = 19.1; // 3 degrees
232 return (v < -bound ? -bound : (v > bound ? bound : v));
233 }
234
236 inline double clamp_cos(const double v) {
237 const double bound = 0.9986; // 3 degrees
238 return (v < -bound ? -bound : (v > bound ? bound : v));
239 }
240
242 template<typename Vec>
243 inline double cos_angle(const Vec &a, const Vec &b) {
244 return dot(a, b) / std::sqrt(length2(a) * length2(b));
245 }
246
248 template<typename Vec>
249 inline double sin_angle(const Vec &a, const Vec &b) {
250 return norm(cross(a, b)) / (norm(a) * norm(b));
251 }
252
254 template<typename Vec>
255 inline typename Vec::FT cotan_angle(const Vec &a, const Vec &b) {
256 return clamp_cot(dot(a, b) / norm(cross(a, b)));
257 }
258
260 template<typename Vec>
261 inline double angle(const Vec &a, const Vec &b) {
262 return std::atan2(norm(cross(a, b)), dot(a, b));
263 }
264
266 template<typename FT>
267 inline FT to_radians(FT degrees) {
268 return degrees * static_cast<FT>(0.01745329251994329576923690768489);
269 }
270
272 template<typename FT>
273 inline FT to_degrees(FT radians) {
274 return radians * static_cast<FT>(57.295779513082320876798154814105);
275 }
276
278 inline float triangle_area(const vec3 &p1, const vec3 &p2, const vec3 &p3) {
279 return 0.5f * length(cross(p2 - p1, p3 - p1));
280 }
281
283 inline float triangle_signed_area(const vec2 &p1, const vec2 &p2, const vec2 &p3) {
284 return 0.5f * det(p2 - p1, p3 - p1);
285 }
286
288 inline vec3 triangle_normal(const vec3 &p1, const vec3 &p2, const vec3 &p3) {
289 vec3 n = cross(p2 - p1, p3 - p2);
290 return normalize(n);
291 }
292
294 inline float dist_point_line_segment(const vec3 &p, const vec3 &v0, const vec3 &v1, vec3 &nearest_point);
295
297 inline float
298 dist_point_triangle(const vec3 &p, const vec3 &v0, const vec3 &v1, const vec3 &v2, vec3 &nearest_point);
299
301 inline vec3 tetra_circum_center(const vec3& p, const vec3& q, const vec3& r, const vec3& s);
302
303 } // namespace geom
304
305
306 namespace color {
307
308 // Encode a color into an integer
309
311 inline int encode(int r, int g, int b) {
312 return (0xff << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
313 }
314
316 inline int encode(int r, int g, int b, int a) {
317 return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
318 }
319
320 // Encode an integer into color components
321
323 inline void decode(int value, int &r, int &g, int &b) {
324 r = ((value >> 16) & 0xff);
325 g = ((value >> 8) & 0xff);
326 b = (value & 0xff);
327 }
328
330 inline void decode(int value, int &r, int &g, int &b, int &a) {
331 r = ((value >> 16) & 0xff);
332 g = ((value >> 8) & 0xff);
333 b = (value & 0xff);
334 a = (value >> 24);
335 }
336
337
338 // Given a color encoded as an integer, get the color component
339
341 inline int red(int color) { return ((color >> 16) & 0xff); }
342
344 inline int green(int color) { return ((color >> 8) & 0xff); }
345
347 inline int blue(int color) { return (color & 0xff); }
348
350 inline int alpha(int color) { return color >> 24; }
351
352 } // namespace color
353
354} // namespace easy3d
355
356
357//=============================================================================
358
359
360// \cond
361namespace easy3d {
362
363 namespace geom {
364
365 template<typename FT>
366 inline Vec<3, FT> barycentric_coordinates(const Vec<3, FT> &p,
367 const Vec<3, FT> &u,
368 const Vec<3, FT> &v,
369 const Vec<3, FT> &w) {
370 Vec<3, FT> result(1.0 / 3.0); // default: barycenter
371
372 Vec<3, FT> vu = v - u, wu = w - u, pu = p - u;
373
374 // find the largest absolute coordinate of normal
375 FT nx = vu[1] * wu[2] - vu[2] * wu[1],
376 ny = vu[2] * wu[0] - vu[0] * wu[2],
377 nz = vu[0] * wu[1] - vu[1] * wu[0], ax = fabs(nx), ay = fabs(ny),
378 az = fabs(nz);
379
380 unsigned char maxCoord;
381
382 if (ax > ay) {
383 if (ax > az)
384 maxCoord = 0;
385 else
386 maxCoord = 2;
387 } else {
388 if (ay > az)
389 maxCoord = 1;
390 else
391 maxCoord = 2;
392 }
393
394 // solve 2D problem
395 switch (maxCoord) {
396 case 0: {
397 if (1.0 + ax != 1.0) {
398 result[1] = 1.0 + (pu[1] * wu[2] - pu[2] * wu[1]) / nx - 1.0;
399 result[2] = 1.0 + (vu[1] * pu[2] - vu[2] * pu[1]) / nx - 1.0;
400 result[0] = 1.0 - result[1] - result[2];
401 }
402 break;
403 }
404
405 case 1: {
406 if (1.0 + ay != 1.0) {
407 result[1] = 1.0 + (pu[2] * wu[0] - pu[0] * wu[2]) / ny - 1.0;
408 result[2] = 1.0 + (vu[2] * pu[0] - vu[0] * pu[2]) / ny - 1.0;
409 result[0] = 1.0 - result[1] - result[2];
410 }
411 break;
412 }
413
414 case 2: {
415 if (1.0 + az != 1.0) {
416 result[1] = 1.0 + (pu[0] * wu[1] - pu[1] * wu[0]) / nz - 1.0;
417 result[2] = 1.0 + (vu[0] * pu[1] - vu[1] * pu[0]) / nz - 1.0;
418 result[0] = 1.0 - result[1] - result[2];
419 }
420 break;
421 }
422 default:
423 break;
424 }
425
426 return result;
427 }
428
429 //-----------------------------------------------------------------------------
430
431 inline bool point_in_polygon(const vec2 &p, const std::vector<vec2> &polygon) {
432 bool inside = false;
433 std::size_t n = polygon.size();
434 for (std::size_t i = 0, j = n - 1; i < n; j = i, ++i) {
435 const vec2 &u0 = polygon[i];
436 const vec2 &u1 = polygon[j]; // current edge
437
438 if (((u0.y <= p.y) && (p.y < u1.y)) || // U1 is above the ray, U0 is on or below the ray
439 ((u1.y <= p.y) && (p.y < u0.y))) // U0 is above the ray, U1 is on or below the ray
440 {
441 // find x-intersection of current edge with the ray.
442 // Only consider edge crossings on the ray to the right of P.
443 double x = u0.x + (p.y - u0.y) * (u1.x - u0.x) / (u1.y - u0.y);
444 if (x > p.x)
445 inside = !inside;
446 }
447 }
448
449 return inside;
450 }
451
452 //-----------------------------------------------------------------------------
453
454 inline float dist_point_line_segment(const vec3 &p, const vec3 &v0, const vec3 &v1, vec3 &nearest_point) {
455 vec3 d1(p - v0);
456 vec3 d2(v1 - v0);
457 vec3 min_v(v0);
458 float t = dot(d2, d2);
459
460 if (t > FLT_MIN) {
461 t = dot(d1, d2) / t;
462 if (t > 1.0)
463 d1 = p - (min_v = v1);
464 else if (t > 0.0)
465 d1 = p - (min_v = v0 + d2 * t);
466 }
467
468 nearest_point = min_v;
469 return norm(d1);
470 }
471
472 //-----------------------------------------------------------------------------
473
474 inline float
475 dist_point_triangle(const vec3 &p, const vec3 &v0, const vec3 &v1, const vec3 &v2, vec3 &nearest_point) {
476 vec3 v0v1 = v1 - v0;
477 vec3 v0v2 = v2 - v0;
478 vec3 n = cross(v0v1, v0v2); // not normalized !
479 float len2 = length2(n);
480
481 // Check if the triangle is degenerated -> measure dist to line segments
482 if (fabs(len2) < FLT_MIN) {
483 vec3 q, qq;
484 float dd = dist_point_line_segment(p, v0, v1, qq);
485 float d = dist_point_line_segment(p, v1, v2, q);
486 if (d < dd) {
487 dd = d;
488 qq = q;
489 }
490
491 d = dist_point_line_segment(p, v2, v0, q);
492 if (d < dd) {
493 dd = d;
494 qq = q;
495 }
496
497 nearest_point = qq;
498 return dd;
499 }
500
501 float inv_d = 1.0f / len2;
502 vec3 v1v2 = v2;
503 v1v2 -= v1;
504 vec3 v0p = p;
505 v0p -= v0;
506 vec3 t = cross(v0p, n);
507 float a = dot(t, v0v2) * -inv_d;
508 float b = dot(t, v0v1) * inv_d;
509 float s01, s02, s12;
510
511 // Calculate the distance to an edge or a corner vertex
512 if (a < 0) {
513 s02 = dot(v0v2, v0p) / length2(v0v2);
514 if (s02 < 0.0) {
515 s01 = dot(v0v1, v0p) / length2(v0v1);
516 if (s01 <= 0.0) {
517 v0p = v0;
518 } else if (s01 >= 1.0) {
519 v0p = v1;
520 } else {
521 (v0p = v0) += (v0v1 *= s01);
522 }
523 } else if (s02 > 1.0) {
524 s12 = dot(v1v2, (p - v1)) / length2(v1v2);
525 if (s12 >= 1.0) {
526 v0p = v2;
527 } else if (s12 <= 0.0) {
528 v0p = v1;
529 } else {
530 (v0p = v1) += (v1v2 *= s12);
531 }
532 } else {
533 (v0p = v0) += (v0v2 *= s02);
534 }
535 }
536
537 // Calculate the distance to an edge or a corner vertex
538 else if (b < 0.0) {
539 s01 = dot(v0v1, v0p) / length2(v0v1);
540 if (s01 < 0.0) {
541 s02 = dot(v0v2, v0p) / length2(v0v2);
542 if (s02 <= 0.0) {
543 v0p = v0;
544 } else if (s02 >= 1.0) {
545 v0p = v2;
546 } else {
547 (v0p = v0) += (v0v2 *= s02);
548 }
549 } else if (s01 > 1.0) {
550 s12 = dot(v1v2, (p - v1)) / length2(v1v2);
551 if (s12 >= 1.0) {
552 v0p = v2;
553 } else if (s12 <= 0.0) {
554 v0p = v1;
555 } else {
556 (v0p = v1) += (v1v2 *= s12);
557 }
558 } else {
559 (v0p = v0) += (v0v1 *= s01);
560 }
561 }
562
563 // Calculate the distance to an edge or a corner vertex
564 else if (a + b > 1.0) {
565 s12 = dot(v1v2, (p - v1)) / length2(v1v2);
566 if (s12 >= 1.0) {
567 s02 = dot(v0v2, v0p) / length2(v0v2);
568 if (s02 <= 0.0) {
569 v0p = v0;
570 } else if (s02 >= 1.0) {
571 v0p = v2;
572 } else {
573 (v0p = v0) += (v0v2 *= s02);
574 }
575 } else if (s12 <= 0.0) {
576 s01 = dot(v0v1, v0p) / length2(v0v1);
577 if (s01 <= 0.0) {
578 v0p = v0;
579 } else if (s01 >= 1.0) {
580 v0p = v1;
581 } else {
582 (v0p = v0) += (v0v1 *= s01);
583 }
584 } else {
585 (v0p = v1) += (v1v2 *= s12);
586 }
587 }
588
589 // Calculate the distance to an interior point of the triangle
590 else {
591 n *= (dot(n, v0p) * inv_d);
592 (v0p = p) -= n;
593 }
594
595 nearest_point = v0p;
596 v0p -= p;
597 return norm(v0p);
598 }
599
600
601 inline vec3 tetra_circum_center(const vec3 &p, const vec3 &q, const vec3 &r, const vec3 &s) {
602 vec3 qp = q - p;
603 float qp2 = length2(qp);
604 vec3 rp = r - p;
605 float rp2 = length2(rp);
606 vec3 sp = s - p;
607 float sp2 = length2(sp);
608
609 double num_x = determinant(mat3(
610 qp.y, qp.z, qp2,
611 rp.y, rp.z, rp2,
612 sp.y, sp.z, sp2)
613 );
614 double num_y = determinant(mat3(
615 qp.x, qp.z, qp2,
616 rp.x, rp.z, rp2,
617 sp.x, sp.z, sp2)
618 );
619 double num_z = determinant(mat3(
620 qp.x, qp.y, qp2,
621 rp.x, rp.y, rp2,
622 sp.x, sp.y, sp2)
623 );
624 double den = determinant(mat3(
625 qp.x, qp.y, qp.z,
626 rp.x, rp.y, rp.z,
627 sp.x, sp.y, sp.z)
628 );
629
630 assert(std::abs(den) > 1e-30f);
631
632 den *= 2.0f;
633
634 return vec3(
635 p.x + float(num_x / den),
636 p.y - float(num_y / den),
637 p.z + float(num_z / den)
638 );
639
640 }
641
642 } // namespace geom
643
644} // namespace easy3d
645// \cond
646
647#endif // EASY3D_CORE_TYPES_H
648
649
GenericBox represents the bounding box of shapes.
Definition: box.h:47
A generic line representation, which supports both 2D and 3D lines.
Definition: line.h:40
OrientedLine implements plucker coordinates, which enables oriented lines to be compared.
Definition: oriented_line.h:43
A 2D polygon representation.
Definition: polygon.h:41
The GenericRect class defines a rectangle in the 2D space.
Definition: rect.h:42
A generic segmentation representation, which supports both 2D and 3D line segments.
Definition: segment.h:43
2 by 2 matrix. Extends Mat with 2D-specific functionality and constructors.
Definition: mat.h:1460
3x3 matrix. Extends Mat with 3D-specific functionality and constructors.
Definition: mat.h:1620
Base class for matrix types.
Definition: mat.h:66
Base class for vector types. It provides generic functionality for N dimensional vectors.
Definition: vec.h:34
size_t size() const
Returns the dimension/size of this vector.
Definition: vec.h:78
double cos_angle(const Vec &a, const Vec &b)
Computes cosine of angle between two (un-normalized) vectors.
Definition: types.h:243
vec3 centroid(const SurfaceMesh *mesh, SurfaceMesh::Face f)
barycenter/centroid of a face
Definition: surface_mesh_geometry.cpp:67
vec3 tetra_circum_center(const vec3 &p, const vec3 &q, const vec3 &r, const vec3 &s)
Computes the circum center of a tetrahedron.
Box bounding_box(const Container &points)
Computes the bounding box of a set of points.
Definition: types.h:180
double angle(const Vec &a, const Vec &b)
Computes angle between two (un-normalized) vectors.
Definition: types.h:261
float dist_point_triangle(const vec3 &p, const vec3 &v0, const vec3 &v1, const vec3 &v2, vec3 &nearest_point)
Computes the distance of a point p to the triangle given by vec3s (v0, v1, v2).
Vec< 3, FT > barycentric_coordinates(const Vec< 3, FT > &p, const Vec< 3, FT > &u, const Vec< 3, FT > &v, const Vec< 3, FT > &w)
Computes the barycentric coordinates of a point p with respect to three points u, v,...
float triangle_area(const SurfaceMesh *mesh, SurfaceMesh::Face f)
compute area of triangle f
Definition: surface_mesh_geometry.cpp:22
Vec barycenter(const Vec &p1, const Vec &p2)
Computes the barycenter of two points.
Definition: types.h:199
float triangle_signed_area(const vec2 &p1, const vec2 &p2, const vec2 &p3)
Computes signed area of a triangle given by three points.
Definition: types.h:283
double clamp_cot(const double v)
Clamps cotangent values as if angles are in [1, 179]
Definition: types.h:230
FT to_radians(FT degrees)
Converts an angle from degrees to radians.
Definition: types.h:267
Vec::FT cotan_angle(const Vec &a, const Vec &b)
Computes cotangent of angle between two (un-normalized) vectors.
Definition: types.h:255
vec3 triangle_normal(const vec3 &p1, const vec3 &p2, const vec3 &p3)
Computes the normal vector of a triangle given by three points.
Definition: types.h:288
float dist_point_line_segment(const vec3 &p, const vec3 &v0, const vec3 &v1, vec3 &nearest_point)
Computes the distance of a point p to a line segment given by vec3s (v0,v1).
bool point_in_polygon(const vec2 &p, const std::vector< vec2 > &polygon)
Tests if a point p lies inside or outside of a polygon. This function is robust to handle general pol...
vec3 orthogonal(const vec3 &v)
Returns a vector orthogonal to v. Its norm() depends on v, but is zero only for a null v.
Definition: types.h:163
double clamp_cos(const double v)
Clamps cosine values as if angles are in [1, 179]
Definition: types.h:236
FT to_degrees(FT radians)
Converts an angle from radians to degrees.
Definition: types.h:273
double sin_angle(const Vec &a, const Vec &b)
Computes sine of angle between two (un-normalized) vectors.
Definition: types.h:249
Definition: collider.cpp:182
Mat2< double > dmat2
A 2 by 2 matrix of double type.
Definition: types.h:75
Mat< 4, 3, float > mat43
A 4 by 3 matrix of float type.
Definition: types.h:72
Vec< 3, float > vec3
A 3D point/vector of float type.
Definition: types.h:45
Mat< 3, 4, double > dmat34
A 3 by 4 matrix of double type.
Definition: types.h:81
GenericOrientedLine< float > OrientedLine3
A 3D oriented line of float type.
Definition: types.h:96
GenericPolygon< float > Polygon2
A 2D polygon of float type.
Definition: types.h:117
T determinant(const Mat< N, N, T > &m)
Return the determinant of N x N (square) matrix m.
GenericRect< float > Rect
A 2D axis-aligned rectangle of float type.
Definition: types.h:112
GenericBox< 2, float > Box2
A 2D axis-aligned bounding box of float type.
Definition: types.h:107
Vec< 3, double > dvec3
A 3D point/vector of double type.
Definition: types.h:52
Vec< 2, int32_t > ivec2
A 2D point/vector of int32_t type.
Definition: types.h:57
Mat4< double > dmat4
A 4 by 4 matrix of double type.
Definition: types.h:79
int next_pow2(int a)
Calculates the next larger power of 2. If the input is already a power of 2, it will return itself.
Definition: types.h:143
Vec< 4, int32_t > ivec4
A 4D point/vector of int32_t type.
Definition: types.h:61
GenericBox< 3, float > Box3
A 3D axis-aligned bounding box of float type.
Definition: types.h:109
Vec< 2, double > dvec2
A 2D point/vector of double type.
Definition: types.h:50
GenericRect< int32_t > iRect
A 2D axis-aligned rectangle of int32_t type.
Definition: types.h:114
T clamp(T x, T lower, T upper)
Clamps a num to be within a given range.
Definition: types.h:130
Quat< float > quat
A quaternion of float type.
Definition: types.h:86
Mat2< float > mat2
A 2 by 2 matrix of float type.
Definition: types.h:64
T length(const Vec< N, T > &v)
Computes the length/magnitude of a vector.
Definition: vec.h:289
GenericPlane< float > Plane3
A 3D plane of float type.
Definition: types.h:104
Vec< 3, int32_t > ivec3
A 3D point/vector of int32_t type.
Definition: types.h:59
GenericLine< 3, float > Line3
A 3D line of float type.
Definition: types.h:93
GenericSegment< 3, float > Segment3
A 3D line segment of float type.
Definition: types.h:101
T det(const Vec< 2, T > &v1, const Vec< 2, T > &v2)
Compute the determinant of the 2x2 matrix formed by the two 2D vectors as the two rows.
Definition: vec.h:405
Quat< double > dquat
A quaternion of double type.
Definition: types.h:88
Mat4< float > mat4
A 4 by 4 matrix of float type.
Definition: types.h:68
Mat3< float > mat3
A 3 by 3 matrix of float type.
Definition: types.h:66
Vec< 4, float > vec4
A 4D point/vector of float type.
Definition: types.h:47
Mat3< double > dmat3
A 3 by 3 matrix of double type.
Definition: types.h:77
Vec< 2, float > vec2
A 2D point/vector of float type.
Definition: types.h:43
GenericSegment< 2, float > Segment2
A 2D line segment of float type.
Definition: types.h:99
Vec< 3, T > cross(const Vec< 3, T > &v1, const Vec< 3, T > &v2)
Compute the cross product of two 3D vectors.
Definition: vec.h:534
GenericLine< 2, float > Line2
A 2D line of float type.
Definition: types.h:91
FT dot(const std::vector< FT > &, const std::vector< FT > &)
Inner product for vectors.
Definition: matrix.h:1803
Vec< 4, double > dvec4
A 4D point/vector of double type.
Definition: types.h:54
Mat< 4, 3, double > dmat43
A 4 by 3 matrix of double type.
Definition: types.h:83
FT norm(const Matrix< FT > &)
utilities
Definition: matrix.h:1424
Vec< N, T > normalize(const Vec< N, T > &v)
Computes and returns the normalized vector (Note: the input vector is not modified).
Definition: vec.h:299
bool is_nan(FT v)
Is this NaN?
Definition: types.h:122
FT truncate_digits(const FT &v, int num)
Rounds the given floating point number v to have num digits.
Definition: types.h:151
Mat< 3, 4, float > mat34
A 3 by 4 matrix of float type.
Definition: types.h:70
T length2(const Vec< N, T > &v)
Computes the squared length/magnitude of a vector.
Definition: vec.h:293