You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
2.8 KiB
134 lines
2.8 KiB
4 years ago
|
#ifndef GFXGEOM3D_INCLUDED
|
||
|
#define GFXGEOM3D_INCLUDED
|
||
|
#if !defined(__GNUC__)
|
||
|
# pragma once
|
||
|
#endif
|
||
|
|
||
|
/************************************************************************
|
||
|
|
||
|
Handy 3D geometrical primitives
|
||
|
|
||
|
$Id: geom3d.h 432 2004-11-02 22:55:41Z garland $
|
||
|
|
||
|
************************************************************************/
|
||
|
|
||
|
#include "vec3.h"
|
||
|
|
||
|
namespace gfx
|
||
|
{
|
||
|
|
||
|
//
|
||
|
// Computing properties of triangles
|
||
|
//
|
||
|
|
||
|
template<class Vec>
|
||
|
inline Vec triangle_raw_normal(const Vec& v1, const Vec& v2, const Vec& v3)
|
||
|
{
|
||
|
return cross(v2-v1, v3-v1);
|
||
|
}
|
||
|
|
||
|
template<class Vec>
|
||
|
inline typename Vec::value_type
|
||
|
triangle_area(const Vec& v1,const Vec& v2,const Vec& v3)
|
||
|
{
|
||
|
return 0.5 * norm(triangle_raw_normal(v1, v2, v3));
|
||
|
}
|
||
|
|
||
|
template<class Vec>
|
||
|
inline Vec triangle_normal(const Vec& v1, const Vec& v2, const Vec& v3)
|
||
|
{
|
||
|
Vec n = triangle_raw_normal(v1, v2, v3);
|
||
|
unitize(n);
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
template<class Vec, class Plane>
|
||
|
inline Plane triangle_plane(const Vec& v1, const Vec& v2, const Vec& v3)
|
||
|
{
|
||
|
Vec n = triangle_normal(v1, v2, v3);
|
||
|
return Plane(n, -(n*v1));
|
||
|
}
|
||
|
|
||
|
template<class Vec, class Plane>
|
||
|
inline Plane triangle_raw_plane(const Vec& v1, const Vec& v2, const Vec& v3)
|
||
|
{
|
||
|
Vec n = triangle_raw_normal(v1, v2, v3);
|
||
|
return Plane(n, -(n*v1));
|
||
|
}
|
||
|
|
||
|
template< class Vec>
|
||
|
inline typename Vec::value_type
|
||
|
triangle_compactness(const Vec& v1, const Vec& v2, const Vec& v3)
|
||
|
{
|
||
|
const double FOUR_ROOT3 = 6.928203230275509;
|
||
|
|
||
|
return FOUR_ROOT3 * triangle_area(v1, v2, v3) /
|
||
|
( norm2(v2 - v1) + norm2(v3 - v2) + norm2(v1 - v3) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Operations with axis-aligned bounding boxes
|
||
|
//
|
||
|
|
||
|
template<class Vec, class List>
|
||
|
void update_bbox(Vec& min, Vec& max, const List& items)
|
||
|
{
|
||
|
typedef typename List::const_iterator iterator;
|
||
|
|
||
|
for(iterator i=items.begin(); i!=items.end(); i++)
|
||
|
{
|
||
|
const Vec& v = *i;
|
||
|
for(int j=0; j<Vec::dim(); j++)
|
||
|
{
|
||
|
if( v[j] < min[j] ) min[j] = v[j];
|
||
|
if( v[j] > max[j] ) max[j] = v[j];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template<class Vec, class List>
|
||
|
void compute_bbox(Vec& min, Vec& max, const List& items)
|
||
|
{
|
||
|
if( items.size()==0 ) min = max = 0;
|
||
|
else min = max = items[0];
|
||
|
|
||
|
update_bbox(min, max, items);
|
||
|
}
|
||
|
|
||
|
template<class Vec>
|
||
|
bool is_inside_bbox(const Vec& p, const Vec& min, Vec& max)
|
||
|
{
|
||
|
for(int i=0; i<Vec::dim(); i++)
|
||
|
if( p[i]<min[i] || p[i]>max[i] )
|
||
|
return false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
template<class Vec>
|
||
|
Vec clamp_to_bbox(Vec p, const Vec& min, const Vec& max)
|
||
|
{
|
||
|
for(int i=0; i<Vec::dim(); i++)
|
||
|
{
|
||
|
if (p[i]<min[i]) p[i]=min[i];
|
||
|
else if (p[i]>max[i]) p[i]=max[i];
|
||
|
}
|
||
|
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Computing properties of tetrahedra
|
||
|
//
|
||
|
|
||
|
extern double tetrahedron_determinant(const Vec3& v0, const Vec3& v1,
|
||
|
const Vec3& v2, const Vec3& v3);
|
||
|
|
||
|
extern double tetrahedron_volume(const Vec3& v0, const Vec3& v1,
|
||
|
const Vec3& v2, const Vec3& v3);
|
||
|
|
||
|
} // namespace gfx
|
||
|
|
||
|
// GFXGEOM3D_INCLUDED
|
||
|
#endif
|