Point-Zoom on Mandelbrot Set in C# - It works, except when the mouse has moved -


i'm able point zoom on mandelbrot set, long mouse doesn't move after zooming has begun. i've tried calculating normalized delta (new coordinate - old coordinate)*(oldzoom), happens image appears jump around new location. i've seen issue before. i'm struggling more here because have somehow convert mouse position delta -2,2 coordinate space of mandelbrot set.

here's code. what's important getzoompoint method, , lines of code define x0 , y0. also, use range class scale values 1 range another. was using deltatrans (thats thing talking earlier normalize mouse delta old scale).

using opentk.graphics.opengl; using spritesheetmaker; using system; using system.collections.generic; using system.drawing; using system.linq; using system.text; using system.threading.tasks;   namespace fractal.fractal {     public class mandelbrot : basetexture     {         private static transform globaltransform = spritesheetmaker.global.transform;         private static vector3 globalscale = globaltransform.scale;         private static vector3 globaltrans = globaltransform.translation;         private static vector3 lastwindowpoint = null;         private static vector3 zoomfactor = vector3.one * 1.2f;         private static vector3 displacement = vector3.zero;         private static int windowsize = 100;          public static vector3 getzoompoint()         {               var zp = openglhelpers.lastzoompoint.clone();             if (lastwindowpoint == null)             {                 lastwindowpoint = zp.clone();             }             var delta = zp - lastwindowpoint;             var oldzoom = globalscale / zoomfactor;             var deltatrans = delta.xy * oldzoom.xy;             var factor = zoomfactor.clone();              range xr = new range(0, windowsize);             range yr = new range(0, windowsize);             range complexrange = new range(-2, 2);              // calculate displacement of zooming position.             var dx = (zp.x - displacement.x) * (factor.x - 1f);             var dy = (zp.y - displacement.y) * (factor.y - 1f);             // compensate displacement.             displacement.x -= dx;             displacement.y -= dy;              zp -= displacement;             var x = complexrange.scalevalue(zp.x, xr);             var y = complexrange.scalevalue(zp.y, yr);              var rtn = new vector3(x, y);              lastwindowpoint = zp.clone();              return rtn;         }         public static mandelbrot generate()         {             var size = new size(windowsize, windowsize);             var radius = new size(size.width / 2, size.height / 2);              bitmap bmp = new bitmap(size.width, size.height);             lockbitmap.lockbitmapunsafe lbm = new lockbitmap.lockbitmapunsafe(bmp);             lbm.lockbits();               var pt = mandelbrot.getzoompoint();             parallel.for(0, size.width, =>             {                 //  float x0 = complexrangex.scalevalue(i, xrange);                 float x0 = ((i - radius.width) / globalscale.x) + pt.x;                  parallel.for(0, size.height, j =>                  {                      // float y0 = complexrangey.scalevalue(j, yrange);                      float y0 = ((j - radius.height) / globalscale.y) + pt.y;                      float value = 0f;                      float x = 0.0f;                      float y = 0.0f;                      int iteration = 0;                      int max_iteration = 100;                      while (x * x + y * y <= 4.0 && iteration < max_iteration)                      {                          float xtemp = x * x - y * y + x0;                          y = 2.0f * x * y + y0;                          x = xtemp;                          iteration += 1;                          if (iteration == max_iteration)                          {                              value = 255;                              break;                          }                          else                          {                              value = iteration * 50f % 255f;                          }                      }                       int v = (int)value;                      lbm.setpixel(i, j, new colorlibrary.hsl(v / 255f, 1.0, 0.5).todotnetcolor());                  });             });             lbm.unlockbits();             var tex = new basetextureimage(bmp);             var rtn = new mandelbrot(tex);             return rtn;         }          public override void draw()         {             base._draw();         }         private mandelbrot(basetextureimage graphic)         {             var topleft = new vector3(0, 1);             var bottomleft = new vector3(0, 0);             var bottomright = new vector3(1, 0);             var topright = new vector3(1, 1);             this.vertices = new list<vector3>()             {                 topleft,bottomleft,bottomright,topright             };             this.size.x = windowsize;             this.size.y = windowsize;             this.texture2d = graphic;         }     } } 

i refactored code, , figured out solution problem. 2 big wins in one. ok, found solution on codeproject written in c# readily able adapt project. i'm not sure why didn't realize when posted question, needed solve issue create 'window' of zoom , not think in terms of 'point zoom'. yes, if trying zoom directly point, point center of sort of window.

here method have, expects start , end mousedown coordinates (screen space), , converts mandelbrot set window size accordingly.

    public void applyzoom(double x0, double y0, double x1, double y1)     {         if (x1 == x0 && y0 == y1)         {             //this click, no movement occurred             return;         }          /*             * xmin, ymin , xmax, ymax current extent of set             * mx0,my0 , mx1,my1 part selected             * math draw selected rectangle             * */         double scalex, scaley;          scalex = (xmax - xmin) / (float)bitmapsize;         scaley = (ymax - ymin) / (float)bitmapsize;         xmax = (float)x1 * scalex + xmin;         ymax = (float)y1 * scaley + ymin;         xmin = (float)x0 * scalex + xmin;         ymin = (float)y0 * scaley + ymin;          this.refresh(); // force mandelbrot redraw      } 

basically, whats happening calculate ratio between mandelbrot window size versus screen size drawing to. then, using scale, convert our mousedown coordinates mandelbrot set coordinates (x1*scalex, etc) , manipulate current min , max coordinates them, using min values pivot point.

here's link codeproject used reference: codeproject link


Comments

Popular posts from this blog

java - nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet Hibernate+SpringMVC -

sql - Postgresql tables exists, but getting "relation does not exist" when querying -

asp.net mvc - breakpoint on javascript in CSHTML? -