예제 #1
0
int WangTiles::SimpleCompaction(const TileSet & tileSet,
                                vector< vector<Tile> > & result)
{
    const int numTiles = tileSet.NumTiles();

    const int numHColors = tileSet.NumHColors();
    const int numVColors = tileSet.NumVColors();
    const int numTilesPerColor = tileSet.NumTilesPerColor();
    
    // find the best aspect ratio
    const int maxFactor = floor(sqrt(numTiles));

    const int height = numVColors*numVColors;
    const int width = numHColors*numHColors*numTilesPerColor;

    {
        result = vector< vector<Tile> > (height);

        for(int i = 0; i < result.size(); i++)
        {
            result[i] = vector<Tile>(width);
        }
    }

    {
        int i = 0; int j = 0;
        for(int e1 = 0; e1 < numVColors; e1++)
            for(int e3 = 0; e3 < numVColors; e3++)
                for(int e0 = 0; e0 < numHColors; e0++)
                    for(int e2 = 0; e2 < numHColors; e2++)
                    {
                        const vector<Tile> & tiles = tileSet.Tiles(e0, e1, e2, e3);

                        for(int k = 0; k < tiles.size(); k++)
                        {
                            result[i][j] = tiles[k];

                            j++;

                            if(j >= result[i].size())
                            {
                                i++; j = 0;
                            }
                        }
                    }
    }
    
    // done 
    return 1;
}
예제 #2
0
int WangTiles::SequentialTiling(const TileSet & tileSet,
                                const int numRowTiles,
                                const int numColTiles,
                                vector< vector<Tile> > & result)
{
    {
        // null initialization
        if(result.size() != numRowTiles)
        {
            result = vector< vector<Tile> >(numRowTiles);
        }

        for(int i = 0; i < result.size(); i++)
        {
            if(result[i].size() != numColTiles)
            {
                result[i] = vector<Tile>(numColTiles);
            }
        }

        {
            Tile empty;
            for(int i = 0; i < numRowTiles; i++)
                for(int j = 0; j < numColTiles; j++)
                {
                    result[i][j] = empty;
                }
        }
    }

    {
        const int numHColors = tileSet.NumHColors();
        const int numVColors = tileSet.NumVColors();
        
        // add tiles
        for(int i = 0; i < numRowTiles; i++)
            for(int j = 0; j < numColTiles; j++)
            {
                // find out the color selection from neighbors
                int e0, e1, e2, e3;

                e0 = result[(i+numRowTiles-1)%numRowTiles][j].e2();
                e1 = result[i][(j+1)%numColTiles].e3();
                e2 = result[(i+1)%numRowTiles][j].e0();
                e3 = result[i][(j+numColTiles-1)%numColTiles].e1();
                
                if(e0 < 0) e0 = rand()%numHColors;
                if(e1 < 0) e1 = rand()%numVColors;
                if(e2 < 0) e2 = rand()%numHColors;
                if(e3 < 0) e3 = rand()%numVColors;

                const vector<Tile> & selections = tileSet.Tiles(e0, e1, e2, e3);

                if(selections.size() <= 0)
                {
                    return 0;
                }
                
                result[i][j] = selections[rand()%selections.size()];
            }
    }

    // done
    return 1;
}
예제 #3
0
int WangTiles::OrthogonalCornerCompaction(const TileSet & tileSet,
                                          vector< vector<Tile> > & result)
{
    const int numHColors = tileSet.NumHColors();
    const int numVColors = tileSet.NumVColors();
    const int numTilesPerColor = tileSet.NumTilesPerColor();
   
    // find the best aspect ratio
    int numTilesPerColorH = numTilesPerColor;
    int numTilesPerColorV = 1;
    while((numHColors*numHColors*numTilesPerColorH >
           numVColors*numVColors*numTilesPerColorV) &&
          (numTilesPerColorH%2 == 0))
    {
        numTilesPerColorH /= 2;
        numTilesPerColorV *= 2;
    }

    const int height = numVColors*numVColors*numTilesPerColorV;
    const int width = numHColors*numHColors*numTilesPerColorH;

    {
        // space allocation for the result
        result = vector< vector<Tile> > (height);

        for(int i = 0; i < result.size(); i++)
        {
            result[i] = vector<Tile>(width);
        }
    }

    {
        vector<int> travelHEdges, travelVEdges;
        if(! TravelEdges(0, numHColors-1, travelHEdges)) return 0;
        if(! TravelEdges(0, numVColors-1, travelVEdges)) return 0;

        // put the tiles
        for(int i = 0; i < height; i++)
            for(int j = 0; j < width; j++)
            {
                int whichVBlock = i/(numVColors*numVColors);
                int whichHBlock = j/(numHColors*numHColors);
                
                int ec = whichVBlock*numTilesPerColorH + whichHBlock;

                int hIndex0 = j%(numHColors*numHColors);
                int hIndex2 = hIndex0 + 1;
                int vIndex1 = i%(numVColors*numVColors);
                int vIndex3 = vIndex1 + 1;
                
                int e0 = travelHEdges[hIndex0];
                int e3 = travelVEdges[vIndex1];
                int e2 = travelHEdges[hIndex0];
                int e1 = travelVEdges[vIndex1];

                // assignment
                const vector<Tile> & tiles = tileSet.Tiles(e0, e1, e2, e3);

                if(tiles.size() <= ec)
                {
                    return 0;
                }
                
                result[i][j] = tiles[ec];
            }
    }
 
    // done
    return 1;
}
예제 #4
0
// algorithm:
// find the tiling for each center color (i.e. assuming numTilesPerColor is 1)
// and repeat the tiling for multiple numTilesPerColor
int WangTiles::EvenCompaction(const TileSet & tileSet,
                              vector< vector<Tile> > & result)
{
    //const int numTiles = tileSet.NumTiles();

    const int numHColors = tileSet.NumHColors();
    const int numVColors = tileSet.NumVColors();
    const int numTilesPerColor = tileSet.NumTilesPerColor();

    // error checking
    if((numHColors*numVColors*numTilesPerColor)%4)
    {
        // illegal input sizes
        return 0;
    }

    // find the best aspect ratio
    int numTilesPerColorH = numTilesPerColor/2;
    int numTilesPerColorV = 2;
    {
        int hFactor = 1;
        int vFactor = 1;
        int numTilesPerColorhv = numTilesPerColor;

        if(numHColors%2)
        {
            hFactor *= 2; numTilesPerColorhv /= 2;
        }

        if(numVColors%2)
        {
            vFactor *= 2; numTilesPerColorhv /= 2;
        }

        const int maxFactor = ceil(sqrt(numTilesPerColorhv));
        int factor = 1;

        for(int i = 1; i <= maxFactor; i++)
        {
            if((numTilesPerColorhv%i) == 0) factor = i;
        }

        if( (numVColors*numVColors*vFactor) <
            (numHColors*numHColors*hFactor) )
        {
            factor = numTilesPerColorhv/factor;
        }

        numTilesPerColorH = factor * hFactor;
        numTilesPerColorV = numTilesPerColorhv/factor * vFactor;
    }

    const int height = numVColors*numVColors*numTilesPerColorV;
    const int width = numHColors*numHColors*numTilesPerColorH;

    {
        // space allocation for the result
        result = vector< vector<Tile> > (height);

        for(int i = 0; i < result.size(); i++)
        {
            result[i] = vector<Tile>(width);
        }
    }

    {
        // put the tiles
        for(int i = 0; i < height; i++)
            for(int j = 0; j < width; j++)
            {
                int ec = i/(numVColors*numVColors)*numTilesPerColorH +
                    j/(numHColors*numHColors);

                int e0 = (j/numHColors)%numHColors;
                int e1 = (i/numVColors)%numVColors;
                int e2 = (j%numHColors);
                int e3 = (i%numVColors);

                if(j%2)
                {
                    // swap e1 and e3
                    int tmp = e1; e1 = e3; e3 = tmp;
                }

                if(i%2)
                {
                    // swap e0 and e2
                    int tmp = e0; e0 = e2; e2 = tmp;
                }
                
                // assignment
                const vector<Tile> & tiles = tileSet.Tiles(e0, e1, e2, e3);

                if(tiles.size() <= ec)
                {
                    return 0;
                }
                
                result[i][j] = tiles[ec];
            }
    }
    
    // done
    return 1;
}
예제 #5
0
int WangTiles::RandomCompaction(const TileSet & tileSet,
                                vector< vector<Tile> > & result)
{
    const int numHColors = tileSet.NumHColors();
    const int numVColors = tileSet.NumVColors();
    const int numTilesPerColor = tileSet.NumTilesPerColor();
   
    // find the best aspect ratio
    int numTilesPerColorH = numTilesPerColor;
    int numTilesPerColorV = 1;
    while((numVColors*numVColors*numTilesPerColorH >
           numHColors*numHColors*numTilesPerColorV) &&
          (numTilesPerColorH%2 == 0))
    {
        numTilesPerColorH /= 2;
        numTilesPerColorV *= 2;
    }

    const int height = numHColors*numHColors*numTilesPerColorV;
    const int width = numVColors*numVColors*numTilesPerColorH;

    {
        // space allocation for the result
        result = vector< vector<Tile> > (height);

        for(int i = 0; i < result.size(); i++)
        {
            result[i] = vector<Tile>(width);
        }
    }

    // do the random assignment
    {
        // build a random permutation
        deque<int> permutation(height*width);

        {
            for(int i = 0; i < permutation.size(); i++)
            {
                permutation[i] = i;
            }
        }

        deque<int> permutationNew;

        while(permutation.size() > 0)
        {
            const int select = rand()%permutation.size();
            permutationNew.push_back(permutation[select]);
            permutation[select] = permutation[permutation.size()-1];
            permutation.pop_back();
        }

        permutation = permutationNew;

        
        for(int e1 = 0; e1 < numVColors; e1++)
            for(int e3 = 0; e3 < numVColors; e3++)
                for(int e0 = 0; e0 < numHColors; e0++)
                    for(int e2 = 0; e2 < numHColors; e2++)
                    {
                        const vector<Tile> & tiles = tileSet.Tiles(e0, e1, e2, e3);
                        for(int k = 0; k < tiles.size(); k++)
                        {
                            const int whereToGo = permutation[0];
                            permutation.pop_front();

                            const int row = whereToGo/width;
                            const int col = whereToGo%width;

                            result[row][col] = tiles[k];
                        }
                    }
    }

    // done
    return 1;
}