Package rakama.worldtools.examples.mandel

Source Code of rakama.worldtools.examples.mandel.Mandelbrot

/*
* Copyright (c) 2012, RamsesA <ramsesakama@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/

package rakama.worldtools.examples.mandel;

import java.io.File;
import java.io.IOException;

import rakama.worldtools.WorldManager;
import rakama.worldtools.canvas.BlockCanvas;
import rakama.worldtools.data.Block;


public class Mandelbrot
{
    static String directory = "C:/Users/My Computer/AppData/Roaming/.minecraft/saves/mandelbrot";
   
    public static void main(String[] args) throws IOException
    {
        WorldManager manager = WorldManager.getWorldManager(new File(directory));
        BlockCanvas canvas = manager.getCanvas();
        renderMandelbrot(canvas, 512, 128, 4);
        manager.closeAll();
    }
       
    public static void renderMandelbrot(BlockCanvas canvas, int size, int maxY, int samples)
    {
        int xStart = -size / 2;
        int zStart = -size / 2;
        int xEnd = xStart + size;
        int zEnd = zStart + size;

        double xScale = 4.0 / size;
        double zScale = 4.0 / size;
        double xCenter = 0.5 + xScale * (xStart + xEnd) / 2.0;
        double zCenter = zScale * (zStart + zEnd) / 2.0;
       
        for(int x=xStart; x<xEnd; x++)
        {
            for(int z=zStart; z<zEnd; z++)
            {
                double x0 = x*xScale - xCenter;
                double z0 = z*zScale - zCenter;
               
                double value = getMultisample(x0, z0, xScale, zScale, samples);
                int height = (int)(value * maxY);   
               
                renderColumn(canvas, x, z, height, maxY);
            }
        }
    }
   
    public static void renderColumn(BlockCanvas canvas, int x, int z, int height, int maxY)
    {
        Block block = getBlock(height, maxY);       
        canvas.setBlock(x, height, z, block);

        Block fill = getFill(block)
        for(int y=0; y<height; y++)
            canvas.setBlock(x, y, z, fill);
       
        double waterLevel = getWaterLevel(maxY);       
        for(int y=height; y<waterLevel; y++)
            canvas.setBlock(x, y, z, Block.WATER);
       
        canvas.setBlock(x, 0, z, Block.BEDROCK);
    }
   
    public static Block getBlock(int y, int maxY)
    {
        if(y >= maxY)
            return Block.OBSIDIAN;
        else if(y > 0.9 * maxY)
            return Block.SNOW;
        else if(y > 0.65 * maxY)
            return Block.STONE;
        else if(y > 0.45 * maxY)
            return Block.GRASS;
        else
            return Block.SAND;
    }
   
    public static Block getFill(Block block)
    {
        if(block.equals(Block.GRASS))
            return Block.DIRT;
        else
            return block;
    }
   
    public static double getWaterLevel(int maxY)
    {
        return maxY * 0.42;
    }
   
    public static double getMultisample(double x0, double z0, double xScale, double zScale, int n)
    {
        double val = 0;
       
        for(int x=0; x<n; x++)
            for(int z=0; z<n; z++)
                val += getValue(x0 + x * xScale / n, z0 + z * zScale / n);
       
        return val / (n * n);
    }
   
    public static double getValue(double x0, double z0)
    {
        int max = 1000;
        int radius = 10;
        int iteration = 0;
        double r = 0;
        double i = 0;
        double rr = 0;
        double ii = 0;
       
        while(rr + ii < radius * radius && iteration < max)
        {
            double temp = rr - ii + x0;
            i = 2*r*i + z0;
            r = temp;
            rr = r*r;
            ii = i*i;
            iteration++;
        }
       
        double value = iteration;
        double magnitude = Math.sqrt(rr + ii);
       
        if(value < max)
            value = smooth(iteration, magnitude, radius);
       
        return flatten(flatten(flatten(normalize(value, max))));
    }
   
    private static double smooth(int iteration, double magnitude, double radius)
    {
        return iteration + 1 - Math.log(Math.log(magnitude) / Math.log(radius)) / Math.log(2);
    }
   
    private static double normalize(double value, double max)
    {
        return Math.log(value) / Math.log(max);
    }

    private static double flatten(double value)
    {
        return Math.log(value + 1) / Math.log(2);
    }
}
TOP

Related Classes of rakama.worldtools.examples.mandel.Mandelbrot

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.