Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

Пример, к которому вы оставили комментарий строит именно то самое изображение на языке с#, которое вам необходимо. Отличается только цветовая палитра.
Добрый день! Уже и не знаю куда обратиться. Нужно построить фрактал Жулиа на языке программирования C#. Что бы получилось данное изображение
Необходимо дополнение, как все это запустить, Где писать все эти команды, чтобы видеть результат. Я имею ввиду, что необходимо продемонстрировать полный код HTML-страницы со скриптом и тегами холста. Может даже сделать Урок 0 "Как начать рисовать в...
КРУГОВОЙ ФРАКТАЛ -ОШИБОЧНАЯ ПРОГРАММА! ПАПА ЗибЕрт
Можешь обяснить подробно что как работает, и почему массу не задаем

Счетчики и рейтинг

Яндекс.Метрика Рейтинг@Mail.ru
President's Council on lastfitnessnews.com, Sports & Nutrition (PCFSN) fitness Homepage
Среда программирования: 
Android Studio

В уроке Анимация на Android я показал, как делать анимацию с помощью View и функции invalidate(). Но у такого метода есть недостаток - метод invalidate() вызывает onDraw() не мгновенно, а когда решит операционная система. И если анимация требует тяжелых расчетов, она может заметно тормозить.
Для тяжелых случаев есть другой метод рисования через SurfaceView.

Класс SurfaceView предоставляет объект Surface, который поддерживает рисование в фоновом потоке и дает возможность использовать OpenGL для трехмерной графики. Это отличный вариант для насыщенных графикой элементов, которые нуждаются в частых обновлениях или должны отображать сложную графическую информацию, как в случае с играми и трехмерной визуализацией.

Основной плюс SurfaceView в том, что он работает в паре с объектом класса Thread, что позволяет выполнять тяжелые графические расчеты в отдельном потоке.

Создадим в нашем проекте еще два класса: MySurfaceView и MyThread.

MySurfaceView:

package me.graphica.canvasanimation;
 
import android.content.Context;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
 
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
 
    private MyThread mMyThread; //наш поток прорисовки
 
    public MySurfaceView(Context context) {
        super(context);
        getHolder().addCallback(this);
    }
 
    @Override
    public void surfaceCreated(SurfaceHolder holder) { //вызывается, когда surfaceView появляется на экране
        mMyThread = new MyThread(getHolder());
        mMyThread.setRunning(true);
        mMyThread.start(); //запускает процесс в отдельном потоке
    }
 
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        //когда view меняет свой размер
    }
 
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) { //когда view исчезает из поля зрения
        boolean retry = true;
        mMyThread.setRunning(false); //останавливает процесс
 
        while(retry) {
            try {
                mMyThread.join(); //ждет окончательной остановки процесса
                retry = false;
            }
            catch (InterruptedException e) {
                //не более чем формальность
            }
        }
    }
}

MyThread:

package me.graphica.canvasanimation;
 
import android.animation.ArgbEvaluator;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.SurfaceHolder;
 
/**
 * Created by Sex_predator on 27.03.2016.
 */
public class MyThread extends Thread {
 
    private final int REDRAW_TIME    = 10; //частота обновления экрана - 10 мс
    private final int ANIMATION_TIME = 1_500; //анимация - 1,5 сек
 
    private final SurfaceHolder mSurfaceHolder; //нужен, для получения canvas
 
    private boolean mRunning; //запущен ли процесс
    private long    mStartTime; //время начала анимации
    private long    mPrevRedrawTime; //предыдущее время перерисовки
 
    private Paint mPaint;
    private ArgbEvaluator mArgbEvaluator;
 
    public MyThread(SurfaceHolder holder) {
        mSurfaceHolder = holder;
        mRunning = false;
 
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);
 
        mArgbEvaluator = new ArgbEvaluator();
    }
 
    public void setRunning(boolean running) { //запускает и останавливает процесс
        mRunning = running;
        mPrevRedrawTime = getTime();
    }
 
    public long getTime() {
        return System.nanoTime() / 1_000_000;
    }
 
    @Override
    public void run() {
        Canvas canvas;
        mStartTime = getTime();
 
        while (mRunning) {
            long curTime = getTime();
            long elapsedTime = curTime - mPrevRedrawTime;
            if (elapsedTime < REDRAW_TIME) //проверяет, прошло ли 10 мс
                continue;
//если прошло, перерисовываем картинку
            canvas = null;
            try {
                canvas = mSurfaceHolder.lockCanvas(); //получаем canvas
                synchronized (mSurfaceHolder) {
                    draw(canvas); //функция рисования
                }
            }
            catch (NullPointerException e) {/*если canvas не доступен*/}
            finally {
                if (canvas != null)
                    mSurfaceHolder.unlockCanvasAndPost(canvas); //освобождаем canvas
            }
 
            mPrevRedrawTime = curTime;
        }
    }
 
    private void draw(Canvas canvas) {
        long curTime = getTime() - mStartTime;
 
        int width = canvas.getWidth();
        int height = canvas.getHeight();
 
        canvas.drawColor(Color.BLACK);
 
        int centerX = width / 2;
        int centerY = height / 2;
 
        float maxSize = Math.min(width, height) / 2;
 
        float fraction = (float) (curTime % ANIMATION_TIME) / ANIMATION_TIME;
 
        int color = (int) mArgbEvaluator.evaluate(fraction, Color.RED, Color.BLACK);
        mPaint.setColor(color);
 
        canvas.drawCircle(centerX, centerY, maxSize * fraction, mPaint);
    }
}

Не рекомендуется делать REDRAW_TIME слишком маленьким, это может сильно нагружать систему. 10 мс вполне достаточно.

Последний штрих: вернемся в MyActivity и сменим
setContentView(new MyView(this));
на
setContentView(new MySurfaceView(this));

Приложение должно выглядеть так: