Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 放大曼德布罗特_C#_Windows_Fractals_Mandelbrot - Fatal编程技术网

C# 放大曼德布罗特

C# 放大曼德布罗特,c#,windows,fractals,mandelbrot,C#,Windows,Fractals,Mandelbrot,我正试图找到一种方法,在点击时放大我的Mandelbrot集。当我点击它时,它会稍微放大,但它不会相应地移动Mandelbrot using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks;

我正试图找到一种方法,在点击时放大我的Mandelbrot集。当我点击它时,它会稍微放大,但它不会相应地移动Mandelbrot

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Numerics;

namespace Project_V2
{
    public partial class FractalGen : Form
    {
        public double zoom = 2.4;
        public FractalGen()
        {
            InitializeComponent();
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            zoom -= 0.3;
            Mandelbrot();
        }

        private void button1_Click(object sender, EventArgs e)
        {
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Mandelbrot();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {

        }

        private void Mandelbrot()
        {
            Bitmap bm = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            DateTime StartT = DateTime.Now;
            for (int x = 0; x < pictureBox1.Width; x++)
            {
                for (int y = 0; y < pictureBox1.Height; y++)
                {
                    double a = (double)(x - (pictureBox1.Width / 1.25)) / (double)(pictureBox1.Width / zoom);
                    double b = (double)(y - (pictureBox1.Height / 2)) / (double)(pictureBox1.Height / zoom);
                    Complex C = new Complex(a, b);
                    Complex Z = new Complex(0, 0);
                    int u = 0;
                    do
                    {
                        u++;
                        Z = Z * Z;
                        Z = Z + C;
                        double Mag = Complex.Abs(Z);
                        if (Mag > 2.0) break;
                    } while (u < 255);
                    Color rgbInside = Color.FromArgb(0, 0, 0);
                    Color rgbOutside = Color.FromArgb(u >= 127 ? 255 : 2 * u, u >= 127 ? (u - 127) : 0, 0);
                    bm.SetPixel(x, y, u < 255 ? rgbOutside : rgbInside);
                }
            }
            pictureBox1.Image = bm;
            DateTime EndT = DateTime.Now;
            string Time = Convert.ToString((EndT - StartT).TotalSeconds);
            textBox1.Text = "Time Taken: " + Time + " Seconds";
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            zoom = 2.4;
            Mandelbrot();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            saveFileDialog1.ShowDialog();
        }

        private void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            string name = saveFileDialog1.FileName;
            pictureBox1.Image.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Png);
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows.Forms;
使用系统数字;
命名空间项目_V2
{
公共部分类FractalGen:Form
{
公共双变焦=2.4;
公共分形
{
初始化组件();
}
私有无效图片单击(对象发送方,事件参数e)
{
缩放-=0.3;
曼德布罗特();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
}
私有void Form1\u加载(对象发送方、事件参数e)
{
曼德布罗特();
}
私有无效计时器1_刻度(对象发送方,事件参数e)
{
}
私有无效Mandelbrot()
{
位图bm=新位图(pictureBox1.Width,pictureBox1.Height);
DateTime StartT=DateTime.Now;
对于(int x=0;x2.0)断裂;
}u<255;
Color rgbInside=Color.FromArgb(0,0,0);
颜色rgbOutside=Color.FromArgb(u>=127?255:2*u,u>=127?(u-127):0,0);
bm.SetPixel(x,y,u<255?rgbOutside:rgbInside);
}
}
pictureBox1.Image=bm;
DateTime EndT=DateTime.Now;
字符串时间=Convert.ToString((EndT-StartT).TotalSeconds);
textBox1.Text=“所用时间:”+时间+“秒”;
}
私有无效按钮1\u单击\u 1(对象发送者,事件参数e)
{
缩放=2.4;
曼德布罗特();
}
私有无效按钮2\u单击(对象发送者,事件参数e)
{
saveFileDialog1.ShowDialog();
}
私有void saveFileDialog1\u FileOk(对象发送方,CancelEventArgs e)
{
string name=saveFileDialog1.FileName;
pictureBox1.Image.Save(saveFileDialog1.FileName,System.Drawing.Imaging.ImageFormat.Png);
}
}
}
当前代码将picturebox的宽度和高度除以一个值,但我希望它能放大我单击的位置。
如何根据单击的位置缩放picturebox?

了解已向您提供的指导将很有帮助。我从中推断,您可能提出了一个现有的问题,然后将其删除,其中讨论了这个问题。如果不知道已经提供了哪些帮助以及您无法理解的具体内容,就很难知道如何最好地给出新的答案

