Thread: rotate line

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    115

    rotate line

    Hello

    For school I need to make a project using GTK. I need to make a small program like Paint.

    I have a function to draw lines.
    Now i need to implement a possibility to rotate this line.

    I store the begincoordinates and endcoordinates of this line.

    does anyone know the best way to do this?

    thanx

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You'll have to describe in a bit more detail what you mean. Do you want to rotate a line once it has already been created? What sort of user interface would you like to have? You could, for example, just let the user drag one of the endpoints of the line around to in effect rotate it.

    If you want to do actual rotation, do you want to rotate about one of the endpoints, or the centre of the line, or what?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Describe precisely what it means to rotate a line. Apart from the begin/end coordinates, that description will also need to represent what are you rotating about and a measure of rotation. Once you've worked that logic out, write a function to implement it.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  4. #4
    Registered User
    Join Date
    Feb 2010
    Posts
    115
    Thank you for the reply.

    I have a linked list with all drawings that i have ever created (lines, ellipses, rectangles...).
    In this linked list I keep from a line the begin and end coordinates.

    I have a toolbar with a button select. If i press this button i can select some objects then I can
    press another button rotate I can choose to rotate between 90, 180 and 270 degrees.

    Now I want to rotate a line 90 degrees.

    For example : function x

    What is the best way to rotate 90 degrees clockwise?
    Do I need to do many if tests to see how to draw it? or is there some kind of mathematical function or some to do this?

  5. #5
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    I cannot tell from your description: are you intending on rotating just the line or the bitmap that the line is on?
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  6. #6
    Registered User
    Join Date
    Feb 2010
    Posts
    115
    just the line

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You can't just "rotate 90 degrees" without rotating about some fixed point. If you have a line then I can think of two ways you might want to rotate it: you might want to rotate the line about (or around or whatever you want to call it) one of its end points, or you might want to rotate the line about the centre of the line (the point on the line that is equidistant from both endpoints).

    Rotating 90 degrees clockwise is pretty easy. Suppose your line has width x and height y. Then a line which is rotated 90 degrees just has width -y and height x. You can get this by taking the following 2D rotation formulae and plugging in theta = 90 degrees: Transformation matrix - Wikipedia, the free encyclopedia
    That page describes it in terms of matrices, but all you really have to know are the formulae for x' and y'.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Registered User
    Join Date
    Feb 2010
    Posts
    115
    Ok, so I fill in this function :
    "for a rotation clockwise about the origin, the functional form is x' = xcosθ + ysinθ and y' = − xsinθ + ycosθ "

    endX = copy->rect->endX* cos(90) + copy->rect->endY* sin(90);
    endY = (-copy->rect->endX* sin(90)) + copy->rect->endY* cos(90);
    printf("%i %i %i %i\n", copy->rect->beginX, copy->rect->beginY, endX, endY);

    Now i get negative values back. This is because it is rotated around the begincoordinates.
    But I dont think these values are correct.

    For example: A line with beginX = 87, beginY = 6 and a length of 6 gives back the values -36 and -85.

    Am I forgetting something or doing something wrong?

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    If you're actually calling sin and cos from C, then don't pass 90 -- these functions take radians, not degrees. You can convert degrees to radians by using a function like
    Code:
    double deg2rad(double deg) {
        return deg * PI * 180;
    }
    where PI can be defined as M_PI if your math.h has it or as the literal
    Code:
    #define PI 3.14159265358979324
    Note that this will rotate the line about the origin (0, 0). If you want to rotate the line about, say, the endpoint (x,y), then translate the endpoints of the line by (-x,-y), perform the rotation, and then translate back again by (x,y).
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  10. #10
    Registered User
    Join Date
    Feb 2010
    Posts
    115
    ok this is what i have done

    Code:
     
          transX = -copy->rect->endX;
          transY = -copy->rect->endY;
          
          endX = transX* cos(deg90InRad) + transY* sin(deg90InRad);
          endY = (-transX* sin(deg90InRad)) + transX* cos(deg90InRad);
      
          endX = -endX;
          endY = -endY;
    but i have still dont have the right coordinates :s

  11. #11
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    No, no . . . When I say translate, I mean take your object and move it by that offset. Here's how you probably want to do it.
    Code:
        // This code rotates the line by 90 degrees clockwise about the point start
        // We want (x,y) to be the location of the end endpoint, and start to be moved to the origin
        // First, set (x,y) to the end
        x = copy->rect->endX;
        y = copy->rect->endY;
    
        // Now translate by (-startX, -startY)
        x -= copy->rect->startX;
        y -= copy->rect->startY;
    
        // Next perform the rotation (you seem to have not copied the formulae correctly, I got this from the Wikipedia page, more or less)
        x = (x * cos(deg90InRad)) - (y * sin(deg90InRad));
        y = (x * sin(deg90InRad)) + (y * cos(deg90InRad);
      
        // Now translate back, by (startX, startY)
        x += copy->rect->startX;
        y += copy->rect->startY;
    At the end of this, one of the endpoints of your rotated line will be (startX, startY) -- since you rotated about that point, it doesn't move anywhere. And the other endpoint of the line segment will be (x, y).
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  12. #12
    Registered User
    Join Date
    Feb 2010
    Posts
    115
    Owk thank you for clearing it up

    I copied your code and changed the vars to my needs but if i run the code and print the coordinates the x,y coordinates are the same as the copy->rect->endX en Y coordinates :s

    Code:
      x = copy->rect->endX;
        y = copy->rect->endY;
    
       
        x -= copy->rect->beginX;
        y -= copy->rect->beginY;
    
       
        transX = (x * cos(deg90InRad)) - (y * sin(deg90InRad));
        transY = (x * sin(deg90InRad)) + (y * cos(deg90InRad));
      
        
        transX += copy->rect->beginX;
        transY += copy->rect->beginY;
        
        x = transX;
        y = transY;
      
        printf("%i %i %i %i %i %in", copy->rect->beginX, copy->rect->beginY, copy->rect->endX, copy->rect->endY, x, y);

  13. #13
    Registered User
    Join Date
    Feb 2010
    Posts
    115
    It is alive !!!

    Thank you very much for the help. It works great now.

  14. #14
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    [edit] You seem to have gotten it working before I typed this up -- good work. You should take some graphics courses sometime. [/edit]

    What's the value of deg90InRad? If you replace it with the hard-coded value (3.14159 / 2), what happens?

    There was a problem with my pseudo-code -- I was replacing the value of x before it was used in calculating y in the second line involving sin and cos. Oops. But it actually works if you adapt it a little:
    Code:
    $ cat rotate.c
    #include <stdio.h>
    #include <math.h>
    
    static const double deg90InRad = -3.14159265358979324 / 2;
    
    int main(int argc, char *argv[]) {
        double startX = 10.0, startY = 10.0;
        double endX = 15.0, endY = 15.0;
        double x, y;
    
        // This code rotates the line by 90 degrees clockwise about the point start
        // We want (x,y) to be the location of the end endpoint, and start to be moved to the origin
        // First, set (x,y) to the end
        x = endX;
        y = endY;
    
        // Now translate by (-startX, -startY)
        x -= startX;
        y -= startY;
    
        // Next perform the rotation (you seem to have not copied the formulae correctly, I got this from the Wikipedia page, more or less)
        endX = (x * cos(deg90InRad)) - (y * sin(deg90InRad));
        endY = (x * sin(deg90InRad)) + (y * cos(deg90InRad));
      
        // Now translate back, by (startX, startY)
        endX += startX;
        endY += startY;    
    
        printf("New line is from (%f,%f) to (%f,%f)\n", startX, startY, endX, endY);
    
        return 0;
    }
    
    $ gcc -W -Wall -g rotate.c -o rotate -lm
    rotate.c: In function ‘main’:
    rotate.c:6: warning: unused parameter ‘argc’
    rotate.c:6: warning: unused parameter ‘argv’
    $ ./rotate 
    New line is from (10.000000,10.000000) to (15.000000,5.000000)
    $
    Turns out I also had to make the angle negative to get a clockwise rotation.

    If you're still having trouble with your code, you might try posting a more substantial portion of it.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  15. #15
    Registered User
    Join Date
    Feb 2010
    Posts
    115
    No, it works now. Thank you so much for your help. You are amazing!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Printing Length of Input and the Limited Input
    By dnguyen1022 in forum C Programming
    Replies: 33
    Last Post: 11-29-2008, 04:13 PM
  2. adding line numbers and concatenating a filename
    By durrty in forum C Programming
    Replies: 25
    Last Post: 06-28-2008, 03:36 AM
  3. Finding carriage returns (\c) in a line
    By JizJizJiz in forum C++ Programming
    Replies: 37
    Last Post: 07-19-2006, 05:44 PM
  4. Adding Line numbers in Word
    By Mister C in forum A Brief History of Cprogramming.com
    Replies: 24
    Last Post: 06-24-2004, 08:45 PM
  5. how to rotate a line of text ??
    By darrenteo in forum C Programming
    Replies: 5
    Last Post: 04-06-2002, 10:09 AM