Исходный файл (1500 × 1000 пикселей, размер файла: 226 КБ, тип MIME: image/png )
ОписаниеILSMJ.png | Русский: Внутренние уровни множеств заполненного множества Жюлиа для fc(z)=z*z+c и c= -0.584895 |
Дата | |
Источник | Собственная работа |
Автор | Адам Маевский |
Разрешение (Повторное использование этого файла) | Я, владелец авторских прав на данную работу, настоящим публикую ее на условиях следующей лицензии: Этот файл лицензирован в соответствии с лицензией Creative Commons Attribution-Share Alike 3.0 Unported.
|
Другие версии |
Ссылки
Внешний вид набора уровней зависит от:
Параметры находятся методом проб и ошибок для получения кривых в виде цифры 8.
Максимальный радиус притяжения (сходимость r.) для c внутри главной кардиоиды равен: [1]
AR = 1-абс(1-кв. корень(1-4c)))
Изображение выше вдохновлено этими изображениями T Kawahira [ нерабочая ссылка ]
Это консольная программа на языке C. Для компиляции:
gcc dc -lm -стена
Для запуска:
./a.out
Это создаст файл 0.000048265.pgm. Чтобы преобразовать его в pgm с помощью Image Magic, используйте:
конвертировать 0.000048265.pgm -изменить размер 1500x1000 c.png
Код отформатирован в Emacs
/* консольная программа на языке c ----------------------------------------- 1.код файла ppm основан на коде Клаудио Роккини http://en.wikipedia.org/wiki/Image:Color_complex_plot.jpg создает 24-битный цветной графический файл, переносимый файл pixmap = PPM см. http://en.wikipedia.org/wiki/Portable_pixmap, чтобы увидеть файл, используйте внешнее приложение (просмотрщик графики) Я думаю, что создание графики не может быть проще --------------------------- 2. сначала он создает массив данных, который используется для хранения значений цвета RGB пикселей, заполняет этот массив данными, а затем записывает данные из массива в файл pgm. Он обеспечивает свободный (не последовательный) доступ к "пикселям" ------------------------------------------- Адам Маевский fraktal.republika.pl Фильтр Собеля Gh = сумма шести значений (3 значения матрицы равны 0). Каждое значение = пиксельный_цвет * коэффициенты_фильтра */ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <complex.h> #include <string.h> /* iXmax/iYmax = 3/2 */ #define iXmax 3000 /* высота изображения в пикселях */ #define iYmax 2000 /* fc(z) = z*z + c */ #define Cx -0.5848950 /* C = Cx + Cy*i */ #define Cy 0.0 #define AR 0.000048265 /* PixelWidth/1; радиус круга вокруг аттрактора ZA = целевой набор для точек притяжения */ #define AR2 AR*AR/* время выхода в бесконечность */ int GiveExtLastIteration ( double _Zx0 , double _Zy0 , double C_x , double C_y , int iMax , double _ER2 ) { int i ; double Zx , Zy ; double Zx2 , Zy2 ; /* Zx2=Zx*Zx; Zy2=Zy*Zy */ Zx = _Zx0 ; /* начальное значение орбиты */ Zy = _Zy0 ; Zx2 = Zx * Zx ; Zy2 = Zy * Zy ; for ( i = 0 ; i < iMax && (( Zx2 + Zy2 ) < _ER2 ); i ++ ) { Zy = 2 * Zx * Zy + C_y ; Zx = Zx2 - Zy2 + C_x ; Zx2 = Zx * Zx ; Zy2 = Zy * Zy ; }; вернуть i ; } /* найти аттрактор ZA, используя прямую итерацию критической точки Z = 0 */ /* если период >1, то даёт одну точку из цикла притяжения */ double complex GiveAttractor ( double _Cx , double _Cy , double ER2 , int _IterationMax ) { int Iteration ; double Zx , Zy ; /* z = zx+zy*i */ double Zx2 , Zy2 ; /* Zx2=Zx*Zx; Zy2=Zy*Zy */ /* -- найти аттрактор ZA, используя прямую итерацию критической точки Z = 0 */ Zx = 0.0 ; Zy = 0.0 ; Zx2 = Zx * Zx ; Zy2 = Zy * Zy ; для ( Итерация = 0 ; Итерация < _IterationMax && (( Zx2 + Zy2 ) < ER2 ); Итерация ++ ) { Zy = 2 * Zx * Zy + _Cy ; Zx = Zx2 - Zy2 + _Cx ; Zx2 = Zx * Zx ; Zy2 = Zy * Zy ; }; вернуть Zx + Zy * I ; } /* притягивание времени к конечному аттрактору ZA */ int GiveIntLastIteration ( double _Zx0 , double _Zy0 , double C_x , double C_y , int iMax , double _AR2 , double _ZAx , double _ZAy ) { int i ; double Zx , Zy ; /* z = zx+zy*i */ double Zx2 , Zy2 ; /* Zx2=Zx*Zx; Zy2=Zy*Zy */ double d , dX , dY ; /* расстояние от z до Alpha */ Zx = _Zx0 ; /* начальное значение орбиты */ Zy = _Zy0 ; Zx2 = Zx * Zx ; Zy2 = Zy * Zy ; dX = Zx - _ZAx ; dY = Zy - _ZAy ; d = dX * dX + dY * dY ; для ( i = 0 ; i < iMax && ( d > _AR2 ); i ++ ) { Zy = 2 * Zx * Zy + C_y ; Zx = Zx2 - Zy2 + C_x ; Zx2 = Zx * Zx ; Zy2 = Zy * Zy ; dX = Zx - _ZAx ; dY = Zy - _ZAy ; d = dX * dX + dY * dY ; }; вернуть i ; } /* возвращает позицию точки (iX,iY) в одномерном массиве; также использует глобальные переменные */ unsigned int f ( unsigned int _iX , unsigned int _iY ) { return ( _iX + ( iYmax - _iY -1 ) * iXmax );} /* ---------------------------------------------------------------- -------------------------------------------------- ------- */int main (){ unsigned int iX , iY , /* индексы двумерного виртуального массива (изображение) = целочисленная координата */ i , /* индекс одномерного массива */ iLength = iXmax * iYmax ; /* длина массива в байтах = количество байт = количество пикселей изображения * количество байт цвета */ /* мировая ( double) координата = параметрическая плоскость */ const double ZxMin = -1.5 ; const double ZxMax = 1.5 ; const double ZyMin = -1.0 ; const double ZyMax = 1.0 ; double PixelWidth = ( ZxMax - ZxMin ) / iXmax ; double PixelHeight = ( ZyMax - ZyMin ) / iYmax ; /* */ double Zx , Zy ; /* Z=Zx+Zy*i */ double complex ZA ; /* аттрактор ZA = ZAx + ZAy*i */ /* */ const double EscapeRadius = 80.0 ; /* радиус окружности вокруг начала координат; его дополнение является целевым набором для точек выхода */ double ER2 = EscapeRadius * EscapeRadius ; const int IterationMax = 60 , IterationMaxBig = 1000001 ; int eLastIteration , iLastIteration ; /* фильтр Собеля */ unsigned char G , Gh , Gv ; /* цвет */ unsigned char color [] = { 255 , 230 , 180 }; const unsigned int MaxColorComponentValue = 255 ; /* компонент цвета кодируется от 0 до 255 ; это 8-битный файл цвета */ /* динамические одномерные массивы для цветов (оттенки серого) */ unsigned char * data , * edge ; data = malloc ( iLength * sizeof ( unsigned char ) ); edge = malloc ( iLength * sizeof ( unsigned char ) ); if ( data == NULL || edge == NULL ) { fprintf ( stderr , "Не удалось выделить память" ); getchar (); return 1 ; } else printf ( "память в порядке \n " ); ZA = GiveAttractor ( Cx , Cy , ER2 , IterationMaxBig ); /* находим аттрактор ZA, используя прямую итерацию критической точки Z = 0 */ /* заполнить массив данных */ for ( iY = 0 ; iY < iYmax ; ++ iY ){ Zy = ZyMin + iY * PixelHeight ; /* */ if ( fabs ( Zy ) < PixelHeight / 2 ) Zy = 0.0 ; /* */ for ( iX = 0 ; iX < iXmax ; ++ iX ){ Zx = ZxMin + iX * PixelWidth ; eLastIteration = GiveExtLastIteration ( Zx , Zy , Cx , Cy , IterationMax , ER2 ); i = f ( iX , iY ); /* вычислить индекс одномерного массива из индексов двумерного массива */ if ( IterationMax != eLastIteration ) { data [ i ] = 245 ;} /* внешний */ else /* внутренний */ { iLastIteration = GiveIntLastIteration ( Zx , Zy , Cx , Cy , IterationMaxBig , AR2 , creal ( ZA ), cimag ( ZA )); data [ i ] = color [ iLastIteration % 2 ];} /* наборы уровней времени притяжения */ /* if (Zx>0 && Zy>0) data[i]=255-data[i]; проверить ориентацию Z-плоскости, отметив первый квадрант */ } } /* поиск границ в массиве данных с использованием фильтра Собеля */ for ( iY = 1 ; iY < iYmax -1 ; ++ iY ){ for ( iX = 1 ; iX < iXmax -1 ; ++ iX ){ Gv = data [ f ( iX -1 , iY + 1 )] + 2 * data [ f ( iX , iY + 1 )] + data [ f ( iX -1 , iY + 1 )] - data [ f ( iX -1 , iY -1 )] - 2 * data [ f ( iX -1 , iY )] - data [ f ( iX + 1 , iY -1 )]; Gh = данные [ f ( iX + 1 , iY + 1 )] + 2 * данные [ f ( iX + 1 , iY )] + данные [ f ( iX -1 , iY -1 )] - данные [ f ( iX + 1 , iY -1 )] - 2 * данные [ f ( iX -1 , iY )] - данные [ f ( iX -1 , iY -1 )]; G = sqrt ( Gh * Gh + Gv * Gv ); я знак равно ж ( iX , iY ); /* вычисляем индекс 1D-массива по индексам 2D-массива */ if ( G == 0 ) { edge [ i ] = 255 ;} /* фон */ else { edge [ i ] = 0 ;} /* граница */ } } /* копируем границы из края в массив данных */ for ( iY = 1 ; iY < iYmax -1 ; ++ iY ){ for ( iX = 1 ; iX < iXmax -1 ; ++ iX ) { i = f ( iX , iY ); /* вычисляем индекс одномерного массива из индексов двумерного массива */ if ( edge [ i ] == 0 ) data [ i ] = 0 ;}} /* ---------- файл -------------------------------------*/ ФАЙЛ * fp ; char name [ 10 ]; /* имя файла */ i = sprintf ( name , "%2.9f" , AR ); /* результат (сохраняется в i), но не используется */ char * filename = strcat ( name , ".pgm" ); char * comment = "# это двоичный файл pgm" ; /* комментарий должен начинаться с # */ /* сохранить изображение в файл pgm */ fp = fopen ( filename , "wb" ); /* создать новый файл, дать ему имя и открыть его в двоичном режиме */ fprintf ( fp , "P5 \n %s \n %u \n %u \n %u \n " , comment , iXmax , iYmax , MaxColorComponentValue ); /* записать заголовок в файл */ fwrite ( data , iLength , 1 , fp ); /* записать байты данных изображения в файл за один шаг */ printf ( "Файл %s сохранен. \n " , filename ); /* --------------свободная память ---------------------*/ free ( data ); free ( edge ); free ( fp ); вернуть 0 ; }
Нажмите на дату/время, чтобы просмотреть файл в том виде, в котором он был в тот момент.
Дата/Время | Миниатюра | Размеры | Пользователь | Комментарий | |
---|---|---|---|---|---|
текущий | 10:35, 16 июля 2011 г. | 1500 × 1000 (226 КБ) | Душа виндсерфера |
Следующая страница использует этот файл:
Этот файл используют и другие вики: