예제 #1
0
 public void LoadAsync(IFractal fractal, Bounds bounds)
 {
     BackgroundWorker worker = new BackgroundWorker();
     worker.DoWork += RunFractalLoad;
     IsLoading = true;
     worker.RunWorkerAsync(new AsyncLoadArgs { Bounds = bounds, Fractal = fractal, Renderer = renderer });
 }
예제 #2
0
 /// <summary>Precomputed values used during the rendering to speed up calculations.</summary>
 private void PrecomputeValues(IFractal fractal, Bounds bounds)
 {
     xIncrement = bounds.Width / width;
     yIncrement = bounds.Height / height;
     minBoundsX = bounds.X.MinValue;
     minBoundsY = bounds.Y.MinValue;
 }
예제 #3
0
        /// <summary>Processes a fractal, computing its values, returning a RenderedFractal.</summary>
        public RenderedFractal Process(IFractal fractal, Bounds boundsToRender, Dimensions imageDimensions)
        {
            width = imageDimensions.Width;
            height = imageDimensions.Height;

            PrecomputeValues(fractal, boundsToRender);

            var buffer = new float[width * height];

            Parallel.For(0, height, y =>
            {
                Parallel.For(0, width, x =>
                {
                    SetPoint(buffer, fractal, x, y);
                });
            });

            return new RenderedFractal(buffer, fractal.MaxIterations, boundsToRender, fractal);
        }
예제 #4
0
        /// <summary>Action to call when the mouse releases on the correct canvas.</summary>
        public void MouseUp(MouseEventArgs e, Canvas boundingBoxCanvas)
        {
            if (!isDrawing)
                return;
            isDrawing = false;
            if (boundingBox == null)
                return;

            boundingBoxCanvas.Children.Remove(boundingBox);

            var screenBounds = new Bounds(
                new Bound(Canvas.GetLeft(boundingBox), Canvas.GetLeft(boundingBox) + boundingBox.Width),
                new Bound(Canvas.GetTop(boundingBox), Canvas.GetTop(boundingBox) + boundingBox.Height));

            if (BoxReleased != null)
                BoxReleased(screenBounds);

            boundingBox = null;
        }
예제 #5
0
        /// <summary>Transforms the Bounds of the screen in to Bounds on the surface of the fractal.</summary>
        public Bounds GetFractalBounds(Bounds screenBounds)
        {
            var percentageBounds = new Bounds(
                new Bound(
                    screenBounds.X.MinValue / ImageProvider.Dimensions.Width,
                    screenBounds.X.MaxValue / ImageProvider.Dimensions.Width),
                new Bound(
                    screenBounds.Y.MinValue / ImageProvider.Dimensions.Height,
                    screenBounds.Y.MaxValue / ImageProvider.Dimensions.Height)
                );

            var newBounds = new Bounds(
                new Bound(
                    InternalLastRenderedBounds.X.MinValue + (InternalLastRenderedBounds.Width * percentageBounds.X.MinValue),
                    InternalLastRenderedBounds.X.MinValue + (InternalLastRenderedBounds.Width * percentageBounds.X.MaxValue)),
                new Bound(
                    InternalLastRenderedBounds.Y.MinValue + (InternalLastRenderedBounds.Height * percentageBounds.Y.MinValue),
                    InternalLastRenderedBounds.Y.MinValue + (InternalLastRenderedBounds.Height * percentageBounds.Y.MaxValue)));

            return newBounds;
        }
예제 #6
0
 /// <summary>Creates a new RenderedFractal with the data of the fractal.</summary>
 public RenderedFractal(float[] data, int maxIterations, Bounds bounds, IFractal fractal)
     : this(data, maxIterations)
 {
     Bounds = bounds;
     Fractal = fractal;
 }
예제 #7
0
 /// <summary>Renders the fractal with the specified bounds, optionally ignoring pushing the bounds on to the history stack.</summary>
 private void RenderNew(Bounds bounds, bool ignoreHistory)
 {
     AsyncLoader.OnFinished += fractal => {
         if(!ignoreHistory)
             History.Push(fractal);
         SetImageDispatch(fractal);
     };
     AsyncLoader.PostFinish += fractal => PostRender(fractal);
     AsyncLoader.LoadAsync(SelectedFractal, bounds);
 }
예제 #8
0
 /// <summary>Renders the fractal with the specified bounds, pushing the render on to the history stack.</summary>
 private void RenderNew(Bounds bounds)
 {
     RenderNew(bounds, false);
 }
예제 #9
0
 /// <summary>Loads a fractal to the specified bounds, converting from bounds obtained from screen units.</summary>
 public void LoadFractalFromScreenBounds(Bounds screenBounds)
 {
     var fractalBounds = renderer.GetFractalBounds(screenBounds);
     RenderNew(fractalBounds);
 }
예제 #10
0
        /// <summary>
        /// Resizes the Bounds to match the aspect ratio of the iamge to be rendered. 
        /// Prevents distorted images.
        /// </summary>
        private Bounds GetResizedBounds(Bounds areaToRender)
        {
            var realImageRatio = ImageProvider.Dimensions.Width / ImageProvider.Dimensions.Height;
            var desiredRatio = areaToRender.Width / areaToRender.Height;
            Bounds newBounds;

            if (realImageRatio < desiredRatio)
            {
                var additionalHeight = (ImageProvider.Dimensions.Height * areaToRender.Width) / ImageProvider.Dimensions.Width - areaToRender.Height;
                var amount = additionalHeight / 2;
                newBounds = new Bounds(areaToRender.X, new Bound(areaToRender.Y.MinValue - amount, areaToRender.Y.MaxValue + amount));
            }
            else
            {
                var additionalWidth = (ImageProvider.Dimensions.Width * areaToRender.Height) / ImageProvider.Dimensions.Height - areaToRender.Width;
                var amount = additionalWidth / 2;
                newBounds = new Bounds(new Bound(areaToRender.X.MinValue - amount, areaToRender.X.MaxValue + amount), areaToRender.Y);
            }

            return newBounds;
        }
예제 #11
0
 /// <summary>
 /// Gets a RenderedFractal by rendering the fractal with the area to render.
 /// 
 /// The bounds will be scaled to match the ImageProvider dimensions.
 /// </summary>
 public RenderedFractal Render(IFractal fractal, Bounds areaToRender)
 {
     var bounds = GetResizedBounds(areaToRender);
     var renderedFractal = fractalProcessor.Process(fractal, bounds, ImageProvider.Dimensions);
     return Render(renderedFractal);
 }