Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
// GLKNearestNeighbor.cpp: implementation of the GLKNearestNeighbor class.
//
//////////////////////////////////////////////////////////////////////
#include <math.h>
#include "GLKNearestNeighbor.h"
#define GLKNN_GRIDNUM 50.0f
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
GLKNearestNeighbor::GLKNearestNeighbor(int pntNum, float** pnts)
{
float xmin,ymin,zmin,xmax,ymax,zmax;
int i,j,k,m;
m_pntNum=0;
if (pntNum<=0) return;
m_pntNum=pntNum;
xmin=1.0e+10; ymin=1.0e+10; zmin=1.0e+10;
xmax=-1.0e+10; ymax=-1.0e+10; zmax=-1.0e+10;
for(i=0;i<pntNum;i++) {
if (pnts[i][0]>xmax) xmax=pnts[i][0];
if (pnts[i][1]>ymax) ymax=pnts[i][1];
if (pnts[i][2]>zmax) zmax=pnts[i][2];
if (pnts[i][0]<xmin) xmin=pnts[i][0];
if (pnts[i][1]<ymin) ymin=pnts[i][1];
if (pnts[i][2]<zmin) zmin=pnts[i][2];
}
m_size=(float)(pow((double)(((xmax-xmin)*(ymax-ymin)*(zmax-zmin))/(GLKNN_GRIDNUM*GLKNN_GRIDNUM*GLKNN_GRIDNUM)),(double)(1.0/3.0)));
m_xmin=xmin-m_size*0.5f;
m_ymin=ymin-m_size*0.5f;
m_zmin=zmin-m_size*0.5f;
m_xNum=(int)((xmax-m_xmin)/m_size)+1;
m_yNum=(int)((ymax-m_ymin)/m_size)+1;
m_zNum=(int)((zmax-m_zmin)/m_size)+1;
m_xmax=m_xmin+m_size*(float)m_xNum-m_size*0.001f;
m_ymax=m_ymin+m_size*(float)m_yNum-m_size*0.001f;
m_zmax=m_zmin+m_size*(float)m_zNum-m_size*0.001f;
m_grids=(GLKObList ****)new long[m_xNum];
for(i=0;i<m_xNum;i++) {
m_grids[i]=(GLKObList ***)new long[m_yNum];
for(j=0;j<m_yNum;j++) {
m_grids[i][j]=(GLKObList **)new long[m_zNum];
for(k=0;k<m_zNum;k++) {
m_grids[i][j][k]=new GLKObList;
m_grids[i][j][k]->RemoveAll();
}
}
}
m_nodeArray=(GLKNearestNeighborNode**)new long[pntNum];
for(m=0;m<pntNum;m++) {
GLKNearestNeighborNode *node;
node=new GLKNearestNeighborNode;
node->m_pos[0]=pnts[m][0];
node->m_pos[1]=pnts[m][1];
node->m_pos[2]=pnts[m][2];
node->m_index=m;
i=(int)((pnts[m][0]-m_xmin)/m_size);
j=(int)((pnts[m][1]-m_ymin)/m_size);
k=(int)((pnts[m][2]-m_zmin)/m_size);
node->m_PosInGLKObList=m_grids[i][j][k]->AddTail(node);
m_nodeArray[m]=node;
}
}
GLKNearestNeighbor::GLKNearestNeighbor(int pntNum, float* xpos, float *ypos, float *zpos)
{
float xmin,ymin,zmin,xmax,ymax,zmax;
int i,j,k,m;
m_pntNum=0;
if (pntNum<=0) return;
m_pntNum=pntNum;
xmin=1.0e+10; ymin=1.0e+10; zmin=1.0e+10;
xmax=-1.0e+10; ymax=-1.0e+10; zmax=-1.0e+10;
for(i=0;i<pntNum;i++) {
if (xpos[i]>xmax) xmax=xpos[i];
if (ypos[i]>ymax) ymax=ypos[i];
if (zpos[i]>zmax) zmax=zpos[i];
if (xpos[i]<xmin) xmin=xpos[i];
if (ypos[i]<ymin) ymin=ypos[i];
if (zpos[i]<zmin) zmin=zpos[i];
}
m_size=(float)(pow((double)(((xmax-xmin)*(ymax-ymin)*(zmax-zmin))/(GLKNN_GRIDNUM*GLKNN_GRIDNUM*GLKNN_GRIDNUM)),(double)(1.0/3.0)));
m_xmin=xmin-m_size*0.5f;
m_ymin=ymin-m_size*0.5f;
m_zmin=zmin-m_size*0.5f;
m_xNum=(int)((xmax-m_xmin)/m_size)+1;
m_yNum=(int)((ymax-m_ymin)/m_size)+1;
m_zNum=(int)((zmax-m_zmin)/m_size)+1;
m_xmax=m_xmin+m_size*(float)m_xNum-m_size*0.001f;
m_ymax=m_ymin+m_size*(float)m_yNum-m_size*0.001f;
m_zmax=m_zmin+m_size*(float)m_zNum-m_size*0.001f;
m_grids=(GLKObList ****)new long[m_xNum];
for(i=0;i<m_xNum;i++) {
m_grids[i]=(GLKObList ***)new long[m_yNum];
for(j=0;j<m_yNum;j++) {
m_grids[i][j]=(GLKObList **)new long[m_zNum];
for(k=0;k<m_zNum;k++) {
m_grids[i][j][k]=new GLKObList;
m_grids[i][j][k]->RemoveAll();
}
}
}
m_nodeArray=(GLKNearestNeighborNode**)new long[pntNum];
for(m=0;m<pntNum;m++) {
GLKNearestNeighborNode *node;
node=new GLKNearestNeighborNode;
node->m_pos[0]=xpos[m];
node->m_pos[1]=ypos[m];
node->m_pos[2]=zpos[m];
node->m_index=m;
i=(int)((xpos[m]-m_xmin)/m_size);
j=(int)((ypos[m]-m_ymin)/m_size);
k=(int)((zpos[m]-m_zmin)/m_size);
node->m_PosInGLKObList=m_grids[i][j][k]->AddTail(node);
m_nodeArray[m]=node;
}
}
GLKNearestNeighbor::~GLKNearestNeighbor()
{
int i,j,k;
if (m_pntNum>0) {
for(i=0;i<m_pntNum;i++) delete (GLKNearestNeighborNode*)(m_nodeArray[i]);
delete [](GLKNearestNeighborNode**)m_nodeArray;
}
for(i=0;i<m_xNum;i++) {
for(j=0;j<m_yNum;j++) {
for(k=0;k<m_zNum;k++) {
delete (m_grids[i][j][k]);
}
delete [](GLKObList **)(m_grids[i][j]);
}
delete [](GLKObList ***)(m_grids[i]);
}
delete [](GLKObList ****)(m_grids);
}
//////////////////////////////////////////////////////////////////////
// Implementation
//////////////////////////////////////////////////////////////////////
void GLKNearestNeighbor::MovePnt(int pntIndex, float xNewPos, float yNewPos, float zNewPos)
{
int i,j,k;
GLKNearestNeighborNode *node=m_nodeArray[pntIndex];
i=(int)((node->m_pos[0]-m_xmin)/m_size);
j=(int)((node->m_pos[1]-m_ymin)/m_size);
k=(int)((node->m_pos[2]-m_zmin)/m_size);
m_grids[i][j][k]->RemoveAt(node->m_PosInGLKObList);
if (xNewPos<m_xmin) xNewPos=m_xmin;
if (yNewPos<m_ymin) yNewPos=m_ymin;
if (zNewPos<m_zmin) zNewPos=m_zmin;
if (xNewPos>m_xmax) xNewPos=m_xmax;
if (yNewPos>m_ymax) yNewPos=m_ymax;
if (zNewPos>m_zmax) zNewPos=m_zmax;
node->m_pos[0]=xNewPos; node->m_pos[1]=yNewPos; node->m_pos[2]=zNewPos;
i=(int)((node->m_pos[0]-m_xmin)/m_size);
j=(int)((node->m_pos[1]-m_ymin)/m_size);
k=(int)((node->m_pos[2]-m_zmin)/m_size);
node->m_PosInGLKObList=m_grids[i][j][k]->AddTail(node);
}
void GLKNearestNeighbor::PntsInRange(float queryPnt[], float range, GLKArray* indexArray)
{
int i,j,k,ii,jj,kk,dd;
float ll;
GLKPOSITION Pos;
dd=(int)(range/m_size)+1;
ii=(int)((queryPnt[0]-m_xmin)/m_size);
jj=(int)((queryPnt[1]-m_ymin)/m_size);
kk=(int)((queryPnt[2]-m_zmin)/m_size);
range=range*range;
indexArray->RemoveAll();
for(i=ii-dd;i<=ii+dd;i++) {
if (i<0) continue;
if (i>=m_xNum) continue;
for(j=jj-dd;j<=jj+dd;j++) {
if (j<0) continue;
if (j>=m_yNum) continue;
for(k=kk-dd;k<=kk+dd;k++) {
if (k<0) continue;
if (k>=m_zNum) continue;
for(Pos=m_grids[i][j][k]->GetHeadPosition();Pos!=nullptr;) {
GLKNearestNeighborNode *node=(GLKNearestNeighborNode *)(m_grids[i][j][k]->GetNext(Pos));
ll=(node->m_pos[0]-queryPnt[0])*(node->m_pos[0]-queryPnt[0])
+(node->m_pos[1]-queryPnt[1])*(node->m_pos[1]-queryPnt[1])
+(node->m_pos[2]-queryPnt[2])*(node->m_pos[2]-queryPnt[2]);
if (ll<=range) indexArray->Add(node->m_index);
}
}
}
}
}
ac2468ac8This file is pinned to the selected release. Download the original to open it in your design tool.