00001
00002 namespace NewGamePhysics.GraphicalElements
00003 {
00004 using System;
00005 using Microsoft.Xna.Framework;
00006 using Microsoft.Xna.Framework.Graphics;
00007
00012 public class GumowskiMiraFractal
00013 {
00017 private GraphicsDevice graphicsDevice;
00018
00022 private int width;
00023
00027 private int height;
00028
00032 private byte[] imageBuffer;
00033
00037 private Texture2D imageTexture;
00038
00042 private double a;
00043
00047 private double mu;
00048
00052 private double x;
00053
00057 private double y;
00058
00062 private UInt32 iterations;
00063
00067 private float scale = 0.02f;
00068
00072 private Vector2 center = new Vector2();
00073
00077 private float fw;
00078
00082 private float fh;
00083
00087 private float fwh;
00088
00092 private float fhh;
00093
00097 private double oldX1;
00098
00102 private double oldY1;
00103
00114 public GumowskiMiraFractal(GraphicsDevice graphicsDevice, int width, int height, double a, double mu, double x1, double y1)
00115 {
00116
00117 this.graphicsDevice = graphicsDevice;
00118 this.width = width;
00119 this.height = height;
00120 this.fw = (float)width;
00121 this.fwh = this.fw / 2.0f;
00122 this.fh = (float)height;
00123 this.fhh = this.fh / 2.0f;
00124 this.a = a;
00125 this.mu = mu;
00126
00127
00128 this.Reset(x1, y1);
00129 }
00130
00134 public int Width
00135 {
00136 get { return this.width; }
00137 }
00138
00142 public int Height
00143 {
00144 get { return this.height; }
00145 }
00146
00150 public double A
00151 {
00152 get { return this.a; }
00153 set { this.a = value; }
00154 }
00155
00159 public double Mu
00160 {
00161 get { return this.mu; }
00162 set { this.mu = value; }
00163 }
00164
00168 public Texture2D ImageTexture
00169 {
00170 get { return this.imageTexture; }
00171 }
00172
00176 public Vector2 Center
00177 {
00178 get { return this.center; }
00179 set { this.center = value; }
00180 }
00181
00185 public float Scale
00186 {
00187 get { return this.scale; }
00188 set { this.scale = value; }
00189 }
00190
00194 public UInt32 Iterations
00195 {
00196 get { return this.iterations; }
00197 }
00198
00202 public void Reset()
00203 {
00204 this.Reset(this.oldX1, this.oldY1);
00205 }
00206
00212 public void Reset(double x1, double y1)
00213 {
00214
00215 this.oldX1 = x1;
00216 this.oldY1 = y1;
00217 this.x = x1;
00218 this.y = y1;
00219
00220
00221 this.iterations = 0;
00222
00223
00224 int imageSize = width * height;
00225 this.imageBuffer = new byte[imageSize];
00226
00227
00228 this.imageTexture = new Texture2D(
00229 graphicsDevice,
00230 width,
00231 height,
00232 1,
00233 TextureUsage.None,
00234 SurfaceFormat.Luminance8);
00235
00236
00237 this.imageTexture.SetData(this.imageBuffer);
00238 }
00239
00245 public void Iterate(int steps)
00246 {
00247 double mup = 2.0 * (1.0 - this.mu);
00248 for (int i = 0; i < steps; i++)
00249 {
00250
00251 double xx = this.x * this.x;
00252 double fxn = this.mu * this.x + (mup * xx) / (1.0 + xx);
00253 double xnp1 = this.y + this.a * (1.0 - 0.05 * this.y * this.y) * this.y + fxn;
00254 double xnp1xnp1 = xnp1*xnp1;
00255 double fxnp1 = this.mu * xnp1 + (mup * xnp1xnp1) / (1.0 + xnp1xnp1);
00256 double ynp1 = -this.x + fxnp1;
00257 this.x = xnp1;
00258 this.y = ynp1;
00259 this.iterations++;
00260
00261
00262 this.PutPixel(xnp1, ynp1, 1);
00263 }
00264
00265
00266 this.imageTexture = new Texture2D(
00267 this.graphicsDevice,
00268 this.width,
00269 this.height,
00270 1,
00271 TextureUsage.None,
00272 SurfaceFormat.Luminance8);
00273
00274
00275 this.imageTexture.SetData(this.imageBuffer);
00276 }
00277
00284 private void PutPixel(double x, double y, byte luminance)
00285 {
00286
00287 float bx = (((float)x - this.center.X) * this.scale) * this.fw + this.fwh;
00288 float by = (((float)y - this.center.Y) * this.scale) * this.fw + this.fhh;
00289 if ((bx >= 0.0f) && (bx < this.fw) && (by >= 0.0f) && (by < this.fh))
00290 {
00291 int offset = (int)bx + this.width * (int)by;
00292 this.imageBuffer[offset] += luminance;
00293 }
00294 }
00295 }
00296 }