【问题标题】:Draw rotated sine image绘制旋转正弦图像
【发布时间】:2011-03-07 19:21:19
【问题描述】:

我正在使用二维傅里叶变换,我有一个方法可以输出以下结果:

代码如下所示:

    private Bitmap PaintSin(int s, int n)
    {
        Data = new int[Width, Height];
        Bitmap buffer = new Bitmap(Width, Height);

        double inner = (2 * Math.PI * s) / n;
        BitmapData originalData = buffer.LockBits(
           new Rectangle(0, 0, buffer.Width, buffer.Height),
           ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

        for (int i = 0; i < buffer.Width; i++)
        {
            for (int j = 0; j < buffer.Height; j++)
            {
                double val;
                int c = 0;

                if (j == 0)
                {
                    val = Math.Sin(inner * i);
                    val += 1;
                    val *= 128;
                    val = val > 255 ? 255 : val;
                    c = (int)val;

                    Color col = Color.FromArgb(c, c, c);
                    SetPixel(originalData, i, j, col);
                }
                else
                    SetPixel(originalData, i, j, GetColor(originalData, i, 0));

                Data[i, j] = c;
            }
        }
        buffer.UnlockBits(originalData);

        return buffer;
    }

现在,我正在尝试考虑一个公式,该公式将接受一个角度并输出一个实线处于给定角度的图像。

例如,如果我输入 45 度,结果将是:

感谢您的帮助!

如果需要,这里是 SetPixel 代码:

    private unsafe void SetPixel(BitmapData originalData, int x, int y, Color color)
    {
        //set the number of bytes per pixel
        int pixelSize = 3;

        //get the data from the original image
        byte* oRow = (byte*)originalData.Scan0 + (y * originalData.Stride);

        //set the new image's pixel to the grayscale version
        oRow[x * pixelSize] = color.B; //B
        oRow[x * pixelSize + 1] = color.G; //G
        oRow[x * pixelSize + 2] = color.R; //R
    }

【问题讨论】:

    标签: c# image math graphics


    【解决方案1】:

    这应该可以通过使用旋转坐标系来实现。 ij的变换如下:

    x = i * cos(angle) - j * sin(angle);
    y = j * cos(angle) + i * sin(angle);
    

    注意:我不确定这里的度数/弧度,所以调整angle 使其适合 cos 和 sin 确实需要的单位。此外,您可能必须根据所需的旋转方向来否定角度。

    实际上,您只需要 x 即可替换您对 i 的使用。我们将预先计算 sin(angle)cos(angle) 因为这些是我们不希望在内部循环中进行的非常昂贵的操作。另外,您的优化已被删除,因为我们不能只画一条线并重复它:

        [...]
        // double angle = ...
        double cos_angle = cos(angle);
        double sin_angle = sin(angle);
        for (int i = 0; i < buffer.Width; i++)
        {
            for (int j = 0; j < buffer.Height; j++)
            {
                double val;
                double x;
                int c = 0;
    
                x = i * cos_angle - j * sin_angle;
                val = Math.Sin(inner * x);
                val += 1;
                val *= 128;
                val = val > 255 ? 255 : val;
                c = (int)val;
    
                Color col = Color.FromArgb(c, c, c);
                SetPixel(originalData, i, j, col);
    
                Data[i, j] = c;
            }
        }
    

    【讨论】:

    • 没错!谢谢 :) 当设置为每 50 毫秒刷新一次时,结果非常糟糕......
    【解决方案2】:

    您可以编写一个简单的函数 rotate(x,y,angle) 并将其结果用于 SetPixel。你可以谷歌搜索旋转矩阵。 angle = 0 的调用应该产生默认输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多