void PointSet::GetCenteredPoint(int index, float* p) { Point4D relative = points[index] - center; p[0] = (float)(relative.GetPoint(0)/SCALE); p[1] = (float)(relative.GetPoint(1)/SCALE); p[2] = (float)(relative.GetPoint(2)/SCALE); return; }
void PointSet::AddPoint(Point4D& p) { if ( count==capacity ) MemAlloc(); points[count] = p; center = Point4D( (center.GetPoint(0)*count+p.GetPoint(0))/(count+1), (center.GetPoint(1)*count+p.GetPoint(1))/(count+1), (center.GetPoint(2)*count+p.GetPoint(2))/(count+1) ); count++; }
void PointSet::CreateDelaunayOnSphere(PointSet* ps, FaceSet* fs, double* progress, std::stringstream* myMsg) { double dummy = 0; if ( progress==NULL ) progress = &dummy; int p_num = ps->GetCount(); PointSet tmpPS; tmpPS.count = p_num; tmpPS.capacity = p_num*2+4; tmpPS.points = new Point4D [tmpPS.capacity]; const double OVERWRAP = 0.1; int* OverwrapID = new int [p_num*2]; memset( OverwrapID, -1, sizeof(int)*2*p_num ); double center[3]; // Estimate Center { double pntRange[] = { DBL_MAX, DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX, -DBL_MAX, }; for ( int i=0 ; i < p_num; i++ ) { Point4D pnt = ps->GetPoint4DAt(i); for ( int j=0; j < 3; j++ ) { pntRange[j+0] = ( pntRange[j+0]>pnt.GetPoint(j) ? pnt.GetPoint(j) : pntRange[j+0]); pntRange[j+3] = ( pntRange[j+3]<pnt.GetPoint(j) ? pnt.GetPoint(j) : pntRange[j+3]); } } for ( int j=0; j < 3; j++ ) { center[j] = ( pntRange[j+3]+pntRange[j+0] )/2; } } // Project onto Sphere { Point4D Center( center[0], center[1], center[2] ); for ( int i=0; i < p_num; i++ ) { double CntPnt[3]; (ps->GetPoint4DAt(i)-Center).GetPoint(CntPnt); double lng = atan(CntPnt[1]/CntPnt[2])+( CntPnt[2]>0 ? 0 : M_PI ) +M_PI/2; double lat = atan( CntPnt[0]/sqrt(CntPnt[1]*CntPnt[1]+CntPnt[2]*CntPnt[2]) ) +M_PI/2; OverwrapID[i] = i; tmpPS.points[i].SetPoint( lng, lat, lng*lng+lat*lat); if ( lng < OVERWRAP ) { OverwrapID[tmpPS.count] = i; tmpPS.points[tmpPS.count++].SetPoint( lng+2*M_PI, lat, (lng+2*M_PI)*(lng+2*M_PI)+lat*lat ); } } } // 外接4角形の作成 tmpPS.count += 4; tmpPS.points[tmpPS.count-4].SetPoint( 6*M_PI, 2*M_PI, M_PI*M_PI*40 ); tmpPS.points[tmpPS.count-3].SetPoint( 6*M_PI, -1*M_PI, M_PI*M_PI*37 ); tmpPS.points[tmpPS.count-2].SetPoint( -2*M_PI, -1*M_PI, M_PI*M_PI*5 ); tmpPS.points[tmpPS.count-1].SetPoint( -2*M_PI, 2*M_PI, M_PI*M_PI*8 ); FaceSet myFS; myFS.AddNewFace( tmpPS.count-2, tmpPS.count-3, tmpPS.count-4 ); myFS.AddNewFace( tmpPS.count-4, tmpPS.count-1, tmpPS.count-2 ); if ( !myFS.CheckDelaunay( &tmpPS ) ) { // AfxMessageBox("Invalid initial Delaunay.", MB_ICONERROR); // return; throw "Invalid initial Delaunay."; } myFS.MakeDelaunay( &tmpPS, progress, myMsg ); for ( int i=1; i <= 4; i++ ) { myFS.RemoveFaceV(tmpPS.count-i); } // IDの整理 { int f_num = myFS.GetFaceCount(), *f_list=NULL ; myFS.GetFaceIDList( &f_list, true ); for ( int i=0; i < f_num; i++ ) { myFS.RemoveFace(i); ASSERT(OverwrapID[f_list[i*3+0]]!=-1); ASSERT(OverwrapID[f_list[i*3+1]]!=-1); ASSERT(OverwrapID[f_list[i*3+2]]!=-1); myFS.AddNewFace( OverwrapID[f_list[i*3+0]], OverwrapID[f_list[i*3+1]], OverwrapID[f_list[i*3+2]] ); } delete [] f_list; } myFS.Unduplication(); delete [] OverwrapID; *fs = myFS; }