Draw rotated sine image


I'm working with 2D Fourier transforms, and I have a method that will output the following result: Original Image

The code looks like this:

    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;
    }

Now, I'm trying to think of a formula that will accept an angle and will out put an image where the solid lines are at the given angle.

For example, if I inputted 45 Degrees, the result would be:

Rotated image

Thank you for any help!

Here is the SetPixel code if that is needed:

    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
    }

Answers:


This should be possible by using a rotated coordinate system. Transformation of i and j is as following:

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

Note: I'm not sure about degree/radians here, so adjust angle so it fits to the unit that cos and sin do need. Also, you might have to negate the angle depending on your desired rotation direction.

In fact, you only need x which replaces your use of i. We'll precompute sin(angle) and cos(angle) because these are quite costy operations we don't want in inner loops. Additionaly, your optimization is removed as we can't draw only one line and repeat it:

    [...]
    // 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;
        }
    }