|
cgma
|
#include <CubitPlane.hpp>
Public Member Functions | |
| CubitPlane () | |
| CubitPlane (const double A, const double B, const double C, const double D) | |
| CubitPlane (const CubitVector &Normal, const double D) | |
| CubitPlane (const CubitVector &Normal, const CubitVector &point) | |
| CubitPlane (DLIList< CubitVector > &positions) | |
| CubitPlane (const CubitPlane ©_from) | |
| CubitPlane (const CubitPlaneStruct &from) | |
| int | mk_plane_with_points (const CubitVector &vector1, const CubitVector &vector2, const CubitVector &vector3) |
| bool | fit_points (const std::vector< CubitVector > &positions) |
| const CubitVector & | normal () const |
| void | normal (const CubitVector &temp_normal) |
| double | coefficient () const |
| void | coefficient (const double temp_coeff) |
| void | set (const CubitVector &Normal, const CubitVector &point) |
| CubitVector | point_on_plane () const |
| double | distance (const CubitVector &vector) const |
| CubitVector | intersect (const CubitVector &base, const CubitVector &direction) const |
| int | intersect (const CubitPlane &other_plane, CubitVector &origin, CubitVector &vector) const |
| CubitVector | project (const CubitVector &point) const |
| void | reverse () |
| CubitPlane & | operator= (const CubitPlane &plane) |
| CubitPlane & | operator= (const CubitPlaneStruct &from) |
| operator CubitPlaneStruct () | |
Private Attributes | |
| CubitVector | normal_ |
| double | d_ |
Definition at line 22 of file CubitPlane.hpp.
Definition at line 26 of file CubitPlane.cpp.
| CubitPlane::CubitPlane | ( | const double | A, |
| const double | B, | ||
| const double | C, | ||
| const double | D | ||
| ) |
| CubitPlane::CubitPlane | ( | const CubitVector & | Normal, |
| const double | D | ||
| ) |
Definition at line 31 of file CubitPlane.cpp.
| CubitPlane::CubitPlane | ( | const CubitVector & | Normal, |
| const CubitVector & | point | ||
| ) |
| CubitPlane::CubitPlane | ( | DLIList< CubitVector > & | positions | ) |
Definition at line 61 of file CubitPlane.cpp.
{
// Newells method for determining approximate plane equation.
// Plane equation is of the form:
// 0 = plane_D +plane_normal.x()*X + plane_normal.y()*Y + plane_normal.z()*Z
if(positions.size() < 3)
throw std::invalid_argument("Must have 3 or more Points");
CubitVector vector_diff;
CubitVector vector_sum;
CubitVector ref_point = CubitVector (0.0, 0.0, 0.0);
CubitVector tmp_vector;
normal_ = CubitVector(0.0, 0.0, 0.0);
CubitVector vector1, vector2;
for (int i=positions.size(); i > 0; i--)
{
vector1 = positions.get_and_step();
vector2 = positions.get();
vector_diff = (vector2) - (vector1);
ref_point += (vector1);
vector_sum = (vector1) + (vector2);
tmp_vector.set(vector_diff.y() * vector_sum.z(),
vector_diff.z() * vector_sum.x(),
vector_diff.x() * vector_sum.y());
normal_ += tmp_vector;
}
double divisor = positions.size() * normal_.length();
// if (divisor < .000000001)
// {
// PRINT_ERROR("Colinear basis vector in CubitPlane constructor");
// }
d_ = (ref_point % normal_) / divisor;
normal_.normalize();
normal_ *= -1.0;
}
| CubitPlane::CubitPlane | ( | const CubitPlane & | copy_from | ) |
| CubitPlane::CubitPlane | ( | const CubitPlaneStruct & | from | ) | [inline] |
| double CubitPlane::coefficient | ( | ) | const [inline] |
Definition at line 128 of file CubitPlane.hpp.
{ return d_; }
| void CubitPlane::coefficient | ( | const double | temp_coeff | ) | [inline] |
Definition at line 129 of file CubitPlane.hpp.
{d_ = temp_coeff; }
| double CubitPlane::distance | ( | const CubitVector & | vector | ) | const |
Definition at line 258 of file CubitPlane.cpp.
| bool CubitPlane::fit_points | ( | const std::vector< CubitVector > & | positions | ) |
Definition at line 98 of file CubitPlane.cpp.
{
//- use the method of linear regression
//
// by creating an Ax=b system where:
//
// ___ ___
// | x[i]*x[i], x[i]*y[i], x[i] |
// A = sum_i | x[i]*y[i], y[i]*y[i], y[i] |
// | x[i], y[i], n |
// --- ---
// ___ ___
// | x[i]*z[i] |
// b = sum_i | y[i]*z[i] |
// | z[i]} |
// --- ---
// But this assumes that z is a linear function of x and y (i.e. z component
// of plane normal != 0.). We check the rank of A to catch this case. We
// handle this case, by transposing the x or y coordinates for the z,
// computing the normal, then transposing back (see itry below).
for ( int itry=0; itry < 3; itry++ )
{
CubitMatrix A(3,3);
std::vector<double> b(3);
A.set(2,2,positions.size());
for ( size_t ipt=0; ipt<positions.size(); ipt++ )
{
double x=0., y=0., z=0.;
if ( itry == 0 )
{
x = positions[ipt].x();
y = positions[ipt].y();
z = positions[ipt].z();
}
else if ( itry == 1 )
{
x = positions[ipt].x();
z = positions[ipt].y();
y = positions[ipt].z();
}
else if ( itry == 2 )
{
z = positions[ipt].x();
y = positions[ipt].y();
x = positions[ipt].z();
}
double sum_xx = x*x + A.get(0,0);
double sum_yy = y*y + A.get(1,1);
double sum_xy = x*y + A.get(1,0);
double sum_x = x + A.get(2,0);
double sum_y = y + A.get(2,1);
A.set(0,0,sum_xx);
A.set(1,1,sum_yy);
A.set(1,0,sum_xy); A.set(0,1,sum_xy);
A.set(2,0,sum_x); A.set(0,2,sum_x);
A.set(1,2,sum_y); A.set(2,1,sum_y);
b[0] += x*z;
b[1] += y*z;
b[2] += z;
}
// Make sure we have full rank. If not, it means:
// if itry==0, plane is parallel to z-axis.
// if itry==1, plane is parallel to z-axis & y-axis
// if itry==2, points are colinear
int rank = A.rank();
if ( rank == 3 )
{
std::vector<double> coef(3);
A.solveNxN( b, coef );
if ( itry == 0 )
normal_.set(coef[0], coef[1], -1);
else if ( itry == 1 )
normal_.set(coef[0], -1, coef[1]);
else if ( itry == 2 )
normal_.set(-1, coef[1], coef[0]);
normal_.normalize();
d_ = 0;
for ( size_t ipt=0; ipt<positions.size(); ipt++ )
{
d_ += normal_.x()*positions[ipt].x() +
normal_.y()*positions[ipt].y() +
normal_.z()*positions[ipt].z();
}
d_ /= positions.size();
return true;
}
}
d_ = 0.0;
normal_.set(0.,0.,0.);
return false;
}
| CubitVector CubitPlane::intersect | ( | const CubitVector & | base, |
| const CubitVector & | direction | ||
| ) | const |
Definition at line 263 of file CubitPlane.cpp.
| int CubitPlane::intersect | ( | const CubitPlane & | other_plane, |
| CubitVector & | origin, | ||
| CubitVector & | vector | ||
| ) | const |
Definition at line 270 of file CubitPlane.cpp.
{
// Code from Graphics Gems III, Georgiades
// Calculate the line of intersection between two planes.
// Initialize the unit direction vector of the line of intersection in
// xdir.
// Pick the point on the line of intersection on the coordinate plane most
// normal to xdir.
// Return TRUE if successful, FALSE otherwise (indicating that the planes
// don't intersect). The order in which the planes are given determines the
// choice of direction of xdir.
//
// int GetXLine(vect4 *pl1, vect4 *plane_2, vect3 *vector, vect3 *xpt)
double invdet; // inverse of 2x2 matrix determinant
vector = normal() * plane_2.normal();
CubitVector dir2(vector.x()*vector.x(),
vector.y()*vector.y(),
vector.z()*vector.z());
CubitVector plane1n = normal();
CubitVector plane2n = plane_2.normal();
if (dir2.z() > dir2.y() && dir2.z() > dir2.x() && dir2.z() > CUBIT_RESABS)
{
// then get a point on the XY plane
invdet = 1.0 / vector.z();
//solve < pl1.x * origin.x + pl1.y * origin.y = - pl1.w >
// < plane2n.x * origin.x + plane2n.y * origin.y = - plane2n.w >
origin.set(plane1n.y() * plane_2.coefficient() -
plane2n.y() * coefficient(),
plane2n.x() * coefficient() -
plane1n.x() * plane_2.coefficient(),
0.0);
}
else if (dir2.y() > dir2.x() && dir2.y() > CUBIT_RESABS)
{
// then get a point on the XZ plane
invdet = -1.0 / vector.y();
// solve < pl1.x * origin.x + pl1.z * origin.z = -pl1.w >
// < plane2n.x * origin.x + plane2n.z * origin.z = -plane2n.w >
origin.set(plane1n.z() * plane_2.coefficient() -
plane2n.z() * coefficient(),
0.0,
plane2n.x() * coefficient() -
plane1n.x() * plane_2.coefficient());
}
else if (dir2.x() > CUBIT_RESABS)
{
// then get a point on the YZ plane
invdet = 1.0 / vector.x();
// solve < pl1.y * origin.y + pl1.z * origin.z = - pl1.w >
// < plane2n.y * origin.y + plane2n.z * origin.z = - plane2n.w >
origin.set(0.0,
plane1n.z() * plane_2.coefficient() -
plane2n.z() * coefficient(),
plane2n.y() * coefficient() -
plane1n.y() * plane_2.coefficient());
}
else // vector is zero, then no point of intersection exists
return CUBIT_FALSE;
origin *= invdet;
invdet = 1.0 / (float)sqrt(dir2.x() + dir2.y() + dir2.z());
vector *= invdet;
return CUBIT_TRUE;
}
| int CubitPlane::mk_plane_with_points | ( | const CubitVector & | vector1, |
| const CubitVector & | vector2, | ||
| const CubitVector & | vector3 | ||
| ) |
Definition at line 198 of file CubitPlane.cpp.
{
// First check to make sure that the points are not collinear
// Vector going from Vertex 0 to Vertex 1
CubitVector vector01 = V1 - V0;
vector01.normalize();
// Vector going from Vertex 0 to Vertex 2
CubitVector vector02 = V2 - V0;
vector02.normalize();
// If the 3 points are collinear, then the cross product of these two
// vectors will yield a null vector (one whose length is zero).
normal_ = vector01 * vector02;
if(normal_.length() <= CUBIT_RESABS)
{
PRINT_ERROR("Points are collinear.\n"
" Cannot create a CubitPlane object.\n");
d_ = 0.0;
return CUBIT_FAILURE;
}
normal_.normalize();
double D0 = -(normal_ % V0);
double D1 = -(normal_ % V1);
double D2 = -(normal_ % V2);
d_ = (D0 + D1 + D2) / 3.0;
return CUBIT_SUCCESS;
}
| const CubitVector & CubitPlane::normal | ( | ) | const [inline] |
Definition at line 123 of file CubitPlane.hpp.
{ return normal_; }
| void CubitPlane::normal | ( | const CubitVector & | temp_normal | ) | [inline] |
Definition at line 125 of file CubitPlane.hpp.
{normal_ = temp_normal;}
| CubitPlane::operator CubitPlaneStruct | ( | ) | [inline] |
Definition at line 108 of file CubitPlane.hpp.
{
CubitPlaneStruct to;
to.normal_ = normal_;
to.d_ = d_;
return to;
}
| CubitPlane & CubitPlane::operator= | ( | const CubitPlane & | plane | ) |
| CubitPlane& CubitPlane::operator= | ( | const CubitPlaneStruct & | from | ) |
| CubitVector CubitPlane::point_on_plane | ( | ) | const |
Definition at line 234 of file CubitPlane.cpp.
{
if ( fabs( normal_.x() ) > CUBIT_RESABS )
return CubitVector(-d_ / normal_.x(), 0, 0);
else if ( fabs( normal_.y() ) > CUBIT_RESABS )
return CubitVector(0, -d_ / normal_.y(), 0);
else if ( fabs( normal_.z() ) > CUBIT_RESABS )
return CubitVector(0, 0, -d_ / normal_.z());
// If A B and C are all zero, the plane is invalid,
// Just return <0,0,0>
return CubitVector(0,0,0);
}
| CubitVector CubitPlane::project | ( | const CubitVector & | point | ) | const |
Definition at line 340 of file CubitPlane.cpp.
| void CubitPlane::reverse | ( | ) | [inline] |
| void CubitPlane::set | ( | const CubitVector & | Normal, |
| const CubitVector & | point | ||
| ) |
double CubitPlane::d_ [private] |
Definition at line 119 of file CubitPlane.hpp.
CubitVector CubitPlane::normal_ [private] |
Definition at line 118 of file CubitPlane.hpp.