// 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 MandelbrotSource} is a {@link FractalSource} that draws the * Mandelbrot Series. * * @author nickjohnson@google.com (Nick Johnson) * @author schwardo@google.com (Don Schwarz) */ public class MandelbrotSource implements FractalSource { private static final int ESCAPE = 10000; private static final int LIMIT = 1000; private static final int PALETTE_STEP = 4; private static final double MB_XMAX = 1; private static final double MB_XMIN = -2; private static final double MB_YMAX = 1.5; private static final double MB_YMIN = -1.5; private static final double M_LN2 = Math.log(2.0); private static final double LOGESCAPE = Math.log(2 * Math.log(ESCAPE)); private final Palette palette; public MandelbrotSource(Palette palette) { this.palette = palette; } public int getValue(double x, double y) { x = (((x - XMIN) / XRANGE * (MB_XMAX - MB_XMIN)) + MB_XMIN); y = (((y - XMIN) / YRANGE * (MB_YMAX - MB_YMIN)) + MB_YMIN); Complex z = new Complex(0, 0); for (int i = 0; i < LIMIT; i++) { z.modify(x, y); if (z.getValue() >= ESCAPE) { return getValueInternal(i, x, y, z); } } return 0; } private int getValueInternal(int i, double ca, double cb, Complex z) { for (int j = 0; j < 2; j++) { z.modify(ca, cb); } double modulus = Math.sqrt(z.getValue()); double value = i + 2 + (LOGESCAPE - Math.log(Math.log(modulus))) / M_LN2; return palette.getColor(value * PALETTE_STEP); } private static class Complex { private double a; private double b; public Complex(double a, double b) { this.a = a; this.b = b; } public void modify(double x, double y) { double na = x + a * a - b * b; double nb = y + 2 * a * b; a = na; b = nb; } public double getValue() { return a * a + b * b; } } }