TiledPatternCoordinateConverter.java

00001 package edu.stanford.hci.r3.pattern.coordinates.conversion;
00002 
00003 import edu.stanford.hci.r3.pattern.TiledPattern;
00004 import edu.stanford.hci.r3.units.PatternDots;
00005 import edu.stanford.hci.r3.units.Percentage;
00006 import edu.stanford.hci.r3.units.coordinates.PercentageCoordinates;
00007 import edu.stanford.hci.r3.units.coordinates.StreamedPatternCoordinates;
00008 import edu.stanford.hci.r3.util.DebugUtils;
00009 
00021 public class TiledPatternCoordinateConverter implements PatternCoordinateConverter {
00022 
00023         private int bottomMostVoidSpaceInDots;
00024 
00028         private int dotsPerTileHorizontal;
00029 
00033         private int dotsPerTileVertical;
00034 
00048         private double maxX;
00049 
00053         private double maxY;
00054 
00058         private double numDotsHorizontalBetweenTiles;
00059 
00063         private double numDotsVerticalBetweenTiles;
00064 
00068         private int numTiles;
00069 
00078         private int numTilesAcross;
00079 
00083         private int numTilesDown;
00084 
00088         private double numTotalDotsAcross;
00089 
00093         private PatternDots numTotalDotsAcrossObj;
00094 
00098         private double numTotalDotsDown;
00099 
00103         private PatternDots numTotalDotsDownObj;
00104 
00108         private double originX;
00109 
00113         private double originY;
00114 
00118         private String regionName;
00119 
00123         private int rightMostVoidSpaceInDots;
00124 
00128         private int startingTile;
00129 
00133         private double tileHeightIncludingPadding;
00134 
00138         private double tileWidthIncludingPadding;
00139 
00149         public TiledPatternCoordinateConverter(String regionName) {
00150                 this(regionName, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
00151         }
00152 
00156         public TiledPatternCoordinateConverter(String theRegionName, //
00157                         double leftMostPatternXCoord, double topMostPatternYCoord, int dotsAcross, int dotsDown) {
00158                 setRegionName(theRegionName);
00159                 setStartingTile(0);
00160                 setTileConfiguration(1, 1);
00161                 setTileSizeInDots(dotsAcross, dotsDown);
00162                 setOriginInDots(leftMostPatternXCoord, topMostPatternYCoord);
00163                 setTotalSizeInDots(dotsAcross, dotsDown);
00164                 setTileToTileOffsetInDots(0, 0);
00165         }
00166 
00205         public TiledPatternCoordinateConverter(String theRegionName, int startTile, int nTilesAcross,
00206                         int nTilesDown, int dotsPerTileHoriz, int dotsPerTileVert,
00207                         double numHorizDotsBetweenTiles, double numVertDotsBetweenTiles,
00208                         double leftMostPatternX, double topMostPatternY, double numDotsAcross,
00209                         double numDotsDown) {
00210                 setRegionName(theRegionName);
00211                 setStartingTile(startTile);
00212                 setTileConfiguration(nTilesAcross, nTilesDown);
00213                 setTileSizeInDots(dotsPerTileHoriz, dotsPerTileVert);
00214                 setOriginInDots(leftMostPatternX, topMostPatternY);
00215                 setTotalSizeInDots(numDotsAcross, numDotsDown);
00216                 setTileToTileOffsetInDots(numHorizDotsBetweenTiles, numVertDotsBetweenTiles);
00217         }
00218 
00234         private void calculateCachedDimensions() {
00235 
00236                 // set the maxX and tileHeight
00237                 if (numTilesAcross == 1) {
00238                         tileWidthIncludingPadding = numTotalDotsAcross;
00239                         maxX = originX + numTotalDotsAcross;
00240                 } else if (numDotsHorizontalBetweenTiles < dotsPerTileHorizontal) { // dX = 0
00241                         tileWidthIncludingPadding = dotsPerTileHorizontal;
00242                         maxX = originX + dotsPerTileHorizontal - rightMostVoidSpaceInDots; // only one
00243                         // horizontal
00244                         // tile
00245                 } else { // bigger than the width
00246                         tileWidthIncludingPadding = numDotsHorizontalBetweenTiles;
00247                         maxX = originX + numDotsHorizontalBetweenTiles * numTiles - rightMostVoidSpaceInDots;
00248                 }
00249 
00250                 // set the maxY and tileHeight
00251                 if (numTilesDown == 1) {
00252                         tileHeightIncludingPadding = numTotalDotsDown;
00253                         maxY = originY + numTotalDotsDown;
00254                 } else if (numDotsVerticalBetweenTiles < dotsPerTileVertical) { // dY = 0
00255                         // only one vertical tile, like bnet's pattern
00256                         tileHeightIncludingPadding = dotsPerTileVertical;
00257                         maxY = originY + dotsPerTileVertical - bottomMostVoidSpaceInDots;
00258                 } else { // bigger than the height
00259                         tileHeightIncludingPadding = numDotsVerticalBetweenTiles;
00260                         maxY = originY + numDotsVerticalBetweenTiles * numTiles - bottomMostVoidSpaceInDots;
00261                 }
00262 
00263                 // DebugUtils.println(regionName);
00264                 // DebugUtils.println("Void Space in X: " + rightMostVoidSpaceInDots);
00265                 // DebugUtils.println("Void Space in Y: " + bottomMostVoidSpaceInDots);
00266         }
00267 
00285         public boolean contains(final double xValPatternDots, final double yValPatternDots) {
00286                 // has to be to the right of the leftmost border
00287                 final boolean insideLeftBoundary = xValPatternDots >= originX;
00288 
00289                 // has to be below the top border
00290                 final boolean insideTopBoundary = yValPatternDots >= originY;
00291 
00292                 // has to be to the left of the rightmost border
00293                 final boolean insideRightBoundary = xValPatternDots < maxX;
00294 
00295                 // has to be above the bottom border
00296                 final boolean insideBottomBoundary = yValPatternDots < maxY;
00297 
00298                 // has to NOT fall in between the gaps between pages...
00299                 final boolean notInHorizontalGap = ((xValPatternDots - originX) % tileWidthIncludingPadding) < dotsPerTileHorizontal;
00300                 final boolean notInVerticalGap = ((yValPatternDots - originY) % tileHeightIncludingPadding) < dotsPerTileVertical;
00301 
00302                 return insideLeftBoundary && insideTopBoundary && insideRightBoundary
00303                                 && insideBottomBoundary && notInHorizontalGap && notInVerticalGap;
00304         }
00305 
00313         public boolean contains(StreamedPatternCoordinates location) {
00314                 final double xTestVal = location.getXVal();
00315                 final double yTestVal = location.getYVal();
00316 
00317                 return contains(xTestVal, yTestVal);
00318         }
00319 
00320         /*
00321          * (non-Javadoc)
00322          * 
00323          * @see edu.stanford.hci.r3.pattern.coordinates.conversion.PatternCoordinateConverter#getArea()
00324          */
00325         @Override
00326         public double getArea() {
00327                 return numTotalDotsAcross * numTotalDotsDown;
00328         }
00329 
00333         public String getRegionName() {
00334                 return regionName;
00335         }
00336 
00343         public PercentageCoordinates getRelativeLocation(StreamedPatternCoordinates coord) {
00344 
00345                 final double xOffset = coord.getXVal() - originX;
00346                 final double yOffset = coord.getYVal() - originY;
00347 
00348                 final double xRelativeToTile = xOffset
00349                                 - (getTileNumHorizontal(coord) * numDotsHorizontalBetweenTiles);
00350                 final double yRelativeToTile = yOffset
00351                                 - (getTileNumVertical(coord) * numDotsVerticalBetweenTiles);
00352 
00353                 final int tileOffset = getTileNumber(coord) - startingTile;
00354 
00355                 final int tileRow = tileOffset / numTilesAcross;
00356                 final int tileCol = tileOffset % numTilesAcross;
00357 
00358                 // how many dots are we in x & y
00359                 final double totalDotsX = tileCol * dotsPerTileHorizontal + xRelativeToTile;
00360                 final double totalDotsY = tileRow * dotsPerTileVertical + yRelativeToTile;
00361 
00362                 final double pctX = totalDotsX / numTotalDotsAcross * 100;
00363                 final double pctY = totalDotsY / numTotalDotsDown * 100;
00364 
00365                 return new PercentageCoordinates( // 
00366                                 new Percentage(pctX, numTotalDotsAcrossObj), // fraction of width
00367                                 new Percentage(pctY, numTotalDotsDownObj)); // fraction of height
00368         }
00369 
00384         public int getTileNumber(StreamedPatternCoordinates coord) {
00385                 if (!contains(coord)) {
00386                         return -1;
00387                 }
00388 
00389                 // using the x or y coordinate, determine the tile number
00390                 // depending on the orientation of the pattern, these numbers may not be the same (i.e., one
00391                 // of them may be zero while the other is not)
00392                 final int tileNumHoriz = getTileNumHorizontal(coord);
00393                 final int tileNumVert = getTileNumVertical(coord);
00394 
00395                 return startingTile + Math.max(tileNumHoriz, tileNumVert);
00396         }
00397 
00402         private int getTileNumHorizontal(StreamedPatternCoordinates coord) {
00403                 return (int) Math.floor((coord.getXVal() - originX) / tileWidthIncludingPadding);
00404         }
00405 
00410         private int getTileNumVertical(StreamedPatternCoordinates coord) {
00411                 return (int) Math.floor((coord.getYVal() - originY) / tileHeightIncludingPadding);
00412         }
00413 
00417         private void setNumDotsFromBottomMostTilesThatAreNotIncluded(int numDots) {
00418                 bottomMostVoidSpaceInDots = numDots;
00419                 calculateCachedDimensions();
00420         }
00421 
00425         private void setNumDotsFromRightMostTilesThatAreNotIncluded(int numDots) {
00426                 rightMostVoidSpaceInDots = numDots;
00427                 calculateCachedDimensions();
00428         }
00429 
00436         public void setOriginInDots(double leftMostPatternX, double topMostPatternY) {
00437                 originX = leftMostPatternX;
00438                 originY = topMostPatternY;
00439 
00440                 // must update some internal state
00441                 calculateCachedDimensions();
00442         }
00443 
00450         public void setPatternInformationByReadingItFrom(TiledPattern p) {
00451                 final int voidX = p.getNumDotsXPerFullTile() - p.getNumDotsXFromRightMostTiles();
00452                 final int voidY = p.getNumDotsYPerFullTile() - p.getNumDotsYFromBottomMostTiles();
00453 
00454                 setNumDotsFromRightMostTilesThatAreNotIncluded(voidX);
00455                 setNumDotsFromBottomMostTilesThatAreNotIncluded(voidY);
00456 
00457                 setOriginInDots(p.getOriginXInDots(), p.getOriginYInDots());
00458                 setStartingTile(p.getInitialPatternFileNumber());
00459                 setTileConfiguration(p.getNumTilesX(), p.getNumTilesY());
00460                 setTileSizeInDots(p.getNumDotsXPerFullTile(), p.getNumDotsYPerFullTile());
00461                 setTileToTileOffsetInDots(p.getNumHorizDotsBetweenTiles(), p.getNumVertDotsBetweenTiles());
00462                 setTotalSizeInDots(p.getNumTotalColumns(), p.getNumTotalRows());
00463 
00464                 DebugUtils.println("");
00465                 System.out.println("=========================");
00466                 System.out.println(p);
00467                 System.out.println(this);
00468                 System.out.println("=========================");
00469 
00470         }
00471 
00477         public void setRegionName(String rName) {
00478                 regionName = rName;
00479         }
00480 
00489         public void setStartingTile(int startTile) {
00490                 startingTile = startTile;
00491         }
00492 
00501         public void setTileConfiguration(int nTilesAcross, int nTilesDown) {
00502                 numTilesAcross = nTilesAcross;
00503                 numTilesDown = nTilesDown;
00504                 numTiles = numTilesAcross * numTilesDown;
00505         }
00506 
00514         public void setTileSizeInDots(int dotsPerTileHoriz, int dotsPerTileVert) {
00515                 dotsPerTileHorizontal = dotsPerTileHoriz;
00516                 dotsPerTileVertical = dotsPerTileVert;
00517 
00518                 // must update some internal state
00519                 calculateCachedDimensions();
00520         }
00521 
00526         public void setTileToTileOffsetInDots(double numHorizDotsBetweenTiles,
00527                         double numVertDotsBetweenTiles) {
00528                 // what is the x offset between the origins of two adjacent tiles?
00529                 // this is the width of a tile, plus a padding that anoto creates when you use the FDK to
00530                 // generate pattern
00531                 numDotsHorizontalBetweenTiles = numHorizDotsBetweenTiles;
00532                 // what is the y offset between the origins of two adjacent tiles?
00533                 // note that in the BNet pattern space, the y offset is 0
00534                 numDotsVerticalBetweenTiles = numVertDotsBetweenTiles;
00535 
00536                 // must update some internal state
00537                 calculateCachedDimensions();
00538         }
00539 
00547         public void setTotalSizeInDots(double numDotsAcross, double numDotsDown) {
00548                 // how wide and tall is the whole region?
00549                 numTotalDotsAcross = numDotsAcross;
00550                 numTotalDotsDown = numDotsDown;
00551 
00552                 // save this for later calculations
00553                 numTotalDotsAcrossObj = new PatternDots(numTotalDotsAcross);
00554                 numTotalDotsDownObj = new PatternDots(numTotalDotsDown);
00555 
00556                 calculateCachedDimensions();
00557         }
00558 
00562         public String toString() {
00563                 return "TiledPatternCoordinateConverter {" + "x=" + originX + ", y=" + originY + " w="
00564                                 + numTotalDotsAcrossObj + ", h=" + numTotalDotsDownObj + "}";
00565         }
00566 }

Generated on Sat Apr 14 18:21:39 2007 for R3 Paper Toolkit by  doxygen 1.4.7