也就是说,要实现你所追求的行为,你必须解决两个基本问题:

  • 确定单击鼠标的位置。当前,您正在使用
    单击
    事件,该事件仅向您的代码报告控件被单击的位置,而不是被单击的位置
  • 修复渲染代码以适应应绘制内容边界的更改。当前,始终将位图中的像素范围映射到以(-0.72,0)为中心的复杂平面中的范围,仅调整距该中心的渲染距离(即
    zoom
    变量)
  • 要处理#1,您需要订阅
    MouseClick
    事件。这将向处理程序传递一个
    MouseEventArgs
    对象,该处理程序具有一个
    Location
    属性,指示控件客户端区域内实际单击的点(即,报告的坐标相对于控件左上角的原点)

    为了解决#2问题,您需要向类中添加一些变量,以跟踪要绘制的相对位置。有很多方法可以做到这一点,但请遵循当前表示当前“缩放”的惯例作为渲染区域的宽度和高度的因素,根据绘制的复杂平面上的位置,跟踪渲染空间的中心(即单击鼠标的位置)似乎是有意义的

    我强烈反对在执行长期运行任务时锁定UI的程序。因此,在修改代码示例的过程中,我对其进行了修改,使其能够在工作线程中渲染图像,并通过在我添加到表单的
    标签上提供状态消息来报告渲染进度。(这涉及到将您的
    Mandelbrot()
    方法设置为
    async
    方法……我在调用它以抑制编译器警告时使用了
    await
    ,但在这种情况下,
    await
    当然不是严格需要的。)

    我没有做的一件事是向代码中添加进一步的优化。这些优化往往会混淆与您的问题直接相关的更改。您可以通过删除冗余计算或使用数学关系来执行成本较低的计算,对代码执行许多有助于提高性能的操作y大于字面tr
    public partial class Form1 : Form
    {
        double zoom = 2.4;
        double centerX = -0.72, centerY = 0;
    
        public Form1()
        {
            InitializeComponent();
        }
    
        private async void pictureBox1_MouseClick(object sender, MouseEventArgs e)
        {
            double minX = centerX - zoom / 2, minY = centerY - zoom / 2;
            centerX = minX + (double)e.Location.X / pictureBox1.Width * zoom;
            centerY = minY + (double)e.Location.Y / pictureBox1.Height * zoom;
            zoom -= 0.3;
            await Mandelbrot();
        }
    
        private async void Form1_Load(object sender, EventArgs e)
        {
            await Mandelbrot();
        }
    
        private async Task Mandelbrot()
        {
            IProgress<double> progress = new Progress<double>(x => label1.Text = $"{x * 100:0}% done");
    
            DateTime StartT = DateTime.UtcNow;
            pictureBox1.Image = await Task.Run(() => _GenerateBitmap(progress));
            DateTime EndT = DateTime.UtcNow;
            string Time = Convert.ToString((EndT - StartT).TotalSeconds);
            textBox1.Text = "Time Taken: " + Time + " Seconds";
        }
    
        private Bitmap _GenerateBitmap(IProgress<double> progress)
        {
            Bitmap bm = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            double minX = centerX - zoom / 2, minY = centerY - zoom / 2;
    
            for (int x = 0; x < pictureBox1.Width; x++)
            {
                for (int y = 0; y < pictureBox1.Height; y++)
                {
                    double a = minX + (double)x / pictureBox1.Width * zoom;
                    double b = minY + (double)y / pictureBox1.Height * zoom;
                    Complex C = new Complex(a, b);
                    Complex Z = new Complex(0, 0);
                    int u = 0;
                    do
                    {
                        u++;
                        Z = Z * Z;
                        Z = Z + C;
                        double Mag = Complex.Abs(Z);
                        if (Mag > 2.0) break;
                    } while (u < 255);
                    Color rgbInside = Color.FromArgb(0, 0, 0);
                    Color rgbOutside = Color.FromArgb(u >= 127 ? 255 : 2 * u, u >= 127 ? (u - 127) : 0, 0);
                    bm.SetPixel(x, y, u < 255 ? rgbOutside : rgbInside);
                }
    
                progress.Report((double)x / pictureBox1.Width);
            }
    
            return bm;
        }
    
        private async void button1_Click_1(object sender, EventArgs e)
        {
            zoom = 2.4;
            await Mandelbrot();
        }
    }