package com.ihunda.android.binauralbeat.viz; /* * @author Giorgio Regni * @contact @GiorgioRegni on Twitter * http://twitter.com/GiorgioRegni * * This file is part of Binaural Beats Therapy or BBT. * * BBT is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * BBT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with BBT. If not, see <http://www.gnu.org/licenses/>. * * BBT project home is at https://github.com/GiorgioRegni/Binaural-Beats */ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import com.ihunda.android.binauralbeat.Visualization; public class Mandelbrot implements Visualization { private static final int PALETTE_SIZE = 768; private static final double ESCAPE = 4; private static final double LOG_ESCAPE = 1.38629436; /** * Beat frequency in Hz */ float freq; float period; private int palette[] = new int[PALETTE_SIZE]; public Mandelbrot() { palette[0] = Color.BLACK; for (int i=1; i<palette.length; i++) { palette[i] = Color.argb(255, i % 256, (i - 47) % 200, (i + 83) % 200); } } // return number of iterations to check if c = a + ib is in Mandelbrot set public double mand(double re, double im, int max) { double re0 = re; double im0 = im; double xtemp; for (int t = 0; t < max; t++) { double re_re = re * re; double im_im = im * im; double z = re_re + im_im; if (z > ESCAPE) { double vz = t - Math.log(Math.log(z)/LOG_ESCAPE); return vz; } xtemp = re_re - im_im + re0; im = 2*re*im + im0; re = xtemp; } return 0; } public void redraw(Canvas c, int width, int height, float now, float totalTime) { // window [-2.0, 1.0, -1.5, 1.5] float dperiod = period * 2 * 200; //double xc = -0.742522478103764; //double yc = -0.143708014488453; double xc = -0.10894500736830963; double yc = -0.8955496975621973; xc = -0.10535958795257323; yc = -0.9237887438236229; double zoom; int N = 80; //Math.min(width, height); // create N-by-N image int max = 40; // maximum number of iterations float ratio = (now % dperiod) / dperiod; if (ratio > 0.5) zoom = 1/((1-ratio)+0.3); else zoom = 1/(ratio+0.3); zoom = 1 / (now + 0.1); //xc = xc * Math.cos(2*Math.PI*ratio); //yc = yc * Math.sin(2*Math.PI*ratio); double size_div_2 = zoom/2; double size_inc = zoom/N; int img[] = new int[N*N]; int base = 0; for (int i = 0; i < N; i++) { double x0 = xc - size_div_2 + size_inc*i; for (int j = 0; j < N; j++) { double y0 = yc - size_div_2 + size_inc*j; int cr = Math.abs((int) (mand(x0, y0, max)/max * PALETTE_SIZE)); /*if (cr >= PALETTE_SIZE) cr = 0;*/ img[j+base] = palette[cr % PALETTE_SIZE]; } base += N; } Bitmap bm = Bitmap.createBitmap(img, N, N, Bitmap.Config.ARGB_4444); /* Paste the bitmap multiple times */ int wm = width/N; double wmd = (double) width/N/wm; int hm = height/N; double hmd = (double) height/N/hm; for (int i=0; i< wm; i++) { for (int j=0; j< hm; j++) { c.drawBitmap(bm, (int) (i*N*wmd) , (int) (j*N*hmd), null); } } } public void setFrequency(float beat_frequency) { freq = beat_frequency; period = 1f / beat_frequency; } }