MeshLib C++ Docs
Loading...
Searching...
No Matches
Math group

Topics

 2d <-> 3d conversion
 BestFit
 Box
 Constants
 Contour
 High Precision
 Intersection
 Matrix
 Aligning Transform
 Ray Box Intersection
 Triangle intersection
 Tuple Bindings
 Vector

Classes

class  MR::QuadricApprox
struct  MR::DenseBox
class  MR::Histogram
struct  MR::Line< V >
struct  MR::Plane3< T >
struct  MR::PreciseVertCoord
struct  MR::QuadraticForm< V >
struct  MR::Quaternion< T >
struct  MR::SegmPoint< T >
 encodes a point inside a line segment using relative distance in [0,1] More...
struct  MR::Sphere< V >
struct  MR::TriPoint< T >
 encodes a point inside a triangle using barycentric coordinates More...

Functions

template<typename V>
 MR::MR_REQUIRES_IF_SUPPORTED (detail::AffineXf3f::IsValidTemplateArg< V >) struct AffineXf
template<typename T>
AffineXf3< T > MR::lookAt (const Vector3< T > &center, const Vector3< T > &eye, const Vector3< T > &up)
 computes rigid transformation xf
template<typename V>
Box< V > MR::computeBoundingBox (const Vector< V, VertId > &points, VertId firstVert, VertId lastVert, const VertBitSet *region=nullptr, const AffineXf< V > *toWorld=nullptr)
template<typename V>
Box< V > MR::computeBoundingBox (const Vector< V, VertId > &points, const VertBitSet *region=nullptr, const AffineXf< V > *toWorld=nullptr)
template<typename V>
Box< V > MR::computeBoundingBox (const Vector< V, VertId > &points, const VertBitSet &region, const AffineXf< V > *toWorld=nullptr)
AffineXf3d MR::makeRigidXf (const MeshPart &mp, const AffineXf3d &meshXf)
template<typename T>
MR::circumcircleDiameterSq (const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
template<typename T>
MR::circumcircleDiameter (const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
template<typename T>
MR::mincircleDiameterSq (const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
template<typename T>
MR::edgeCoveringRadiusSq (const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
template<typename T>
MR::coveringRadiusSq (const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
template<typename T>
MR::minTriangleAngleSin (const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
template<typename T>
MR::triangleAspectRatio (const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
template<typename T>
MR::dihedralAngleSin (const Vector3< T > &leftNorm, const Vector3< T > &rightNorm, const Vector3< T > &edgeVec)
template<typename T>
MR::dihedralAngleCos (const Vector3< T > &leftNorm, const Vector3< T > &rightNorm)
template<typename T>
MR::dihedralAngle (const Vector3< T > &leftNorm, const Vector3< T > &rightNorm, const Vector3< T > &edgeVec)
enum class  MR::InSphereResult { MR::InSphereResult::NoSphere , MR::InSphereResult::Outside , MR::InSphereResult::OnSphere , MR::InSphereResult::Inside }
 the result of inSphere predicates More...
InSphereResult MR::inSphere (const Vector3i &a, const Vector3i &b, const Vector3i &c, const Vector3i &d, std::int64_t rSq)
InSphereResult MR::inSphere (const std::array< PreciseVertCoords, 4 > &vs, std::int64_t rSq)
template<typename T>
std::enable_if_t< std::is_floating_point_v< T >, InSphereResultMR::inSphere (const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c, const Vector3< T > &d, T rSq)
 MR::MR_BIND_TEMPLATE (InSphereResult inSphere(const Vector3f &a, const Vector3f &b, const Vector3f &c, const Vector3f &d, float rSq))
 MR::MR_BIND_TEMPLATE (InSphereResult inSphere(const Vector3d &a, const Vector3d &b, const Vector3d &c, const Vector3d &d, double rSq))
using MR::InSphereTesterf = InSphereTester<float>
using MR::InSphereTesterd = InSphereTester<double>
using MR::InSphereTesteri = InSphereTester<int>
bool MR::orient3d (const Vector3i &a, const Vector3i &b, const Vector3i &c)
bool MR::orient3d (const Vector3i &a, const Vector3i &b, const Vector3i &c, const Vector3i &d)
bool MR::orient3d (const PreciseVertCoords *vs)
bool MR::orient3d (const std::array< PreciseVertCoords, 4 > &vs)
bool MR::ccwAroundLine (const PreciseVertCoords *vs)
bool MR::ccwAroundLine (const std::array< PreciseVertCoords, 5 > &vs)
TriangleSegmentIntersectResult MR::doTriangleSegmentIntersect (const std::array< PreciseVertCoords, 5 > &vs)
bool MR::segmentIntersectionOrder (const std::array< PreciseVertCoords, 8 > &vs)
bool MR::segmentIntersectionTriPlaneOrder (const std::array< PreciseVertCoords, 8 > &vs)
ConvertToIntVector MR::getToIntConverter (const Box3d &box)
 creates converter from Vector3f to Vector3i in Box range (int diapason is mapped to box range)
ConvertToFloatVector MR::getToFloatConverter (const Box3d &box)
 creates converter from Vector3i to Vector3f in Box range (int diapason is mapped to box range)
Vector< Vector3i, VertId > MR::computeIntCoords (const ConvertToIntVector &conv, const VertCoords &points, const VertBitSet *valid=nullptr)
VertCoords MR::computeFloatCoords (const ConvertToFloatVector &conv, const Vector< Vector3i, VertId > &intCoords, const VertBitSet *valid=nullptr)
std::optional< Vector3i > MR::findTwoSegmentsIntersection (const Vector3i &ai, const Vector3i &bi, const Vector3i &ci, const Vector3i &di)
Vector3f MR::findTriangleSegmentIntersectionPrecise (const Vector3f &a, const Vector3f &b, const Vector3f &c, const Vector3f &d, const Vector3f &e, CoordinateConverters converters)
template<typename T>
Vector2< T > MR::fromEigen (const Eigen::Matrix< T, 2, 1 > &ev)
template<typename T>
Eigen::Matrix< T, 2, 1 > MR::toEigen (const Vector2< T > &v)
template<typename T>
Eigen::Matrix< T, 2, 2 > MR::toEigen (const SymMatrix2< T > &m)
template<typename T>
Eigen::Matrix< T, 2, 2 > MR::toEigen (const Matrix2< T > &m)
template<typename T>
Matrix2< T > MR::fromEigen (const Eigen::Matrix< T, 2, 2 > &m)
template<typename T>
Vector3< T > MR::fromEigen (const Eigen::Matrix< T, 3, 1 > &ev)
template<typename T>
Eigen::Matrix< T, 3, 1 > MR::toEigen (const Vector3< T > &v)
template<typename T>
Eigen::Matrix< T, 3, 3 > MR::toEigen (const SymMatrix3< T > &m)
template<typename T>
Eigen::Matrix< T, 3, 3 > MR::toEigen (const Matrix3< T > &m)
template<typename T>
Matrix3< T > MR::fromEigen (const Eigen::Matrix< T, 3, 3 > &m)
template<typename T>
Eigen::Matrix< T, 4, 4 > MR::toEigen (const SymMatrix4< T > &m)
template<typename T>
Eigen::Matrix< T, 4, 4 > MR::toEigen (const Matrix4< T > &m)
template<typename T>
Matrix4< T > MR::fromEigen (const Eigen::Matrix< T, 4, 4 > &m)
template<typename T>
Vector4< T > MR::fromEigen (const Eigen::Matrix< T, 4, 1 > &ev)
template<typename T>
Eigen::Matrix< T, 4, 1 > MR::toEigen (const Vector4< T > &v)
template<typename T>
Eigen::Matrix< T, 4, 1 > MR::toEigen (const Vector3< T > &v, T w)
template<typename T>
Quaternion< T > MR::fromEigen (const Eigen::Quaternion< T > &eq)
template<typename T>
Eigen::Quaternion< T > MR::toEigen (const Quaternion< T > &q)

Detailed Description

Typedef Documentation

◆ InSphereTesterd

◆ InSphereTesterf

◆ InSphereTesteri

Enumeration Type Documentation

◆ InSphereResult

enum class MR::InSphereResult
strong

#include <MRMesh/MRInSphere.h>

the result of inSphere predicates

Enumerator
NoSphere 

the sphere is not defined: the points A, B, C are collinear or coincident, or rSq is less than the squared circumradius of triangle ABC

Outside 

the sphere exists, and the point D is strictly outside

OnSphere 

the sphere exists, and the point D is exactly on it; never returned by the simulation-of-simplicity overload, which resolves such ties into Inside or Outside

Inside 

the sphere exists, and the point D is strictly inside

Function Documentation

◆ ccwAroundLine() [1/2]

bool MR::ccwAroundLine ( const PreciseVertCoords * vs)
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

Precise predicate for the rotational order of three half-planes around a directed line. The line passes via vs[0] and vs[1] and is directed from vs[0] to vs[1]; the three half-planes are bounded by that line and pass via vs[2], vs[3], vs[4] respectively. Returns true iff the half-planes follow one another in counter-clockwise order around the line, as seen by the viewer the line's direction points at. Only the rotation of every point around the line matters, so cyclic permutations of vs[2], vs[3], vs[4] do not change the result, while a swap of two of them, as well as a swap of vs[0] and vs[1], inverts it. Implemented via orient3d and inherits its simulation-of-simplicity, so the predicate is never "undefined" even if some of the points coincide; all five ids must be distinct.

◆ ccwAroundLine() [2/2]

bool MR::ccwAroundLine ( const std::array< PreciseVertCoords, 5 > & vs)
inlinenodiscard

◆ circumcircleDiameter()

template<typename T>
T MR::circumcircleDiameter ( const Vector3< T > & a,
const Vector3< T > & b,
const Vector3< T > & c )
inlinenodiscard

#include <MRMesh/MRTriMath.h>

Computes the diameter of the triangle's ABC circumcircle

◆ circumcircleDiameterSq()

template<typename T>
T MR::circumcircleDiameterSq ( const Vector3< T > & a,
const Vector3< T > & b,
const Vector3< T > & c )
nodiscard

#include <MRMesh/MRTriMath.h>

Computes the squared diameter of the triangle's ABC circumcircle;

◆ computeBoundingBox() [1/3]

template<typename V>
Box< V > MR::computeBoundingBox ( const Vector< V, VertId > & points,
const VertBitSet & region,
const AffineXf< V > * toWorld = nullptr )
inline

#include <MRMesh/MRComputeBoundingBox.h>

passes through all region points corresponding to set bits in region and finds the minimal bounding box containing all of them; if toWorld transformation is given then returns minimal bounding box in world space

◆ computeBoundingBox() [2/3]

template<typename V>
Box< V > MR::computeBoundingBox ( const Vector< V, VertId > & points,
const VertBitSet * region = nullptr,
const AffineXf< V > * toWorld = nullptr )
inline

#include <MRMesh/MRComputeBoundingBox.h>

passes through all region points corresponding to set bits in region (if provided) and finds the minimal bounding box containing all of them; if toWorld transformation is given then returns minimal bounding box in world space

◆ computeBoundingBox() [3/3]

template<typename V>
Box< V > MR::computeBoundingBox ( const Vector< V, VertId > & points,
VertId firstVert,
VertId lastVert,
const VertBitSet * region = nullptr,
const AffineXf< V > * toWorld = nullptr )

#include <MRMesh/MRComputeBoundingBox.h>

passes through all region points 1) in the range [firstVert, lastVert) 2) corresponding to set bits in region (if provided) and finds the minimal bounding box containing all of them; if toWorld transformation is given then returns minimal bounding box in world space

◆ computeFloatCoords()

VertCoords MR::computeFloatCoords ( const ConvertToFloatVector & conv,
const Vector< Vector3i, VertId > & intCoords,
const VertBitSet * valid = nullptr )
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

converts given integer coordinates into float points in parallel

Parameters
validif given then only valid coordinates are converted, and the content of other elements in the returned vector is undefined

◆ computeIntCoords()

Vector< Vector3i, VertId > MR::computeIntCoords ( const ConvertToIntVector & conv,
const VertCoords & points,
const VertBitSet * valid = nullptr )
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

converts given points into integer coordinates in parallel

Parameters
validif given then only valid points are converted, and the content of other elements in the returned vector is undefined

◆ coveringRadiusSq()

template<typename T>
T MR::coveringRadiusSq ( const Vector3< T > & a,
const Vector3< T > & b,
const Vector3< T > & c )
nodiscard

#include <MRMesh/MRTriMath.h>

Computes the squared maximal distance from a point of the triangle ABC to the nearest of its vertices, so the balls of that radius around the vertices cover the whole triangle. For non-obtuse triangles it is the squared circumradius, and for obtuse ones it can be much smaller than in the minimal enclosing circle, e.g. when the third vertex is near the longest edge

a non-obtuse triangle contains its circumcenter, which is the farthest point from the vertices; this is circumcircleDiameterSq / 4 written on the lengths already at hand, and none of the guards in it can trigger here: a triangle with a zero side or zero area is obtuse by the test

otherwise that point is on the boundary, where the two nearest vertices are equidistant, and always on the longest edge: the circumcenter is beyond it, the distance along every bisector grows towards the circumcenter, so each bisector is maximal where it meets that edge

◆ dihedralAngle()

template<typename T>
T MR::dihedralAngle ( const Vector3< T > & leftNorm,
const Vector3< T > & rightNorm,
const Vector3< T > & edgeVec )
nodiscard

#include <MRMesh/MRTriMath.h>

given an edge direction between two faces with given normals (not necessary of unit length), computes the dihedral angle between the faces: 0 if both faces are in the same plane, positive if the faces form convex surface, negative if the faces form concave surface; please consider the usage of faster dihedralAngleSin(e) and dihedralAngleCos(e)

◆ dihedralAngleCos()

template<typename T>
T MR::dihedralAngleCos ( const Vector3< T > & leftNorm,
const Vector3< T > & rightNorm )
nodiscard

#include <MRMesh/MRTriMath.h>

given two face normals, computes cosine of dihedral angle between the faces: 1 if both faces are in the same plane, 0 if the surface makes right angle turn at the edge, -1 if the faces overlap one another

◆ dihedralAngleSin()

template<typename T>
T MR::dihedralAngleSin ( const Vector3< T > & leftNorm,
const Vector3< T > & rightNorm,
const Vector3< T > & edgeVec )
nodiscard

#include <MRMesh/MRTriMath.h>

given an edge direction between two faces with given normals, computes sine of dihedral angle between the faces: 0 if both faces are in the same plane, positive if the faces form convex surface, negative if the faces form concave surface

◆ doTriangleSegmentIntersect()

TriangleSegmentIntersectResult MR::doTriangleSegmentIntersect ( const std::array< PreciseVertCoords, 5 > & vs)
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

checks whether triangle ABC (vertices 0,1,2) and segment DE (vertices 3,4) intersect. Simulation-of-simplicity removes the degenerate cases (segment passing exactly through an edge or vertex of the triangle, or lying in the triangle's plane), so the answer is always a clean yes/no.

◆ edgeCoveringRadiusSq()

template<typename T>
T MR::edgeCoveringRadiusSq ( const Vector3< T > & a,
const Vector3< T > & b,
const Vector3< T > & c )
nodiscard

#include <MRMesh/MRTriMath.h>

Computes the squared maximal distance from a point of the segment AB to the nearest of the points A, B and C: this is where the balls of that radius around the three points stop covering the segment

where C projects on the segment, times its length

squared distance from the point in the given relative position to the nearest of A, B and C

that distance is maximal where the two nearest of the points are equidistant

A and B

A and C

B and C

◆ findTriangleSegmentIntersectionPrecise()

Vector3f MR::findTriangleSegmentIntersectionPrecise ( const Vector3f & a,
const Vector3f & b,
const Vector3f & c,
const Vector3f & d,
const Vector3f & e,
CoordinateConverters converters )
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

finds intersection precise, using high precision int inside this function input should have intersection

◆ findTwoSegmentsIntersection()

std::optional< Vector3i > MR::findTwoSegmentsIntersection ( const Vector3i & ai,
const Vector3i & bi,
const Vector3i & ci,
const Vector3i & di )
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

given two line segments AB and CD located in one plane, finds whether they intersect and if yes, computes their common point using integer-only arithmetic

◆ fromEigen() [1/7]

template<typename T>
Vector2< T > MR::fromEigen ( const Eigen::Matrix< T, 2, 1 > & ev)
inlinenodiscard

◆ fromEigen() [2/7]

template<typename T>
Matrix2< T > MR::fromEigen ( const Eigen::Matrix< T, 2, 2 > & m)
inlinenodiscard

◆ fromEigen() [3/7]

template<typename T>
Vector3< T > MR::fromEigen ( const Eigen::Matrix< T, 3, 1 > & ev)
inlinenodiscard

◆ fromEigen() [4/7]

template<typename T>
Matrix3< T > MR::fromEigen ( const Eigen::Matrix< T, 3, 3 > & m)
inlinenodiscard

◆ fromEigen() [5/7]

template<typename T>
Vector4< T > MR::fromEigen ( const Eigen::Matrix< T, 4, 1 > & ev)
inlinenodiscard

◆ fromEigen() [6/7]

template<typename T>
Matrix4< T > MR::fromEigen ( const Eigen::Matrix< T, 4, 4 > & m)
inlinenodiscard

◆ fromEigen() [7/7]

template<typename T>
Quaternion< T > MR::fromEigen ( const Eigen::Quaternion< T > & eq)
inlinenodiscard

◆ getToFloatConverter()

ConvertToFloatVector MR::getToFloatConverter ( const Box3d & box)
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

creates converter from Vector3i to Vector3f in Box range (int diapason is mapped to box range)

◆ getToIntConverter()

ConvertToIntVector MR::getToIntConverter ( const Box3d & box)
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

creates converter from Vector3f to Vector3i in Box range (int diapason is mapped to box range)

◆ inSphere() [1/3]

InSphereResult MR::inSphere ( const std::array< PreciseVertCoords, 4 > & vs,
std::int64_t rSq )
nodiscard

#include <MRMesh/MRInSphere.h>

checks whether the point vs[3] is strictly inside the sphere of radius sqrt(rSq) passing via points vs[0], vs[1], vs[2], with the center located on the positive side of plane vs[0]vs[1]vs[2] (same convention as in the overload above); full simulation-of-simplicity semantics: the answer equals the answer of the plain predicate on the symbolically perturbed points, where the point with rank r among the four (by ascending ids) receives +eps^(9*L^r) to x, +eps^(3*L^r) to y, +eps^(L^r) to z with L = 128, eps -> +0 (z gets the largest perturbation as in getPointDegrees, but the ladder between the ranks is 128: it exceeds the maximal degree-weight of one point in the predicate polynomials, which makes the resolution independent of whether the ranks are computed among 3 or among all 4 points); consequently:

  • "vs[3] exactly on the sphere" resolves into Inside or Outside by the ids;
  • rSq exactly equal to the squared circumradius: the perturbation decides the sphere's existence, so the answer can be NoSphere even for vs[3] strictly inside;
  • three coincident or distinct collinear triangle points always give NoSphere: the perturbed triangle is needle-like (the perturbation magnitudes differ vastly) and its circumradius diverges as eps -> +0;
  • two coincident triangle points: the sphere exists iff 4*rSq*(Vx^2+Vy^2) > |V|^4 at the leading order (the pair separates along z), V = the third point minus the pair

◆ inSphere() [2/3]

template<typename T>
std::enable_if_t< std::is_floating_point_v< T >, InSphereResult > MR::inSphere ( const Vector3< T > & a,
const Vector3< T > & b,
const Vector3< T > & c,
const Vector3< T > & d,
T rSq )
nodiscard

#include <MRMesh/MRInSphere.h>

checks whether the point d is strictly inside the sphere of radius sqrt(rSq) passing via points a, b, c, whose center is located on the positive side of plane abc, in floating-point; see the comment on InSphereTester above for the limitations

◆ inSphere() [3/3]

InSphereResult MR::inSphere ( const Vector3i & a,
const Vector3i & b,
const Vector3i & c,
const Vector3i & d,
std::int64_t rSq )
nodiscard

#include <MRMesh/MRInSphere.h>

checks whether the point D is strictly inside the sphere of radius sqrt(rSq) passing via points A, B, C, whose center is located on the positive side of plane ABC (in the half-space pointed at by cross( b - a, c - a ) from the plane); returns OnSphere when D is exactly on the sphere; cyclic permutations of (A, B, C) do not change the result, a swap of two of them selects the mirror sphere; rSq must be given in the same integer grid units as the point coordinates

◆ lookAt()

template<typename T>
AffineXf3< T > MR::lookAt ( const Vector3< T > & center,
const Vector3< T > & eye,
const Vector3< T > & up )

#include <MRMesh/MRAffineXf3.h>

computes rigid transformation xf

xf.z - directed from center to eye
xf.x - directed orthogonal to up and xf.z
xf.y - directed orthogonal to xf.z and xf.x
xf(eye) = 0

◆ makeRigidXf()

AffineXf3d MR::makeRigidXf ( const MeshPart & mp,
const AffineXf3d & meshXf )
nodiscard

#include <MRMesh/MRMakeRigidXf.h>

given a mesh part and its arbitrary transformation, computes and returns the rigid transformation that best approximates meshXf

◆ mincircleDiameterSq()

template<typename T>
T MR::mincircleDiameterSq ( const Vector3< T > & a,
const Vector3< T > & b,
const Vector3< T > & c )
nodiscard

#include <MRMesh/MRTriMath.h>

Computes the squared diameter of the smallest enclosed circle around ABC; For acute triangles it is the same as circumcircle, for obtuse triangles - the circle with the longest triangle's edge as a diameter

◆ minTriangleAngleSin()

template<typename T>
T MR::minTriangleAngleSin ( const Vector3< T > & a,
const Vector3< T > & b,
const Vector3< T > & c )
nodiscard

#include <MRMesh/MRTriMath.h>

Computes sine of minimal angle in ABC triangle, which is equal to ratio of minimal edge length to circumcircle diameter

◆ MR_BIND_TEMPLATE() [1/2]

MR::MR_BIND_TEMPLATE ( InSphereResult inSphereconst Vector3d &a, const Vector3d &b, const Vector3d &c, const Vector3d &d, double rSq)

#include <MRMesh/MRInSphere.h>

◆ MR_BIND_TEMPLATE() [2/2]

MR::MR_BIND_TEMPLATE ( InSphereResult inSphereconst Vector3f &a, const Vector3f &b, const Vector3f &c, const Vector3f &d, float rSq)

#include <MRMesh/MRInSphere.h>

◆ MR_REQUIRES_IF_SUPPORTED()

template<typename V>
MR::MR_REQUIRES_IF_SUPPORTED ( detail::AffineXf3f::IsValidTemplateArg< V > )

#include <MRMesh/MRAffineXf.h>

affine transformation: y = A*x + b, where A in VxV, and b in V

Here U == V doesn't seem to cause any issues in the C++ code, but we're still disabling it because it somehow gets emitted when generating the bindings, and results in duplicate functions in C#.

creates translation-only transformation (with identity linear component)

creates linear-only transformation (without translation)

creates transformation with given linear part with given stable point

application of the transformation to a point

applies only linear part of the transformation to given vector (e.g. to normal) skipping adding shift (b) for example if this is a rigid transformation, then only rotates input vector

computes inverse transformation

composition of two transformations: \(y = (u * v) ( x ) = u( v( x ) ) = ( u.A * ( v.A * x + v.b ) + u.b ) = ( u.A * v.A ) * x + ( u.A * v.b + u.b )\)

◆ orient3d() [1/4]

bool MR::orient3d ( const PreciseVertCoords * vs)
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

Same predicate as orient3d( a, b, c, d ) evaluated on vs[0..3].pt, but first sorts the four vertices by their id (ascending, flipping the result once per swap). The simulation-of-simplicity perturbation depends on vertex id, so sorting makes the result depend only on the set of four vertices and not on the order they are passed in: every call involving the same four vertices agrees, which keeps orientation decisions consistent mesh-wide.

◆ orient3d() [2/4]

bool MR::orient3d ( const std::array< PreciseVertCoords, 4 > & vs)
inlinenodiscard

◆ orient3d() [3/4]

bool MR::orient3d ( const Vector3i & a,
const Vector3i & b,
const Vector3i & c )
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

Precise orientation predicate for the origin against the plane of triangle ABC. Returns true iff dot( a, cross( b, c ) ) > 0, i.e. (a, b, c) form a right-handed vector triple / the tetrahedron (origin, a, b, c) has positive signed volume. Geometrically the origin then lies on the side that the right-hand normal cross( b - a, c - a ) of triangle ABC points away from (equivalently, seen from the origin A->B->C winds clockwise). Simulation-of-simplicity resolves the degenerate case dot( a, cross( b, c ) ) == 0 (origin exactly on plane ABC) deterministically, so the predicate is never "undefined".

◆ orient3d() [4/4]

bool MR::orient3d ( const Vector3i & a,
const Vector3i & b,
const Vector3i & c,
const Vector3i & d )
inlinenodiscard

#include <MRMesh/MRPrecisePredicates3.h>

Precise orientation predicate for point D against the plane of triangle ABC (the general case of the 3-argument overload above, which tests the origin instead of D). Returns true iff dot( a - d, cross( b - d, c - d ) ) > 0, i.e. the tetrahedron (d, a, b, c) has positive signed volume. Geometrically D then lies on the side that the right-hand normal cross( b - a, c - a ) of triangle ABC points away from (equivalently, seen from D the vertices A->B->C wind clockwise). Simulation-of-simplicity resolves the degenerate case (D exactly on plane ABC) deterministically, so the predicate is never "undefined".

◆ segmentIntersectionOrder()

bool MR::segmentIntersectionOrder ( const std::array< PreciseVertCoords, 8 > & vs)
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

given line segment s (vertices 0,1) and two triangles ta (vertices 2,3,4) and tb (vertices 5,6,7), each known to be pierced by s, returns the order in which s meets them, using precise predicates. Here s^t denotes the point where segment s crosses triangle t, and s[0]/s[1] are the segment endpoints. Walking s from s[0] to s[1]: true: order is s[0], s^ta, s^tb, s[1] (ta met before tb) false: order is s[0], s^tb, s^ta, s[1] (tb met before ta) triangles ta and tb may share at most two vertices; all remaining vertices must be unique

◆ segmentIntersectionTriPlaneOrder()

bool MR::segmentIntersectionTriPlaneOrder ( const std::array< PreciseVertCoords, 8 > & vs)
nodiscard

#include <MRMesh/MRPrecisePredicates3.h>

given line segment s (vertices 0,1), triangle ta (vertices 2,3,4) known to be pierced by s, and infinite plane pb passing via vertices 5,6,7, returns the order in which the line of s meets ta and pb, using precise predicates. Here s^ta is the point where s crosses ta, and s^pb is the point where the line of s crosses pb. Walking the line in the direction from s[0] to s[1]: true: s^ta is met before s^pb (order is s[0], s^ta, s^pb) false: s^pb is met before s^ta (order is s^pb, s^ta, s[1]) ta and pb may share at most two vertices; all remaining vertices must be unique

◆ toEigen() [1/11]

template<typename T>
Eigen::Matrix< T, 2, 2 > MR::toEigen ( const Matrix2< T > & m)
inlinenodiscard

◆ toEigen() [2/11]

template<typename T>
Eigen::Matrix< T, 3, 3 > MR::toEigen ( const Matrix3< T > & m)
inlinenodiscard

◆ toEigen() [3/11]

template<typename T>
Eigen::Matrix< T, 4, 4 > MR::toEigen ( const Matrix4< T > & m)
inlinenodiscard

◆ toEigen() [4/11]

template<typename T>
Eigen::Quaternion< T > MR::toEigen ( const Quaternion< T > & q)
inlinenodiscard

◆ toEigen() [5/11]

template<typename T>
Eigen::Matrix< T, 2, 2 > MR::toEigen ( const SymMatrix2< T > & m)
inlinenodiscard

◆ toEigen() [6/11]

template<typename T>
Eigen::Matrix< T, 3, 3 > MR::toEigen ( const SymMatrix3< T > & m)
inlinenodiscard

◆ toEigen() [7/11]

template<typename T>
Eigen::Matrix< T, 4, 4 > MR::toEigen ( const SymMatrix4< T > & m)
inlinenodiscard

◆ toEigen() [8/11]

template<typename T>
Eigen::Matrix< T, 2, 1 > MR::toEigen ( const Vector2< T > & v)
inlinenodiscard

◆ toEigen() [9/11]

template<typename T>
Eigen::Matrix< T, 3, 1 > MR::toEigen ( const Vector3< T > & v)
inlinenodiscard

◆ toEigen() [10/11]

template<typename T>
Eigen::Matrix< T, 4, 1 > MR::toEigen ( const Vector3< T > & v,
T w )
inlinenodiscard

◆ toEigen() [11/11]

template<typename T>
Eigen::Matrix< T, 4, 1 > MR::toEigen ( const Vector4< T > & v)
inlinenodiscard

◆ triangleAspectRatio()

template<typename T>
T MR::triangleAspectRatio ( const Vector3< T > & a,
const Vector3< T > & b,
const Vector3< T > & c )
nodiscard

#include <MRMesh/MRTriMath.h>

Aspect ratio of a triangle is the ratio of the circum-radius to twice its in-radius