Skip to content
Snippets Groups Projects
Commit f7676595 authored by Vladimír Ulman's avatar Vladimír Ulman
Browse files

Added functions to determine point on a given surface.

GetClosestPointOnQuadricSurface() is the one.
parent f083143c
No related branches found
No related tags found
No related merge requests found
......@@ -513,3 +513,92 @@ int ActiveMesh::CalcQuadricSurface_Taubin(const int vertexID,
return 0;
}
bool ActiveMesh::GetPointOnQuadricSurface(const float x,const float y,
float &z1, float &z2,
const float (&coeffs)[10])
{
const float a=coeffs[9];
const float b=coeffs[3] +coeffs[5]*x +coeffs[6]*y;
const float c=coeffs[0] +coeffs[1]*x +coeffs[2]*y
+coeffs[4]*x*y +coeffs[7]*x*x +coeffs[8]*y*y;
const float sqArg=b*b - 4*a*c;
if (sqArg < 0.f) return false;
z1=(-b + sqrtf(sqArg)) / (2.f*a);
z2=(-b - sqrtf(sqArg)) / (2.f*a);
return true;
}
float ActiveMesh::GetClosestPointOnQuadricSurface(Vector3F& point,
const float (&coeffs)[10])
{
//backup original input coordinate
const float x=point.x;
const float y=point.y;
const float z=point.z;
float tmp1,tmp2;
//list of possible coordinates
std::vector<Vector3F> pointAdepts;
//took a pair of coordinates, calculate the third one
//and make it an adept...
if (GetPointOnQuadricSurface(x,y,tmp1,tmp2,coeffs))
{
pointAdepts.push_back(Vector3F(x,y,tmp1));
pointAdepts.push_back(Vector3F(x,y,tmp2));
}
if (GetPointOnQuadricSurface(x,z,tmp1,tmp2,coeffs))
{
pointAdepts.push_back(Vector3F(x,tmp1,z));
pointAdepts.push_back(Vector3F(x,tmp2,z));
}
if (GetPointOnQuadricSurface(y,z,tmp1,tmp2,coeffs))
{
pointAdepts.push_back(Vector3F(tmp1,y,z));
pointAdepts.push_back(Vector3F(tmp2,y,z));
}
//are we doomed?
if (pointAdepts.size() == 0)
return (-999999.f);
//find the closest
int closestIndex=ChooseClosestPoint(pointAdepts,point);
//calc distance to it
point-=pointAdepts[closestIndex];
tmp1=point.Len();
//adjust the input/output point
point=pointAdepts[closestIndex];
return (tmp1);
}
int ActiveMesh::ChooseClosestPoint(const std::vector<Vector3F>& points,
const Vector3F& point)
{
int minIndex=-1;
float minSqDist=9999999999999.f;
Vector3F p;
for (unsigned int i=0; i < points.size(); ++i)
{
p=point;
p-=points[i];
if (p.LenQ() < minSqDist)
{
minIndex=i;
minSqDist=p.LenQ();
}
}
return minIndex;
}
......@@ -33,15 +33,47 @@ class ActiveMesh
* Scalar product of \e coeffs and [1,x,y,z,xy,xz,yz,x^2,y^2,z^2] = 0.
* This also explains the order (and meaning) of the \e coeffs array.
* Order was adopted from [1], eq (2), page 3.
*
*
* The algorithm has been implemented according to
* the "instructions" [2], Appendix A, page 131.
*
* [1]: Dong-Ming Yan, Wenping Wang, Yang Liu, Zhouwang Yang.
* Variational mesh segmentation via quadric surface fitting.
* Elsevier: Computer-Aided Design 44 (2012), pp. 1072-1082.
*
* [2]: Hui Ma, Geometric Fitting of Quadratic Curves and Surfaces,
* Dissertation Thesis, Univ. Alabama, 2011.
*/
int CalcQuadricSurface_Taubin(const int vertexID,
float (&coeffs)[10]);
/**
* Calculate the 3rd coordinate (e.g., z) to complete a 3D point
* [x,y,z] given the other two coordinates (e.g., x and y).
* The point should lay on the quadric surface given with
* the coefficients \e coeffs.
*
* Returns false if such point could not be determined.
*
* Note that due to symmetries in the equations, one can use
* the very same function to obtain x given y,z, etc.
*
* Also note that two points are actually generated, one need
* to examine their distance to the point around which the surface
* has been calculated, and take the closer one.
*/
bool GetPointOnQuadricSurface(const float x,const float y,
float &z1, float &z2,
const float (&coeffs)[10]);
///Adjusts the input \e point to arrive at the surface given by its \e coeffs,
///the value of \e point is, therefore, changed.
float GetClosestPointOnQuadricSurface(Vector3F& point,
const float (&coeffs)[10]);
///returns index of the closest from \e points to the \e point
int ChooseClosestPoint(const std::vector<Vector3F>& points,
const Vector3F& point);
///input is filename
......@@ -54,7 +86,10 @@ class ActiveMesh
void CenterMesh(const Vector3F& newCentre);
void ScaleMesh(const Vector3F& scale);
void displayMesh(void); //defined in graphics.cpp
//the following functions are all defined in graphics.cpp
void displayMesh(void);
void displayVertexAndNeigs(void);
void displayQuadricSurface(void);
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment