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.
80 lines
2.3 KiB
80 lines
2.3 KiB
//////////////////////////////////////////////////////////////////// |
|
// Sphere.inl |
|
// |
|
// Copyright 2007 cDc@seacave |
|
// Distributed under the Boost Software License, Version 1.0 |
|
// (See http://www.boost.org/LICENSE_1_0.txt) |
|
|
|
|
|
// D E F I N E S /////////////////////////////////////////////////// |
|
|
|
|
|
// S T R U C T S /////////////////////////////////////////////////// |
|
|
|
template <typename TYPE, int DIMS> |
|
inline TSphere<TYPE,DIMS>::TSphere(const POINT& p1, const POINT& p2, const POINT& p3) |
|
{ |
|
Set(p1, p2, p3); |
|
} // constructor |
|
/*----------------------------------------------------------------*/ |
|
|
|
|
|
template <typename TYPE, int DIMS> |
|
inline void TSphere<TYPE,DIMS>::Set(const POINT& c, TYPE r) |
|
{ |
|
center = c; |
|
radius = r; |
|
} |
|
template <typename TYPE, int DIMS> |
|
inline void TSphere<TYPE, DIMS>::Set(const POINT& p1, const POINT& p2, const POINT& p3) |
|
{ |
|
// compute relative distances |
|
TYPE A((p1 - p2).squaredNorm()); |
|
TYPE B((p2 - p3).squaredNorm()); |
|
TYPE C((p3 - p1).squaredNorm()); |
|
|
|
// re-orient triangle (make A longest side) |
|
const POINT *a(&p3), *b(&p1), *c(&p2); |
|
if (B < C) std::swap(B, C), std::swap(b, c); |
|
if (A < B) std::swap(A, B), std::swap(a, b); |
|
|
|
// if obtuse |
|
if (B + C <= A) { |
|
// just use longest diameter |
|
radius = SQRT(A) / TYPE(2); |
|
center = (*b + *c) / TYPE(2); |
|
} else { |
|
// otherwise circumscribe (http://en.wikipedia.org/wiki/Circumscribed_circle) |
|
const TYPE cos_a(SQUARE(B + C - A) / (B*C*TYPE(4))); |
|
radius = SQRT(A / ((TYPE(1) - cos_a)*TYPE(4))); |
|
const POINT alpha(*a - *c), beta(*b - *c); |
|
const POINT alphaXbeta(alpha.cross(beta)); |
|
center = (beta * alpha.squaredNorm() - alpha * beta.squaredNorm()).cross(alphaXbeta) / |
|
(alphaXbeta.squaredNorm() * TYPE(2)) + *c; |
|
} |
|
} |
|
/*----------------------------------------------------------------*/ |
|
|
|
|
|
template <typename TYPE, int DIMS> |
|
inline void TSphere<TYPE,DIMS>::Enlarge(TYPE x) |
|
{ |
|
radius += x; |
|
} |
|
template <typename TYPE, int DIMS> |
|
inline void TSphere<TYPE,DIMS>::EnlargePercent(TYPE x) |
|
{ |
|
radius *= x; |
|
} // Enlarge |
|
/*----------------------------------------------------------------*/ |
|
|
|
|
|
// Classify point to sphere. |
|
template <typename TYPE, int DIMS> |
|
inline GCLASS TSphere<TYPE, DIMS>::Classify(const POINT& p) const |
|
{ |
|
if ((center - p).squaredNorm() > SQUARE(radius)) |
|
return CULLED; |
|
return VISIBLE; |
|
} |
|
/*----------------------------------------------------------------*/
|
|
|