📄 ifs.c
字号:
/* * ifs.c --- modified iterated functions system for goom. *//*- * Copyright (c) 1997 by Massimino Pascal <Pascal.Massimon@ens.fr> * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * * If this mode is weird and you have an old MetroX server, it is buggy. * There is a free SuSE-enhanced MetroX X server that is fine. * * When shown ifs, Diana Rose (4 years old) said, "It looks like dancing." * * Revision History: * 13-Dec-2003: Added some goom specific stuffs (to make ifs a VisualFX). * 11-Apr-2002: jeko@ios-software.com: Make ifs.c system-indendant. (ifs.h added) * 01-Nov-2000: Allocation checks * 10-May-1997: jwz@jwz.org: turned into a standalone program. * Made it render into an offscreen bitmap and then copy * that onto the screen, to reduce flicker. *//* #ifdef STANDALONE */#include <math.h>#include <stdlib.h>#include <stdio.h>#include "goom_config.h"#ifdef HAVE_MMX#include "mmx.h"#endif#include "goom_graphic.h"#include "ifs.h"#include "goom_tools.h"typedef struct _ifsPoint{ gint32 x, y;}IFSPoint;#define MODE_ifs#define PROGCLASS "IFS"#define HACK_INIT init_ifs#define HACK_DRAW draw_ifs#define ifs_opts xlockmore_opts#define DEFAULTS "*delay: 20000 \n" \"*ncolors: 100 \n"#define SMOOTH_COLORS#define LRAND() ((long) (goom_random(goomInfo->gRandom) & 0x7fffffff))#define NRAND(n) ((int) (LRAND() % (n)))#if RAND_MAX < 0x10000#define MAXRAND (((float)(RAND_MAX<16)+((float)RAND_MAX)+1.0f)/127.0f)#else#define MAXRAND (2147483648.0/127.0) /* unsigned 1<<31 / 127.0 (cf goom_tools) as a float */#endif/*****************************************************/typedef float DBL;typedef int F_PT;/* typedef float F_PT; *//*****************************************************/#define FIX 12#define UNIT ( 1<<FIX )#define MAX_SIMI 6#define MAX_DEPTH_2 10#define MAX_DEPTH_3 6#define MAX_DEPTH_4 4#define MAX_DEPTH_5 2/* PREVIOUS VALUE #define MAX_SIMI 6 * settings for a PC 120Mhz... *#define MAX_DEPTH_2 10#define MAX_DEPTH_3 6#define MAX_DEPTH_4 4#define MAX_DEPTH_5 3*/#define DBL_To_F_PT(x) (F_PT)( (DBL)(UNIT)*(x) )typedef struct Similitude_Struct SIMI;typedef struct Fractal_Struct FRACTAL;struct Similitude_Struct{ DBL c_x, c_y; DBL r, r2, A, A2; F_PT Ct, St, Ct2, St2; F_PT Cx, Cy; F_PT R, R2;};struct Fractal_Struct{ int Nb_Simi; SIMI Components[5 * MAX_SIMI]; int Depth, Col; int Count, Speed; int Width, Height, Lx, Ly; DBL r_mean, dr_mean, dr2_mean; int Cur_Pt, Max_Pt; IFSPoint *Buffer1, *Buffer2;};typedef struct _IFS_DATA { FRACTAL *Root; FRACTAL *Cur_F; /* Used by the Trace recursive method */ IFSPoint *Buf; int Cur_Pt; int initalized;} IfsData;/*****************************************************/static DBLGauss_Rand (PluginInfo *goomInfo, DBL c, DBL A, DBL S){ DBL y; y = (DBL) LRAND () / MAXRAND; y = A * (1.0 - exp (-y * y * S)) / (1.0 - exp (-S)); if (NRAND (2)) return (c + y); return (c - y);}static DBLHalf_Gauss_Rand (PluginInfo *goomInfo, DBL c, DBL A, DBL S){ DBL y; y = (DBL) LRAND () / MAXRAND; y = A * (1.0 - exp (-y * y * S)) / (1.0 - exp (-S)); return (c + y);}static voidRandom_Simis (PluginInfo *goomInfo, FRACTAL * F, SIMI * Cur, int i){ while (i--) { Cur->c_x = Gauss_Rand (goomInfo, 0.0, .8, 4.0); Cur->c_y = Gauss_Rand (goomInfo, 0.0, .8, 4.0); Cur->r = Gauss_Rand (goomInfo, F->r_mean, F->dr_mean, 3.0); Cur->r2 = Half_Gauss_Rand (goomInfo, 0.0, F->dr2_mean, 2.0); Cur->A = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (M_PI / 180.0); Cur->A2 = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (M_PI / 180.0); Cur++; }}static voidfree_ifs_buffers (FRACTAL * Fractal){ if (Fractal->Buffer1 != NULL) { (void) free ((void *) Fractal->Buffer1); Fractal->Buffer1 = (IFSPoint *) NULL; } if (Fractal->Buffer2 != NULL) { (void) free ((void *) Fractal->Buffer2); Fractal->Buffer2 = (IFSPoint *) NULL; }}static voidfree_ifs (FRACTAL * Fractal){ free_ifs_buffers (Fractal);}/***************************************************************/static voidinit_ifs (PluginInfo *goomInfo, IfsData *data){ int i; FRACTAL *Fractal; int width = goomInfo->screen.width; int height = goomInfo->screen.height; if (data->Root == NULL) { data->Root = (FRACTAL *) malloc (sizeof (FRACTAL)); if (data->Root == NULL) return; data->Root->Buffer1 = (IFSPoint *) NULL; data->Root->Buffer2 = (IFSPoint *) NULL; } Fractal = data->Root; free_ifs_buffers (Fractal); i = (NRAND (4)) + 2; /* Number of centers */ switch (i) { case 3: Fractal->Depth = MAX_DEPTH_3; Fractal->r_mean = .6; Fractal->dr_mean = .4; Fractal->dr2_mean = .3; break; case 4: Fractal->Depth = MAX_DEPTH_4; Fractal->r_mean = .5; Fractal->dr_mean = .4; Fractal->dr2_mean = .3; break; case 5: Fractal->Depth = MAX_DEPTH_5; Fractal->r_mean = .5; Fractal->dr_mean = .4; Fractal->dr2_mean = .3; break; default: case 2: Fractal->Depth = MAX_DEPTH_2; Fractal->r_mean = .7; Fractal->dr_mean = .3; Fractal->dr2_mean = .4; break; } Fractal->Nb_Simi = i; Fractal->Max_Pt = Fractal->Nb_Simi - 1; for (i = 0; i <= Fractal->Depth + 2; ++i) Fractal->Max_Pt *= Fractal->Nb_Simi; if ((Fractal->Buffer1 = (IFSPoint *) calloc (Fractal->Max_Pt, sizeof (IFSPoint))) == NULL) { free_ifs (Fractal); return; } if ((Fractal->Buffer2 = (IFSPoint *) calloc (Fractal->Max_Pt, sizeof (IFSPoint))) == NULL) { free_ifs (Fractal); return; } Fractal->Speed = 6; Fractal->Width = width; /* modif by JeKo */ Fractal->Height = height; /* modif by JeKo */ Fractal->Cur_Pt = 0; Fractal->Count = 0; Fractal->Lx = (Fractal->Width - 1) / 2; Fractal->Ly = (Fractal->Height - 1) / 2; Fractal->Col = rand () % (width * height); /* modif by JeKo */ Random_Simis (goomInfo, Fractal, Fractal->Components, 5 * MAX_SIMI);}/***************************************************************/static inline voidTransform (SIMI * Simi, F_PT xo, F_PT yo, F_PT * x, F_PT * y){ F_PT xx, yy; xo = xo - Simi->Cx; xo = (xo * Simi->R) >> FIX; /* / UNIT; */ yo = yo - Simi->Cy; yo = (yo * Simi->R) >> FIX; /* / UNIT; */ xx = xo - Simi->Cx; xx = (xx * Simi->R2) >> FIX; /* / UNIT; */ yy = -yo - Simi->Cy; yy = (yy * Simi->R2) >> FIX; /* / UNIT; */ *x = ((xo * Simi->Ct - yo * Simi->St + xx * Simi->Ct2 - yy * Simi->St2) >> FIX /* / UNIT */ ) + Simi->Cx; *y = ((xo * Simi->St + yo * Simi->Ct + xx * Simi->St2 + yy * Simi->Ct2) >> FIX /* / UNIT */ ) + Simi->Cy;}/***************************************************************/static voidTrace (FRACTAL * F, F_PT xo, F_PT yo, IfsData *data){ F_PT x, y, i; SIMI *Cur; Cur = data->Cur_F->Components; for (i = data->Cur_F->Nb_Simi; i; --i, Cur++) { Transform (Cur, xo, yo, &x, &y); data->Buf->x = F->Lx + ((x * F->Lx) >> (FIX+1) /* /(UNIT*2) */ ); data->Buf->y = F->Ly - ((y * F->Ly) >> (FIX+1) /* /(UNIT*2) */ ); data->Buf++; data->Cur_Pt++; if (F->Depth && ((x - xo) >> 4) && ((y - yo) >> 4)) { F->Depth--; Trace (F, x, y, data); F->Depth++; } }}static voidDraw_Fractal (IfsData *data){ FRACTAL *F = data->Root; int i, j; F_PT x, y, xo, yo; SIMI *Cur, *Simi; for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) { Cur->Cx = DBL_To_F_PT (Cur->c_x); Cur->Cy = DBL_To_F_PT (Cur->c_y); Cur->Ct = DBL_To_F_PT (cos (Cur->A)); Cur->St = DBL_To_F_PT (sin (Cur->A)); Cur->Ct2 = DBL_To_F_PT (cos (Cur->A2)); Cur->St2 = DBL_To_F_PT (sin (Cur->A2)); Cur->R = DBL_To_F_PT (Cur->r); Cur->R2 = DBL_To_F_PT (Cur->r2); } data->Cur_Pt = 0; data->Cur_F = F; data->Buf = F->Buffer2; for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) { xo = Cur->Cx; yo = Cur->Cy; for (Simi = F->Components, j = F->Nb_Simi; j; --j, Simi++) { if (Simi == Cur) continue; Transform (Simi, xo, yo, &x, &y); Trace (F, x, y, data); } } /* Erase previous */ F->Cur_Pt = data->Cur_Pt; data->Buf = F->Buffer1; F->Buffer1 = F->Buffer2; F->Buffer2 = data->Buf;}static IFSPoint *draw_ifs (PluginInfo *goomInfo, int *nbpt, IfsData *data){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -