📄 sparsegrid3d.java
字号:
} } } else // not toroidal { // compute xmin and xmax for the neighborhood such that they are within boundaries final int xmin = ((x-dist>=0)?x-dist:0); final int xmax =((x+dist<=width-1)?x+dist:width-1); // compute ymin and ymax for the neighborhood such that they are within boundaries final int ymin = ((y-dist>=0)?y-dist:0); final int ymax = ((y+dist<=height-1)?y+dist:height-1); final int zmin = ((z-dist>=0)?z-dist:0); final int zmax = ((z+dist<=length-1)?z+dist:length-1); for( int x0 = xmin ; x0 <= xmax ; x0++ ) { for( int y0 = ymin ; y0 <= ymax ; y0++ ) { for( int z0 = zmin ; z0 <= zmax ; z0++ ) { if( x0 != x || y0 != y || z0 != z ) { xPos.add( x0 ); yPos.add( y0 ); zPos.add( z0 ); } } } } } } public void getNeighborsHamiltonianDistance( final int x, final int y, final int z, final int dist, final boolean toroidal, IntBag xPos, IntBag yPos, IntBag zPos ) { // won't work for negative distances if( dist < 0 ) { throw new RuntimeException( "Runtime exception in method getNeighborsHamiltonianDistance: Distance must be positive" ); } if( xPos == null || yPos == null || zPos == null ) { throw new RuntimeException( "Runtime exception in method getNeighborsHamiltonianDistance: xPos and yPos should not be null" ); } xPos.clear(); yPos.clear(); zPos.clear(); // for toroidal environments the code will be different because of wrapping arround if( toroidal ) { // compute xmin and xmax for the neighborhood final int xmax = x+dist; final int xmin = x-dist; for( int x0 = xmin; x0 <= xmax ; x0++ ) { final int x_0 = stx(x0); // compute ymin and ymax for the neighborhood; they depend on the curreny x0 value final int ymax = y+(dist-((x0-x>=0)?x0-x:x-x0)); final int ymin = y-(dist-((x0-x>=0)?x0-x:x-x0)); for( int y0 = ymin; y0 <= ymax; y0++ ) { final int y_0 = sty(y0); final int zmax = z+(dist-((x0-x>=0)?x0-x:x-x0)-((y0-y>=0)?y0-y:y-y0)); final int zmin = z-(dist-((x0-x>=0)?x0-x:x-x0)-((y0-y>=0)?y0-y:y-y0)); for( int z0 = zmin; z0 <= zmax; z0++ ) { final int z_0 = stz(z0); if( x_0 != x || y_0 != y || z_0 != z ) { xPos.add( x_0 ); yPos.add( y_0 ); zPos.add( z_0 ); } } } } } else // not toroidal { // compute xmin and xmax for the neighborhood such that they are within boundaries final int xmax = ((x+dist<=width-1)?x+dist:width-1); final int xmin = ((x-dist>=0)?x-dist:0); for( int x0 = xmin ; x0 <= xmax ; x0++ ) { final int x_0 = x0; // compute ymin and ymax for the neighborhood such that they are within boundaries // they depend on the curreny x0 value final int ymax = ((y+(dist-((x0-x>=0)?x0-x:x-x0))<=height-1)?y+(dist-((x0-x>=0)?x0-x:x-x0)):height-1); final int ymin = ((y-(dist-((x0-x>=0)?x0-x:x-x0))>=0)?y-(dist-((x0-x>=0)?x0-x:x-x0)):0); for( int y0 = ymin; y0 <= ymax; y0++ ) { final int y_0 = y0; final int zmin = ((z-(dist-((x0-x>=0)?x0-x:x-x0)-((y0-y>=0)?y0-y:y-y0))>=0)?z-(dist-((x0-x>=0)?x0-x:x-x0)-((y0-y>=0)?y0-y:y-y0)):0); final int zmax = ((z+(dist-((x0-x>=0)?x0-x:x-x0)-((y0-y>=0)?y0-y:y-y0))<=length-1)?z+(dist-((x0-x>=0)?x0-x:x-x0)-((y0-y>=0)?y0-y:y-y0)):length-1) ; for( int z0 = zmin; z0 <= zmax; z0++ ) { final int z_0 = z0; if( x_0 != x || y_0 != y || z_0 != z ) { xPos.add( x_0 ); yPos.add( y_0 ); zPos.add( z_0 ); } } } } } } /** * Gets all neighbors of a location that satisfy max( abs(x-X) , abs(y-Y), abs(z-Z) ) <= dist. This region forms a * cube 2*dist+1 cells across, centered at (X,Y,Z). If dist==1, this * is equivalent to the twenty-six neighbors surrounding (X,Y,Z), plus (X,Y) itself. * Places each x, y, and z value of these locations in the provided IntBags xPos, yPos, and zPos, clearing the bags first. * Then places into the result Bag the objects at each of those <x,y,z> locations clearning it first. * Returns the result Bag (constructing one if null had been passed in). * null may be passed in for the various bags, though it is more efficient to pass in a 'scratch bag' for * each one. */ public Bag getNeighborsMaxDistance( final int x, final int y, final int z, final int dist, final boolean toroidal, Bag result, IntBag xPos, IntBag yPos, IntBag zPos ) { if( xPos == null ) xPos = new IntBag(); if( yPos == null ) yPos = new IntBag(); if( zPos == null ) zPos = new IntBag(); getNeighborsMaxDistance( x, y, z, dist, toroidal, xPos, yPos, zPos ); return getObjectsAtLocations(xPos,yPos,zPos,result); } /** * Gets all neighbors of a location that satisfy abs(x-X) + abs(y-Y) + abs(z-Z) <= dist. This region * forms an <a href="http://images.google.com/images?q=octahedron">octohedron</a> 2*dist+1 cells from point * to opposite point inclusive, centered at (X,Y,Y). If dist==1 this is * equivalent to the six neighbors above, below, left, and right, front, and behind (X,Y,Z)), * plus (X,Y,Z) itself. * Places each x, y, and z value of these locations in the provided IntBags xPos, yPos, and zPos, clearing the bags first. * Then places into the result Bag the objects at each of those <x,y,z> locations clearning it first. * Returns the result Bag (constructing one if null had been passed in). * null may be passed in for the various bags, though it is more efficient to pass in a 'scratch bag' for * each one. */ public Bag getNeighborsHamiltonianDistance( final int x, final int y, final int z, final int dist, final boolean toroidal, Bag result, IntBag xPos, IntBag yPos, IntBag zPos ) { if( xPos == null ) xPos = new IntBag(); if( yPos == null ) yPos = new IntBag(); if( zPos == null ) zPos = new IntBag(); getNeighborsHamiltonianDistance( x, y, z, dist, toroidal, xPos, yPos, zPos ); return getObjectsAtLocations(xPos,yPos,zPos,result); } /** For each <xPos,yPos,zPos> location, puts all such objects into the result bag. Returns the result bag. If the provided result bag is null, one will be created and returned. */ public Bag getObjectsAtLocations(final IntBag xPos, final IntBag yPos, final IntBag zPos, Bag result) { if (result==null) result = new Bag(); else result.clear(); final int len = xPos.numObjs; final int[] xs = xPos.objs; final int[] ys = yPos.objs; final int[] zs = zPos.objs; for(int i=0; i < len; i++) { // a little efficiency: add if we're 1, addAll if we're > 1, // do nothing if we're 0 Bag temp = getObjectsAtLocation(xs[i],ys[i],zs[i]); if (temp!=null) { int n = temp.numObjs; if (n==1) result.add(temp.objs[0]); else if (n > 1) result.addAll(temp); } } return result; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -