// Copyright 2009 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package com.google.appengine.demos.mandelbrot; /** * {@code TileFactory} wraps a {@link FractalSource} of arbitrary size * and complexity and vends {@link PixelSource} objects that * correspond to tiles of the overall image. * * @author schwardo@google.com (Don Schwarz) * @author nickjohnson@google.com (Nick Johnson) */ public class TileFactory { /** * The size of each tile, expressed as a power of 2. For example, a * value of 6 corresponds to 2**6 x 2**6 tiles (or 64x64). This * should match the value of {@code Image.TileSize} in {@code * gigabrot.dzi}. */ private static final int TILEPOW = 8; /** * The number of pixels of overlap on each side of each tile. This * should match the value of {@code Image.Overlap} in the {@code * gigabrot.dzi}. */ private static final int OVERLAP = 1; /** * The {@link FractalSource} representing the overall image that is being tiled. */ private final FractalSource fractalSource; /** * Construct a {@link TileFactory} that vends tiles of {@link FractalSource}. */ public TileFactory(FractalSource fractalSource) { this.fractalSource = fractalSource; } /** * Constructs a {@link PixelSource} that provides the tile of {@code * fractalSource} at coordinates ({@code x} and {@code y}) of level * {@code level}. * * @param level The zoom level of the desired tile. * @param x The x coordinate of the desired tile, starting at 0 * (measured in numbers of tiles). * @param y The x coordinate of the desired tile, starting at 0 * (measured in numbers of tiles). */ public PixelSource createTile(int level, int x, int y) { int tile_level = level - TILEPOW; double xunits = FractalSource.XRANGE / ((double) (1 << tile_level)); double yunits = FractalSource.YRANGE / ((double) (1 << tile_level)); final double xscale = xunits / ((double) (1 << TILEPOW)); final double yscale = yunits / ((double) (1 << TILEPOW)); final double xmin = FractalSource.XMIN + xunits * x; final double ymin = FractalSource.YMIN + yunits * y; int sizelen = 1 << ((level > TILEPOW) ? TILEPOW : level); final int width = sizelen + 2 * OVERLAP; final int height = sizelen + 2 * OVERLAP; return new PixelSource() { public int getWidth() { return width; } public int getHeight() { return height; } public int getPixel(int x, int y) { return fractalSource.getValue(((double) x) * xscale + xmin, ((double) y) * yscale + ymin); } }; } }