Results 1 to 6 of 6

Thread: [RESOLVED] Rotation

  1. #1

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Resolved [RESOLVED] Rotation

    I have an array that contains the state of certain cells. It looks like this.

    Code:
       5                  
       4                  
       3   *   *   *   *      
    y  2   *   *   *   *      
       1   *   *   *   *      
       0   *   *   *   *      
           0   1   2   3   4   5
                x
    I am trying to rotate the array using this formula:

    x' = (x * Cos deg.) - (y * Sin deg.)
    y' = (x * Sin deg.) + y * (Cos deg.)

    The code (VB .Net) uses Math.Cos & Math.Sin which produce double results. I think my problem happens when I convert the results to integer. Am I missing something?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  2. #2
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Rotation

    You did not mention a problem.

    That rotation equation is valid for arbitrary angles and arbitrary x, y values. Obviously, for a finite grid you will get into trouble; you can never execute the rotation exactly over an arbitrary angle (perhaps there are some angles like 45 or 30 degrees that will work exactly, but not all). Only in the limit that your cell size goes to zero (== continuous, infinite cells) will you be able to represent the rotation exactly, but of course that is a limit you cannot practically take.

    I would tell you to simply round the values down or up, but I'm sure you are already doing that by converting to an integer so evidently that doesn't work as you expected (though you didn't tell us what happens).
    Perhaps you can try something 'clever' like rounding the x values 'to the left' (== down) and the y values up or down when the angle is between 0 and 180 degrees. Otherwise, the cells appear underneath the x-axis and you would round the x values 'to the right' (== up). This is just something I thought of and probably does not work at all.

  3. #3
    Only Slightly Obsessive jemidiah's Avatar
    Join Date
    Apr 2002
    Posts
    2,431

    Re: Rotation

    One thing that might be tripping you up is that you've written your formula in degrees, while the .NET trig functions expect arguments in radians. To convert 50 degrees to radians, multiply by pi/180, i.e. 50 degrees = 50*pi/180 radians = 0.872 radians. All other angles are similar.

    But yeah, we haven't actually been told a problem, so maybe that's not it at all.
    The time you enjoy wasting is not wasted time.
    Bertrand Russell

    <- Remember to rate posts you find helpful.

  4. #4
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Rotation

    vb c#
    [guess]If you are transforming each cell from the source array to the target array you will find the end result is nearly always full of holes (edit: as nick is saying above). Do it backwards, transform each cell in the target array back to the source and you can guarantee all cells will be filled. [/guess]

    You can also work in scaled integers if you wish. It's considerably faster than converting every single cell calculation from Double to Integer. Choose a scale that gives enough decimal precision without overflowing.
    Code:
                const int SCL = 0x10000;
                int ICos0 = (int)(Math.Cos(angle) * (double)SCL);
                int ISin0 = (int)(Math.Sin(angle) * (double)SCL);
    
                x1 = (x * ICos0 - y * ISin0) / SCL;
                y1 = (x * ISin0 + y * ICos0) / SCL;
    It's C# but .net is .net.
    Last edited by Milk; Feb 26th, 2010 at 05:55 PM.
    W o t . S i g

  5. #5

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Rotation

    Thanks everyone! Making the angle 90 degrees and converting to radians sure made a big difference.

    The Game of Life has taken over mine I have learned a lot about graphics in the last couple of weeks.


    Code:
            'real close...
            ' x' = (x * Cos deg.) - (y * Sin deg.)
            ' y' = (x * Sin deg.) + y * (Cos deg.)
            SetUndo() 'set undo
            CutPBsel(False) 'cut the selection, (copy to PBselCopy then delete it)
            If PBselCopy.Count <= 1 Then Exit Sub
            Dim d As Double = degrees * (Math.PI / 180) 'Thanks to jemidiah@vbforums for this nugget
    
            Dim x, y As Double, rect As Rectangle = New Rectangle(0, 0, 0, 0)
            Dim xc, yc As Integer 'the centers
            'calculate centers
            For z As Integer = 0 To PBselCopy.Count - 1
                xc += PBselCopy(z).X
                yc += PBselCopy(z).Y
            Next
            xc = xc \ PBselCopy.Count
            yc = yc \ PBselCopy.Count
    
            For z As Integer = 0 To PBselCopy.Count - 1
                'make relative to center
                PBselCopy(z).X = PBselCopy(z).X - xc
                PBselCopy(z).Y = PBselCopy(z).Y - yc
                'rotate
                x = (PBselCopy(z).X * Math.Cos(d)) - (PBselCopy(z).Y * Math.Sin(d))
                y = (PBselCopy(z).X * Math.Sin(d)) + (PBselCopy(z).Y * Math.Cos(d))
                'make relative to center
                PBselCopy(z).X = CInt(x) + xc
                PBselCopy(z).Y = CInt(y) + yc
                'set the state
                zCellUniverse.State(PBselCopy(z).X, PBselCopy(z).Y) = PBselCopy(z).State
                'new selection rectange
                If rect.IsEmpty Then
                    rect = New Rectangle(PBselCopy(z).X * BlockSize, PBselCopy(z).Y * BlockSize, _
                                         BlockSize, BlockSize)
                Else
                    rect = Rectangle.Union(rect, New Rectangle(PBselCopy(z).X * BlockSize, PBselCopy(z).Y * BlockSize, _
                                         BlockSize, BlockSize))
                End If
            Next
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  6. #6
    Only Slightly Obsessive jemidiah's Avatar
    Join Date
    Apr 2002
    Posts
    2,431

    Re: [RESOLVED] Rotation

    A 90 degree rotation can be done much more simply than using the rotation matrix and trig functions. If speed is at all an issue, at the least you can evaluate Math.Cos(d) and Math.Sin(d) beforehand and plug them in directly. I don't know if the .NET compiler is smart enough to know that those functions don't have side effects and that it can optimize them out.
    The time you enjoy wasting is not wasted time.
    Bertrand Russell

    <- Remember to rate posts you find helpful.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width