Annotation of QuadraticMandel/genfractal.c, revision 1.2

1.1       cvsmgr      1: /*******************************************************************************
1.2     ! cvsmgr      2: +*  Fractal set generation for quadratic maps.
        !             3: +*  Copyright (C) 2011, Raúl Durán Díaz, raul.duran@uah.es
        !             4: +*
        !             5: +*  This program is free software: you can redistribute it and/or modify
        !             6: +*  it under the terms of the GNU General Public License as published by
        !             7: +*  the Free Software Foundation, either version 3 of the License, or
        !             8: +*  (at your option) any later version.
        !             9: +*
        !            10: +*  This program is distributed in the hope that it will be useful,
        !            11: +*  but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            12: +*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            13: +*  GNU General Public License for more details.
        !            14: +*
        !            15: +*  You should have received a copy of the GNU General Public License
        !            16: +*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
        !            17: *******************************************************************************/
        !            18: /*******************************************************************************
1.1       cvsmgr     19: +*
                     20: +* 9.12.2005
                     21: +*
                     22: +* $Id: genfractal.c,v 1.24 2010/03/16 17:42:39 rduran Exp $
                     23: +* $Name:  $
                     24: +*
                     25: +* Falta por hacer el cálculo del mínimo A para Gc. Ahora se usa la
                     26: +* iteración especial con valor de 50.0
                     27: +*
                     28: *******************************************************************************/
                     29: # include <stdlib.h>
                     30: # include <stdio.h>
                     31: # include <string.h>
                     32: # include <math.h>
                     33: # include <stdarg.h>
                     34: # include "mypng.h"
                     35: # include "genfractal.h"
                     36: # include "mathutil.h"
                     37: 
                     38: enum Zona {ZONA_Fbc_MAS, ZONA_Fbc_MENOS, ZONA_Fc_MAS, ZONA_Fc_MENOS, ZONA_Gc, ZONA_00};
                     39: 
                     40: static double minA = 1.0;
                     41: static double a1   = 1.0;
                     42: static double b1   = 1.0;
                     43: static double c1   = 1.0;
                     44: static double a2   = 1.0;
                     45: static double b2   = 1.0;
                     46: static double c2   = 1.0;
                     47: 
                     48: enum Zona zona = ZONA_Fbc_MAS;
                     49: 
                     50: /*******************************************************************************
                     51: +* El siguiente if a 1 para imagen en color, 0 para blanco y negro.
                     52: *******************************************************************************/
                     53: # if 1
                     54: static void PNGColorAssign(png_colorp p, int iter, int itermax)
                     55: {
                     56: double ratio = 767.0*((double) iter / (double) itermax);
                     57: int    c     = lround(ratio);
                     58: 
                     59: # if 0
                     60: if (c != 0 && c != 767) printf("iter: %d, ratio=%lf, c=%d\n", iter, ratio, c);
                     61: # endif
                     62:    switch (c/256)
                     63:    {
                     64:       case 0:
                     65:         p->blue = c%256;
                     66: # if 0
                     67: if (c!=0 && c!=255) printf("Caso 0\n");
                     68: # endif
                     69:       break;
                     70: 
                     71:       case 1:
                     72:         p->blue  = 255 - c%256;
                     73:         p->green = c%256;
                     74: # if 0
                     75: if (c!=0 && c!=255) printf("Caso 1\n");
                     76: # endif
                     77:       break;
                     78: 
                     79:       default:
                     80:         p->green = 255 - c%256;
                     81:         p->red   = c%256;
                     82: # if 0
                     83: if (c!=0 && c!=255) printf("Caso default\n");
                     84: # endif
                     85:    }
                     86: }
                     87: # endif
                     88: 
                     89: /*******************************************************************************
                     90: +* El siguiente if a 0 para imagen en color, 1 para blanco y negro.
                     91: *******************************************************************************/
                     92: # if 0
                     93: static void PNGColorAssign(png_colorp p, int iter, int itermax)
                     94: {
                     95: double ratio = 255.0*((double) iter / (double) itermax);
                     96: 
                     97: /*******************************************************************************
                     98: +* El siguiente if a 1 para fondo blanco, fractal negro.
                     99: *******************************************************************************/
                    100: # if 1
                    101:    p->blue = p->green = p->red = 255 - lround(ratio);
                    102: # endif
                    103: /*******************************************************************************
                    104: +* El siguiente if a 1 para fondo negro, fractal blanco.
                    105: *******************************************************************************/
                    106: # if 0
                    107:    p->blue = p->green = p->red = lround(ratio);
                    108: # endif
                    109: }
                    110: # endif
                    111: 
                    112: static double ComputeZR(double zr, double zi)
                    113: {
                    114:    return a1*zr*zr + 2.0*b1*zr*zi + c1*zi*zi;
                    115: }
                    116: 
                    117: static double ComputeZI(double zr, double zi)
                    118: {
                    119:    return a2*zr*zr + 2.0*b2*zr*zi + c2*zi*zi;
                    120: }
                    121: 
                    122: static double maximo(double a, double b)
                    123: {
                    124:    if (a > b)
                    125:       return a;
                    126:    else
                    127:       return b;
                    128: }
                    129: 
                    130: static double minimo(double a, double b)
                    131: {
                    132:    if (a < b)
                    133:       return a;
                    134:    else
                    135:       return b;
                    136: }
                    137: 
                    138: /*******************************************************************************
                    139: +* Función A_t para la parte F^+_{bc}
                    140: *******************************************************************************/
                    141: static double Ap_t(double t)
                    142: {
                    143:    return pow(1. - pow(t,2),2)/pow(1. + pow(t,2),2) +
                    144:           pow(t,2)/pow(1. + pow(t,2),2)*
                    145:           (
                    146:            pow(c1,2)*pow(t,2)  +
                    147:            4.*pow(b1,2)        +
                    148:            4.*b1*c1*t
                    149:           );
                    150: }
                    151: 
                    152: 
                    153: static void ComputeMinAplus00(void)
                    154: {
                    155: double t = sqrt(2./(2.+pow(c1,2)));
                    156: 
                    157:    minA = minimo(minA, Ap_t(t));
                    158:    minA = minimo(minA, Ap_t(-t));
                    159: 
                    160:    return;
                    161: }
                    162: 
                    163: void ComputeMinAplus(void)
                    164: {
                    165: double k;
                    166: double p;
                    167: double q;
                    168: double d;
                    169: double rho;
                    170: double theta;
                    171: double l1q;
                    172: double l2q;
                    173: int    i;
                    174: 
                    175:    k = (pow(c1,2)-2.*pow(b1,2)+2.)/(3.*b1*c1);
                    176:    p = (-4.*k-3.*b1*c1-2.*pow(c1,2)*k+3.*b1*c1*pow(k,2)+4.*pow(b1,2)*k)/(b1*c1);
                    177:    q = (-2.*pow(k,2)-3.*b1*c1*k+2+b1*c1*pow(k,3)-2.*pow(b1,2)+2.*pow(b1,2)*pow(k,2)-pow(c1,2)*pow(k,2))/(b1*c1);
                    178: 
                    179:    if ((d = 81.*pow(q,2)+12.*pow(p,3)) < 0.0)
                    180:    {
                    181:       l1q = q*q/4.;
                    182:       l2q = -d/324.;
                    183:       rho = sqrt(l1q + l2q);
                    184:       theta = atan(sqrt(l2q/l1q));
                    185: 
                    186:       for (i = 0; i < 3; i++)
                    187:          minA = minimo(minA, Ap_t(2.*pow(rho, 1./3.)*cos(theta/3. + 2.*i*M_PI/3.) + k));
                    188:    }
                    189:    else
                    190:    {
                    191:       fprintf(stderr, "#WARNING: Discriminante positivo, sólo hay una solución.\n");
                    192:       minA = minimo(minA, Ap_t(pow(-q/2. + sqrt(d)/18.,1./3.) + pow(-q/2. - sqrt(d)/18.,1./3.) + k));
                    193:    }
                    194: 
                    195:    return;
                    196: }
                    197: 
                    198: /*******************************************************************************
                    199: +* Función A_t para la parte F^-_{bc}
                    200: *******************************************************************************/
                    201: static double Am_t(double t)
                    202: {
                    203:    return 1 + pow(t,2)/pow(1. + pow(t,2),2)*
                    204:           (
                    205:            pow(c1,2)*pow(t,2)  +
                    206:            4.*pow(b1,2)        +
                    207:            4.*b1*c1*t
                    208:           );
                    209: }
                    210: 
                    211: static void ComputeMinAminus00(void)
                    212: {
                    213:    if (b1 != 0.0)
                    214:    {
                    215:       minA = minimo(minA, Am_t(1.));
                    216:       minA = minimo(minA, Am_t(-1.));
                    217:    }
                    218: 
                    219:    return;
                    220: }
                    221: 
                    222: static void ComputeMinAminus(void)
                    223: {
                    224: double k;
                    225: double p;
                    226: double q;
                    227: double d;
                    228: double rho;
                    229: double theta;
                    230: double l1q;
                    231: double l2q;
                    232: int    i;
                    233: 
                    234:    k = (pow(c1,2)-2.*pow(b1,2))/(3.*b1*c1);
                    235:    p = (4.*pow(b1,2)*k-2.*pow(c1,2)*k+3.*b1*c1*pow(k,2)-3.*b1*c1)/(b1*c1);
                    236:    q = (-2.*pow(b1,2)+2.*pow(b1,2)*pow(k,2)-pow(c1,2)*pow(k,2)+b1*c1*pow(k,3)-3.*b1*c1*k)/(b1*c1);
                    237: 
                    238:    if ((d = 81.*pow(q,2)+12.*pow(p,3)) < 0.0)
                    239:    {
                    240:       l1q = q*q/4.;
                    241:       l2q = -d/324.;
                    242:       rho = sqrt(l1q + l2q);
                    243:       theta = atan(sqrt(l2q/l1q));
                    244: 
                    245:       for (i = 0; i < 3; i++)
                    246:          minA = minimo(minA, Am_t(2.*pow(rho, 1./3.)*cos(theta/3. + 2.*i*M_PI/3.) + k));
                    247:    }
                    248:    else
                    249:    {
                    250:       fprintf(stderr, "#WARNING: Discriminante positivo, sólo hay una solución.\n");
                    251:       minA = minimo(minA, Am_t(pow(-q/2. + sqrt(d)/18.,1./3.) + pow(-q/2. - sqrt(d)/18.,1./3.) + k));
                    252:    }
                    253: 
                    254:    return;
                    255: }
                    256: 
                    257: /*******************************************************************************
                    258: +* Función A_t y sus derivadas para la parte F^+_{c}
                    259: *******************************************************************************/
                    260: static double AFcMas_t(double t)
                    261: {
                    262:    return 1/pow(1. + pow(t,2),2)*
                    263:           (
                    264:            pow(c1,2)*pow(t,4)  +
                    265:            4.*c1*pow(t,3)      +
                    266:            4.*pow(t,2)         +
                    267:            1.
                    268:           );
                    269: }
                    270: 
                    271: static void ComputeMinAFcMas0(void)
                    272: {
                    273: 
                    274:    minA = minimo(minA, AFcMas_t(sqrt(2.)/.2));
                    275:    minA = minimo(minA, AFcMas_t(-sqrt(2.)/.2));
                    276: 
                    277:    return;
                    278: }
                    279: 
                    280: static void ComputeMinAFcMas(void)
                    281: {
                    282: double k;
                    283: double p;
                    284: double q;
                    285: double d;
                    286: double rho;
                    287: double theta;
                    288: double l1q;
                    289: double l2q;
                    290: int    i;
                    291: 
                    292:    k = 1./3.*(pow(c1,2)-2.)/c1;
                    293:    p = (-2.*k*pow(c1,2) + 4.*k + 3.*c1*pow(k,2) - 3.*c1)/c1;
                    294:    q = (-1. - pow(c1,2)*pow(k,2) + 2.*pow(k,2) + c1*pow(k,3) - 3.*c1*k)/c1;
                    295: 
                    296:    if ((d = 81.*pow(q,2)+12.*pow(p,3)) < 0.0)
                    297:    {
                    298:       l1q = q*q/4.;
                    299:       l2q = -d/324.;
                    300:       rho = sqrt(l1q + l2q);
                    301:       theta = atan(sqrt(l2q/l1q));
                    302: 
                    303:       for (i = 0; i < 3; i++)
                    304:          minA = minimo(minA, AFcMas_t(2.*pow(rho, 1./3.)*cos(theta/3. + 2.*i*M_PI/3.) + k));
                    305:    }
                    306:    else
                    307:    {
                    308:       fprintf(stderr, "#WARNING: Discriminante positivo, sólo hay una solución.\n");
                    309:       minA = minimo(minA, AFcMas_t(pow(-q/2. + sqrt(d)/18.,1./3.) + pow(-q/2. - sqrt(d)/18.,1./3.) + k));
                    310:    }
                    311: 
                    312:    return;
                    313: }
                    314: 
                    315: /*******************************************************************************
                    316: +* Función A_t y sus derivadas para la parte F^-_{c}
                    317: *******************************************************************************/
                    318: static double AFcMenos_t(double t)
                    319: {
                    320:    return 1/pow(1. + pow(t,2),2)*
                    321:           (
                    322:            pow(c1,2)*pow(t,4)  -
                    323:            4.*c1*pow(t,3)      +
                    324:            4.*pow(t,2)         +
                    325:            1.
                    326:           );
                    327: }
                    328: 
                    329: static void ComputeMinAFcMenos0(void)
                    330: {
                    331: 
                    332:    minA = minimo(minA, AFcMenos_t(sqrt(2.)/.2));
                    333:    minA = minimo(minA, AFcMenos_t(-sqrt(2.)/.2));
                    334: 
                    335:    return;
                    336: }
                    337: 
                    338: static void ComputeMinAFcMenos(void)
                    339: {
                    340: double k;
                    341: double p;
                    342: double q;
                    343: double d;
                    344: double rho;
                    345: double theta;
                    346: double l1q;
                    347: double l2q;
                    348: int    i;
                    349: 
                    350:    k = -1./3.*(pow(c1,2)-2.)/c1;
                    351:    p = (2.*k*pow(c1,2) - 4.*k + 3.*c1*pow(k,2) - 3.*c1)/c1;
                    352:    q = (1. + pow(c1,2)*pow(k,2) - 2.*pow(k,2) + c1*pow(k,3) - 3.*c1*k)/c1;
                    353: 
                    354:    if ((d = 81.*pow(q,2)+12.*pow(p,3)) < 0.0)
                    355:    {
                    356:       l1q = q*q/4.;
                    357:       l2q = -d/324.;
                    358:       rho = sqrt(l1q + l2q);
                    359:       theta = atan(sqrt(l2q/l1q));
                    360: 
                    361:       for (i = 0; i < 3; i++)
                    362:          minA = minimo(minA, AFcMenos_t(2.*pow(rho, 1./3.)*cos(theta/3. + 2.*i*M_PI/3.) + k));
                    363:    }
                    364:    else
                    365:    {
                    366:       fprintf(stderr, "#WARNING: Discriminante positivo, sólo hay una solución.\n");
                    367:       minA = minimo(minA, AFcMenos_t(pow(-q/2. + sqrt(d)/18.,1./3.) + pow(-q/2. - sqrt(d)/18.,1./3.) + k));
                    368:    }
                    369: 
                    370:    return;
                    371: }
                    372: 
                    373: /*******************************************************************************
                    374: +* Función para la parte G_{c}
                    375: *******************************************************************************/
                    376: static void ComputeMinAGc(void)
                    377: {
                    378: double ypsilon;
                    379: double Ypsilon;
                    380: double tau1;
                    381: 
                    382:    ypsilon = 3*pow(c1,9)    - 9*pow(c1,8)    + 36*pow(c1,7)   -
                    383:              111*pow(c1,6)  + 540*pow(c1,5)  - 1107*pow(c1,4) +
                    384:              2592*pow(c1,3) - 3321*pow(c1,2) + 6237*c1-10044;
                    385: 
                    386:    if (ypsilon > 0.0)
                    387:    {
                    388:       Ypsilon = pow((c1-1.)*pow(c1+1.,2) + sqrt(ypsilon)/9., 1./3.);
                    389:       tau1 = (3*pow(Ypsilon,2) + 3*(1-c1)*Ypsilon -
                    390:              (pow(c1,3)-pow(c1,2)+3*c1-15))/(3*c1*Ypsilon);
                    391:    }
                    392: }
                    393: 
                    394: /*******************************************************************************
                    395: +* Cálculo del mínimo de la B y computación del Modúlo máximo.
                    396: *******************************************************************************/
                    397: 
                    398: static double ComputeMod2Max(double alpha, double beta)
                    399: {
                    400: double minB = 0.0;
                    401: 
                    402:    if (zona == ZONA_Fbc_MAS)
                    403:       minB = c1*alpha - sqrt(pow(2.*b1*alpha,2)+pow(2.*beta-c1*alpha,2));
                    404:    else if (zona == ZONA_Fbc_MENOS)
                    405:       minB = c1*alpha+2.*beta - sqrt(pow(2.*b1*alpha,2)+pow(c1*alpha,2));
                    406:    else if (zona == ZONA_Fc_MAS)
                    407:       minB = beta + alpha*c1 - sqrt(pow(beta-alpha*c1,2) + 4.*pow(alpha,2));
                    408:    else if (zona == ZONA_Fc_MENOS)
                    409:       minB = beta + alpha*c1 - sqrt(pow(beta-alpha*c1,2) + 4.*pow(alpha,2));
                    410:    else if (zona == ZONA_Gc)
                    411:       minB = alpha*(c1 + 1.) - sqrt(pow(-c1+1.,2)*pow(alpha,2)+4.*pow(alpha-beta,2));
                    412:    else if (zona == ZONA_00)
                    413:       minB = -2.*sqrt(pow(alpha,2) + pow(beta,2));
                    414:    else
                    415:    {
                    416:       fprintf(stderr, "#ERROR: Zona no implementada en el cálculo de min B.\n");
                    417:       return 0.;
                    418:    }
                    419: 
                    420:    return maximo(0., (1.-minB)/minA);
                    421: }
                    422: 
                    423: /*******************************************************************************
                    424: +* Parte fija del cómputo.
                    425: *******************************************************************************/
                    426: static void IterComputation(png_colorpp image, int itermax)
                    427: {
                    428: int         row, col, iter;
                    429: double      mod2;
                    430: double      mod2max;
                    431: double      zrtemp, zitemp;
                    432: double      zr, zi;
                    433: double      cr, ci;
                    434: # if 0
                    435: png_color   p;
                    436: # endif
                    437: 
                    438:    for (row = 0; row < NUM_ROWS; row++)
                    439:    {
                    440:       for (col = 0; col < NUM_COLS; col++)
                    441:       {
                    442:          cr = PixToCoordX(col);
                    443:          ci = PixToCoordY(row);
                    444: 
                    445:          mod2max = ComputeMod2Max(cr, ci);
                    446: 
                    447:          zr = 0.0;
                    448:          zi = 0.0;
                    449: 
                    450:          for (iter = 0; iter < itermax; iter++)
                    451:          {
                    452:             zrtemp = ComputeZR(zr, zi);
                    453:             zitemp = ComputeZI(zr, zi);
                    454: 
                    455:             zr = zrtemp + cr;
                    456:             zi = zitemp + ci;
                    457: 
                    458:             mod2 = zr*zr + zi*zi;
                    459:             if (mod2 > mod2max)
                    460:             {
                    461: # if 0
                    462:                printf("Nos salimos en la: %d\n", iter);
                    463: # endif
                    464:                break;
                    465:             }
                    466:          }
                    467: # if 0
                    468:          if (iter >= itermax)
                    469:             printf("Nos salimos por exceso, en (%lf, %lf)\n", cr, ci);
                    470: # endif
                    471: 
                    472:          PNGColorAssign(&image[row][col], iter, itermax);
                    473:       }
                    474:    }
                    475: 
                    476: # if 0
                    477:    p.red = 0; p.green = 255; p.blue = 0;
                    478:    DrawHorizLine(image, 0.0, p);
                    479:    DrawHorizLine(image, 1.0, p);
                    480:    DrawHorizLine(image, -1.0, p);
                    481: 
                    482:    DrawVertiLine(image, 0.0, p);
                    483:    DrawVertiLine(image, 1.0, p);
                    484:    DrawVertiLine(image, -1.0, p);
                    485: # endif
                    486: }
                    487: 
                    488: /*******************************************************************************
                    489: +* Parte fija del cómputo.
                    490: *******************************************************************************/
                    491: static void IterComputationEspecial(png_colorpp image, int itermax, double modmax)
                    492: {
                    493: int         row, col, iter;
                    494: double      mod2;
                    495: double      mod2max;
                    496: double      zrtemp, zitemp;
                    497: double      zr, zi;
                    498: double      cr, ci;
                    499: int         flag_changed = 0,
                    500:             mandel_zone  = 0,
                    501:             is_break     = 0;
                    502: # if 0
                    503: png_color   p;
                    504: # endif
                    505: 
                    506:    for (row = 0; row < NUM_ROWS; row++)
                    507:    {
                    508:       for (col = 0; col < NUM_COLS; col++)
                    509:       {
                    510: 
                    511:          cr = PixToCoordX(col);
                    512:          ci = PixToCoordY(row);
                    513: 
                    514:          mod2max = modmax;
                    515: 
                    516:          zr = 0.0;
                    517:          zi = 0.0;
                    518: 
                    519:          is_break = 0;
                    520:          for (iter = 0; iter < itermax; iter++)
                    521:          {
                    522:             zrtemp = ComputeZR(zr, zi);
                    523:             zitemp = ComputeZI(zr, zi);
                    524: 
                    525:             zr = zrtemp + cr;
                    526:             zi = zitemp + ci;
                    527: 
                    528:             mod2 = zr*zr + zi*zi;
                    529:             if (mod2 > mod2max)
                    530:             {
                    531:                if (mandel_zone)
                    532:                {
                    533:                   mandel_zone = 0;
                    534:                   flag_changed = 1;
                    535:                }
                    536:                is_break = 1;
                    537:                break;
                    538:             }
                    539:          }
                    540:          if (is_break == 0)
                    541:          {
                    542:             if (mandel_zone == 0)
                    543:             {
                    544:                mandel_zone = 1;
                    545:                flag_changed = 1;
                    546:             }
                    547:          }
                    548:          else
                    549:          {
                    550:             if (mandel_zone == 1)
                    551:             {
                    552:                mandel_zone = 0;
                    553:                flag_changed = 1;
                    554:             }
                    555:          }
                    556: 
                    557:          if (flag_changed)
                    558:          {
                    559: # if 0
                    560:             printf("%15.10lf %15.10lf\n", cr, ci);
                    561: # endif
                    562:             flag_changed = 0;
                    563:          }
                    564: 
                    565:          PNGColorAssign(&image[row][col], iter, itermax);
                    566:       }
                    567: # if 0
                    568:       printf("\n");
                    569: # endif
                    570:    }
                    571: 
                    572: # if 0
                    573:    p.red = 0; p.green = 255; p.blue = 0;
                    574:    DrawHorizLine(image, 0.0, p);
                    575:    DrawHorizLine(image, 1.0, p);
                    576:    DrawHorizLine(image, -1.0, p);
                    577: 
                    578:    DrawVertiLine(image, 0.0, p);
                    579:    DrawVertiLine(image, 1.0, p);
                    580:    DrawVertiLine(image, -1.0, p);
                    581: # endif
                    582: }
                    583: 
                    584: /*******************************************************************************
                    585: +* GenFractal
                    586: +* Genera la imagen fractal para las zonas \Delta^+ y \Delta^-
                    587: *******************************************************************************/
                    588: int GenFractal(char *img_name, double alpha,
                    589:                                double beta,
                    590:                                int    itermax,
                    591:                                double side_len,
                    592:                                double offset_x,
                    593:                                double offset_y)
                    594: {
                    595: png_colorpp image = NULL;
                    596: png_text    info_text[NUM_TEXT];
                    597: int         status;
                    598: double      c_temp;
                    599: 
                    600: /*******************************************************************************
                    601: +* Parámetros de tamaño para la imagen. Reserva de memoria para ella.
                    602: *******************************************************************************/
                    603:    SetSide(side_len);
                    604:    SetOffsetX(offset_x);
                    605:    SetOffsetY(offset_y);
                    606: 
                    607:    if (!(image = AllocatePNG(NUM_ROWS, NUM_COLS)))
                    608:       return ERROR;
                    609: 
                    610:    BuildTextPtr(info_text, alpha, beta, itermax, side_len, offset_x, offset_y);
                    611: 
                    612: /*******************************************************************************
                    613: +* Definición de la forma cuadrática.
                    614: +* Parte fija:
                    615: *******************************************************************************/
                    616:    a1 = 0.0;
                    617:    a2 = 1.0;
                    618:    b2 = 0.0;
                    619: 
                    620: /*******************************************************************************
                    621: +* Definición de la forma cuadrática.
                    622: +* Chequeo de condiciones sobre alpha y beta.
                    623: *******************************************************************************/
                    624:    if (beta == 0.0)   /* Beta ha de ser diferente de cero */
                    625:       return ERROR;
                    626: 
                    627:    if ((alpha + 2.*beta) == 0.0) /* alpha + 2*beta != 0.0 */
                    628:       return ERROR;
                    629: 
                    630: /*******************************************************************************
                    631: +* Definición de la forma cuadrática.
                    632: +* Parte variable en función de alpha y beta:
                    633: *******************************************************************************/
                    634:    c_temp = (4.*pow(alpha,3) - 27.*pow(beta,2))/pow(alpha + 2.*beta,3);
                    635: 
                    636:    if (c_temp < 0.0)
                    637:    {
                    638:    /* Zona F^-_{bc} */
                    639:       c2 = 1.0;
                    640:       zona = ZONA_Fbc_MENOS;
                    641:    }
                    642:    else
                    643:    {
                    644:    /* Zona F^+_{bc} */
                    645:       c2 = -1.0;
                    646:       zona = ZONA_Fbc_MAS;
                    647:    }
                    648: 
                    649:    b1 = -c2*(alpha - beta)/(alpha + 2.*beta);
                    650:    c1 = sqrt((-c2)*c_temp);
                    651: 
                    652:    if (zona == ZONA_Fbc_MAS)
                    653:    {
                    654:       if (c1 == 2.*b1  ||  c1 == -2.*b1)
                    655:       {
                    656:          fprintf(stderr, "#ERROR: Valores de b1 y c1 inválidos.\n");
                    657:          return ERROR;
                    658:       }
                    659:    }
                    660: 
                    661: /*******************************************************************************
                    662: +* Cálculo del mínimo de A, según valores de b1, c1 y zonas.
                    663: *******************************************************************************/
                    664:    minA = 1.;
                    665:    if (zona == ZONA_Fbc_MAS)
                    666:    {
                    667:       if (b1 == 0.0  ||  c1 == 0.0)
                    668:          ComputeMinAplus00();
                    669:       else
                    670:          ComputeMinAplus();
                    671:    }
                    672:    else if (zona == ZONA_Fbc_MENOS)
                    673:    {
                    674:       if (b1 == 0.0  ||  c1 == 0.0)
                    675:          ComputeMinAminus00();
                    676:       else
                    677:          ComputeMinAminus();
                    678:    }
                    679:    else
                    680:    {
                    681:       fprintf(stderr, "#ERROR: Zona no implementada.\n");
                    682:       return ERROR;
                    683:    }
                    684: 
                    685: /*******************************************************************************
                    686: +* Computación y generación de la imagen.
                    687: *******************************************************************************/
                    688:    IterComputation(image, itermax);
                    689:    status = WritePNG(img_name, image, info_text, NUM_TEXT);
                    690:    DeallocatePNG(image, NUM_ROWS, NUM_COLS);
                    691:    return status;
                    692: }
                    693: 
                    694: /*******************************************************************************
                    695: +* GenFractal
                    696: +* Genera la imagen fractal para las zonas C^+ y C^-
                    697: *******************************************************************************/
                    698: int GenFractalLinear(char *img_name, double alpha,
                    699:                                      double beta,
                    700:                                      int    itermax,
                    701:                                      double side_len,
                    702:                                      double offset_x,
                    703:                                      double offset_y)
                    704: {
                    705: png_colorpp image = NULL;
                    706: png_text    info_text[NUM_TEXT];
                    707: int         status;
                    708: 
                    709: /*******************************************************************************
                    710: +* Parámetros de tamaño para la imagen. Reserva de memoria para ella.
                    711: *******************************************************************************/
                    712:    SetSide(side_len);
                    713:    SetOffsetX(offset_x);
                    714:    SetOffsetY(offset_y);
                    715: 
                    716:    if (!(image = AllocatePNG(NUM_ROWS, NUM_COLS)))
                    717:       return ERROR;
                    718: 
                    719:    BuildTextPtr(info_text, alpha, beta, itermax, side_len, offset_x, offset_y);
                    720: 
                    721: /*******************************************************************************
                    722: +* Definición de la forma cuadrática.
                    723: +* Parte fija:
                    724: *******************************************************************************/
                    725:    a1 = 0.0;
                    726:    a2 = 1.0;
                    727:    b2 = 0.0;
                    728:    c2 = 0.0;
                    729: 
                    730: /*******************************************************************************
                    731: +* Definición de la forma cuadrática.
                    732: +* Chequeo de condiciones sobre beta.
                    733: *******************************************************************************/
                    734:    if (beta == 0.0)   /* Beta ha de ser diferente de cero */
                    735:       return ERROR;
                    736: 
                    737:    if (alpha + 2.*beta != 0.0)
                    738:       return ERROR;   /* alpha + 2*beta ha de ser cero */
                    739: 
                    740: /*******************************************************************************
                    741: +* Definición de la forma cuadrática.
                    742: +* Parte variable en función de beta: setting de zonas.
                    743: *******************************************************************************/
                    744:    if (beta*(27.0+32.0*beta) < 0.0)
                    745:    {
                    746:       b1 = -1.0;
                    747:       zona = ZONA_Fc_MENOS;
                    748:    }
                    749:    else
                    750:    {
                    751:       b1 = 1.0;
                    752:       zona = ZONA_Fc_MAS;
                    753:    }
                    754: 
                    755:    c1 = b1/9.0*sqrt(fabs(3.0*(27.0+32.0*beta)/beta));
                    756: 
                    757: /*******************************************************************************
                    758: +* Cálculo del mínimo de A, según valores de b1, c1 y zonas.
                    759: *******************************************************************************/
                    760:    minA = 1.;
                    761:    if (zona == ZONA_Fc_MAS)
                    762:    {
                    763:       if (c1 == 0.0)
                    764:          ComputeMinAFcMas0();
                    765:       else
                    766:          ComputeMinAFcMas();
                    767:    }
                    768:    else if (zona == ZONA_Fc_MENOS)
                    769:    {
                    770:       if (c1 == 0.0)
                    771:          ComputeMinAFcMenos0();
                    772:       else
                    773:          ComputeMinAFcMenos();
                    774:    }
                    775:    else
                    776:    {
                    777:       fprintf(stderr, "#ERROR: Zona no implementada.\n");
                    778:       return ERROR;
                    779:    }
                    780: 
                    781: /*******************************************************************************
                    782: +* Computación y generación de la imagen.
                    783: *******************************************************************************/
                    784:    IterComputation(image, itermax);
                    785:    status = WritePNG(img_name, image, info_text, NUM_TEXT);
                    786:    DeallocatePNG(image, NUM_ROWS, NUM_COLS);
                    787:    return status;
                    788: }
                    789: 
                    790: /*******************************************************************************
                    791: +* GenFractal
                    792: +* Genera la imagen fractal para el eje X (menos el origen).
                    793: *******************************************************************************/
                    794: int GenFractalAlpha(char *img_name, double alpha,
                    795:                                     double beta,
                    796:                                     int    itermax,
                    797:                                     double side_len,
                    798:                                     double offset_x,
                    799:                                     double offset_y)
                    800: {
                    801: png_colorpp image = NULL;
                    802: png_text    info_text[NUM_TEXT];
                    803: int         status;
                    804: 
                    805: /*******************************************************************************
                    806: +* Parámetros de tamaño para la imagen. Reserva de memoria para ella.
                    807: *******************************************************************************/
                    808:    SetSide(side_len);
                    809:    SetOffsetX(offset_x);
                    810:    SetOffsetY(offset_y);
                    811: 
                    812:    if (!(image = AllocatePNG(NUM_ROWS, NUM_COLS)))
                    813:       return ERROR;
                    814: 
                    815:    BuildTextPtr(info_text, alpha, beta, itermax, side_len, offset_x, offset_y);
                    816: 
                    817: /*******************************************************************************
                    818: +* Definición de la forma cuadrática.
                    819: +* Parte fija:
                    820: *******************************************************************************/
                    821:    a1 = 1.0;
                    822:    a2 = 0.0;
                    823:    b1 = 1.0;
                    824:    b2 = -1.0;
                    825:    c2 = 0.0;
                    826: 
                    827: /*******************************************************************************
                    828: +* Definición de la forma cuadrática.
                    829: +* Chequeo de condiciones sobre alpha y beta, y setting de zona.
                    830: *******************************************************************************/
                    831:    if (alpha == 0.0  ||  beta != 0.0)   /* Alpha ha de ser diferente de cero */
                    832:       return ERROR;                     /* y beta igual a cero.              */
                    833: 
                    834:    zona = ZONA_Gc;
                    835: 
                    836: /*******************************************************************************
                    837: +* Definición de la forma cuadrática.
                    838: +* Parte variable en función de alpha:
                    839: *******************************************************************************/
                    840: 
                    841:    c1 = (4.0*alpha - 9.0)/alpha/12.0;
                    842: 
                    843: /*******************************************************************************
                    844: +* Cálculo del mínimo de A, según valores de b1, c1 y zonas.
                    845: *******************************************************************************/
                    846:    ComputeMinAGc();
                    847:    minA = 1.;
                    848: 
                    849: # if 0
                    850:    if (zona == ZONA_Gc)
                    851:    {
                    852:       fprintf(stderr, "#ERROR: Zona no implementada.\n");
                    853:       return ERROR;
                    854:    }
                    855:    else
                    856:    {
                    857:       fprintf(stderr, "#ERROR: Zona no implementada.\n");
                    858:       return ERROR;
                    859:    }
                    860: # endif
                    861: 
                    862: /*******************************************************************************
                    863: +* Computación y generación de la imagen.
                    864: *******************************************************************************/
                    865: # if 0
                    866:    IterComputation(image, itermax);
                    867: # endif
                    868:    IterComputationEspecial(image, itermax, 50.0);
                    869:    status = WritePNG(img_name, image, info_text, NUM_TEXT);
                    870:    DeallocatePNG(image, NUM_ROWS, NUM_COLS);
                    871:    return status;
                    872: }
                    873: 
                    874: /*******************************************************************************
                    875: +* GenFractal_00
                    876: +* Genera la imagen fractal para el punto origen (0,0)
                    877: *******************************************************************************/
                    878: int GenFractal_00(char *img_name, double alpha,
                    879:                                   double beta,
                    880:                                   int    itermax,
                    881:                                   double side_len,
                    882:                                   double offset_x,
                    883:                                   double offset_y)
                    884: {
                    885: png_colorpp image = NULL;
                    886: png_text    info_text[NUM_TEXT];
                    887: int         status;
                    888: 
                    889: /*******************************************************************************
                    890: +* Parámetros de tamaño para la imagen. Reserva de memoria para ella.
                    891: *******************************************************************************/
                    892:    SetSide(side_len);
                    893:    SetOffsetX(offset_x);
                    894:    SetOffsetY(offset_y);
                    895: 
                    896:    if (!(image = AllocatePNG(NUM_ROWS, NUM_COLS)))
                    897:       return ERROR;
                    898: 
                    899:    BuildTextPtr(info_text, alpha, beta, itermax, side_len, offset_x, offset_y);
                    900: 
                    901: /*******************************************************************************
                    902: +* Definición de la forma cuadrática.
                    903: *******************************************************************************/
                    904:    a1 = 0.0;
                    905:    b1 = 1.0;
                    906:    c1 = 0.0;
                    907:    a2 = 1.0;
                    908:    b2 = 0.0;
                    909:    c2 = -1.0;
                    910: 
                    911: /*******************************************************************************
                    912: +* Chequeo de condiciones sobre alpha y beta. Setting de zona.
                    913: *******************************************************************************/
                    914:    if (alpha != 0.0  ||  beta != 0.0)   /* Alfa y Beta han de ser cero. */
                    915:       return ERROR;
                    916: 
                    917:    zona = ZONA_00;
                    918: 
                    919: /*******************************************************************************
                    920: +* Cálculo del mínimo de A, según valores de b1, c1 y zonas.
                    921: *******************************************************************************/
                    922:    minA = 1.;
                    923:    if (zona == ZONA_00)
                    924:    {
                    925:       minA = 1.;
                    926:    }
                    927:    else
                    928:    {
                    929:       fprintf(stderr, "#ERROR: Zona no implementada.\n");
                    930:       return ERROR;
                    931:    }
                    932: 
                    933: /*******************************************************************************
                    934: +* Computación y generación de la imagen.
                    935: *******************************************************************************/
                    936:    IterComputation(image, itermax);
                    937:    status = WritePNG(img_name, image, info_text, NUM_TEXT);
                    938:    DeallocatePNG(image, NUM_ROWS, NUM_COLS);
                    939:    return status;
                    940: }
                    941: 
                    942: /*******************************************************************************
                    943: +* GenFractalEspecial1
                    944: +* Genera la imagen para F^+_c cuando c = 0.
                    945: *******************************************************************************/
                    946: int GenFractalEspecial1(char *img_name, double alpha,
                    947:                                         double beta,
                    948:                                         int    itermax,
                    949:                                         double side_len,
                    950:                                         double offset_x,
                    951:                                         double offset_y)
                    952: {
                    953: png_colorpp image = NULL;
                    954: png_text    info_text[NUM_TEXT];
                    955: int         status;
                    956: 
                    957: /*******************************************************************************
                    958: +* Parámetros de tamaño para la imagen. Reserva de memoria para ella.
                    959: *******************************************************************************/
                    960:    SetSide(side_len);
                    961:    SetOffsetX(offset_x);
                    962:    SetOffsetY(offset_y);
                    963: 
                    964:    if (!(image = AllocatePNG(NUM_ROWS, NUM_COLS)))
                    965:       return ERROR;
                    966: 
                    967:    BuildTextPtr(info_text, alpha, beta, itermax, side_len, offset_x, offset_y);
                    968: 
                    969: /*******************************************************************************
                    970: +* Definición de la forma cuadrática.
                    971: *******************************************************************************/
                    972:    a1 = 0.0;
                    973:    b1 = 1.0;
                    974:    c1 = 0.0;
                    975:    a2 = 1.0;
                    976:    b2 = 0.0;
                    977:    c2 = 0.0;
                    978: 
                    979:    IterComputationEspecial(image, itermax, 20.0);
                    980:    status = WritePNG(img_name, image, info_text, NUM_TEXT);
                    981:    DeallocatePNG(image, NUM_ROWS, NUM_COLS);
                    982:    return status;
                    983: }
                    984: 
                    985: /*******************************************************************************
                    986: +* GenFractalEspecial2
                    987: +* Genera la imagen para F^-_c cuando c = 0.
                    988: *******************************************************************************/
                    989: int GenFractalEspecial2(char *img_name, double alpha,
                    990:                                         double beta,
                    991:                                         int    itermax,
                    992:                                         double side_len,
                    993:                                         double offset_x,
                    994:                                         double offset_y)
                    995: {
                    996: png_colorpp image = NULL;
                    997: png_text    info_text[NUM_TEXT];
                    998: int         status;
                    999: 
                   1000: /*******************************************************************************
                   1001: +* Parámetros de tamaño para la imagen. Reserva de memoria para ella.
                   1002: *******************************************************************************/
                   1003:    SetSide(side_len);
                   1004:    SetOffsetX(offset_x);
                   1005:    SetOffsetY(offset_y);
                   1006: 
                   1007:    if (!(image = AllocatePNG(NUM_ROWS, NUM_COLS)))
                   1008:       return ERROR;
                   1009: 
                   1010:    BuildTextPtr(info_text, alpha, beta, itermax, side_len, offset_x, offset_y);
                   1011: 
                   1012: /*******************************************************************************
                   1013: +* Definición de la forma cuadrática.
                   1014: *******************************************************************************/
                   1015:    a1 = 0.0;
                   1016:    b1 = -1.0;
                   1017:    c1 = 0.0;
                   1018:    a2 = 1.0;
                   1019:    b2 = 0.0;
                   1020:    c2 = 0.0;
                   1021: 
                   1022:    IterComputationEspecial(image, itermax, 20.0);
                   1023:    status = WritePNG(img_name, image, info_text, NUM_TEXT);
                   1024:    DeallocatePNG(image, NUM_ROWS, NUM_COLS);
                   1025:    return status;
                   1026: }
                   1027: 
                   1028: /*******************************************************************************
                   1029: +* GenFractalEspecial3
                   1030: +* Genera la imagen para G^_c cuando c = 0.
                   1031: *******************************************************************************/
                   1032: int GenFractalEspecial3(char *img_name, double alpha,
                   1033:                                         double beta,
                   1034:                                         int    itermax,
                   1035:                                         double side_len,
                   1036:                                         double offset_x,
                   1037:                                         double offset_y)
                   1038: {
                   1039: png_colorpp image = NULL;
                   1040: png_text    info_text[NUM_TEXT];
                   1041: int         status;
                   1042: 
                   1043: /*******************************************************************************
                   1044: +* Parámetros de tamaño para la imagen. Reserva de memoria para ella.
                   1045: *******************************************************************************/
                   1046:    SetSide(side_len);
                   1047:    SetOffsetX(offset_x);
                   1048:    SetOffsetY(offset_y);
                   1049: 
                   1050:    if (!(image = AllocatePNG(NUM_ROWS, NUM_COLS)))
                   1051:       return ERROR;
                   1052: 
                   1053:    BuildTextPtr(info_text, alpha, beta, itermax, side_len, offset_x, offset_y);
                   1054: 
                   1055: /*******************************************************************************
                   1056: +* Definición de la forma cuadrática.
                   1057: *******************************************************************************/
                   1058:    a1 = 1.0;
                   1059:    b1 = 1.0;
                   1060:    c1 = 0.0;
                   1061:    a2 = 0.0;
                   1062:    b2 = -1.0;
                   1063:    c2 = 0.0;
                   1064: 
                   1065:    IterComputationEspecial(image, itermax, 20.0);
                   1066:    status = WritePNG(img_name, image, info_text, NUM_TEXT);
                   1067:    DeallocatePNG(image, NUM_ROWS, NUM_COLS);
                   1068:    return status;
                   1069: }
                   1070: 
                   1071: /*******************************************************************************
                   1072: +* GenFractalEspecial5
                   1073: +* Genera el caso F^+_{00}
                   1074: *******************************************************************************/
                   1075: int GenFractalEspecial5(char *img_name, double alpha,
                   1076:                                         double beta,
                   1077:                                         int    itermax,
                   1078:                                         double side_len,
                   1079:                                         double offset_x,
                   1080:                                         double offset_y)
                   1081: {
                   1082: png_colorpp image = NULL;
                   1083: png_text    info_text[NUM_TEXT];
                   1084: int         status;
                   1085: 
                   1086: /*******************************************************************************
                   1087: +* Parámetros de tamaño para la imagen. Reserva de memoria para ella.
                   1088: *******************************************************************************/
                   1089:    SetSide(side_len);
                   1090:    SetOffsetX(offset_x);
                   1091:    SetOffsetY(offset_y);
                   1092: 
                   1093:    if (!(image = AllocatePNG(NUM_ROWS, NUM_COLS)))
                   1094:       return ERROR;
                   1095: 
                   1096:    BuildTextPtr(info_text, alpha, beta, itermax, side_len, offset_x, offset_y);
                   1097: 
                   1098: /*******************************************************************************
                   1099: +* Definición de la forma cuadrática.
                   1100: *******************************************************************************/
                   1101:    a1 = 0.0;
                   1102:    b1 = 0.0;
                   1103:    c1 = 0.0;
                   1104:    a2 = 1.0;
                   1105:    b2 = 0.0;
                   1106:    c2 = -1.0;
                   1107: 
                   1108:    IterComputationEspecial(image, itermax, 40.0);
                   1109:    status = WritePNG(img_name, image, info_text, NUM_TEXT);
                   1110:    DeallocatePNG(image, NUM_ROWS, NUM_COLS);
                   1111:    return status;
                   1112: }
                   1113: 
                   1114: /*******************************************************************************
                   1115: +* GenFractalEspecial6
                   1116: +* Genera el caso F^-_{00}
                   1117: *******************************************************************************/
                   1118: int GenFractalEspecial6(char *img_name, double alpha,
                   1119:                                         double beta,
                   1120:                                         int    itermax,
                   1121:                                         double side_len,
                   1122:                                         double offset_x,
                   1123:                                         double offset_y)
                   1124: {
                   1125: png_colorpp image = NULL;
                   1126: png_text    info_text[NUM_TEXT];
                   1127: int         status;
                   1128: 
                   1129: /*******************************************************************************
                   1130: +* Parámetros de tamaño para la imagen. Reserva de memoria para ella.
                   1131: *******************************************************************************/
                   1132:    SetSide(side_len);
                   1133:    SetOffsetX(offset_x);
                   1134:    SetOffsetY(offset_y);
                   1135: 
                   1136:    if (!(image = AllocatePNG(NUM_ROWS, NUM_COLS)))
                   1137:       return ERROR;
                   1138: 
                   1139:    BuildTextPtr(info_text, alpha, beta, itermax, side_len, offset_x, offset_y);
                   1140: 
                   1141: /*******************************************************************************
                   1142: +* Definición de la forma cuadrática.
                   1143: *******************************************************************************/
                   1144:    a1 = 0.0;
                   1145:    b1 = 0.0;
                   1146:    c1 = 0.0;
                   1147:    a2 = 1.0;
                   1148:    b2 = 0.0;
                   1149:    c2 = 1.0;
                   1150: 
                   1151:    IterComputationEspecial(image, itermax, 40.0);
                   1152:    status = WritePNG(img_name, image, info_text, NUM_TEXT);
                   1153:    DeallocatePNG(image, NUM_ROWS, NUM_COLS);
                   1154:    return status;
                   1155: }
                   1156: 
                   1157: /*******************************************************************************
                   1158: +* GenFractalEspecial7
                   1159: +* Genera el caso F^+_{bc} cuando $c=\pm 2b$
                   1160: *******************************************************************************/
                   1161: int GenFractalEspecial7(char *img_name, double alpha,
                   1162:                                         double beta,
                   1163:                                         int    itermax,
                   1164:                                         double side_len,
                   1165:                                         double offset_x,
                   1166:                                         double offset_y)
                   1167: {
                   1168: png_colorpp image = NULL;
                   1169: png_text    info_text[NUM_TEXT];
                   1170: int         status;
                   1171: 
                   1172: /*******************************************************************************
                   1173: +* Parámetros de tamaño para la imagen. Reserva de memoria para ella.
                   1174: *******************************************************************************/
                   1175:    SetSide(side_len);
                   1176:    SetOffsetX(offset_x);
                   1177:    SetOffsetY(offset_y);
                   1178: 
                   1179:    if (!(image = AllocatePNG(NUM_ROWS, NUM_COLS)))
                   1180:       return ERROR;
                   1181: 
                   1182:    BuildTextPtr(info_text, alpha, beta, itermax, side_len, offset_x, offset_y);
                   1183: 
                   1184: /*******************************************************************************
                   1185: +* Definición de la forma cuadrática.
                   1186: +* Parte fija:
                   1187: *******************************************************************************/
                   1188:    a1 = 0.0;
                   1189:    a2 = 1.0;
                   1190:    b2 = 0.0;
                   1191:    c2 = -1.0;
                   1192:    b1 = beta;
                   1193:    c1 = 2*beta;
                   1194: 
                   1195: /*******************************************************************************
                   1196: +* Computación y generación de la imagen.
                   1197: *******************************************************************************/
                   1198:    IterComputationEspecial(image, itermax, 40.0);
                   1199:    status = WritePNG(img_name, image, info_text, NUM_TEXT);
                   1200:    DeallocatePNG(image, NUM_ROWS, NUM_COLS);
                   1201:    return status;
                   1202: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>