Link to home
Start Free TrialLog in
Avatar of rojabuck
rojabuck

asked on

Finding the orientation of a line

I would like a c function which i can pass the co-ordinates of a line as int's (start x,y and end x,y) and for that function to return a double containing the oreantation of that line as a degree. The returned value should be calculated as shown in the picture: http://www.dcs.st-and.ac.uk/~arb11/angle-function.gif

Does anyone have any idea how to go about this? I have tried using the atan and atan2 functions and generaly get garbage out, i am aware that this most likely mearly my lack of maths knowlage when it comes to trig etc.

Any help would be very much appreciated!

Regards
Roja
Avatar of Infinity08
Infinity08
Flag of Belgium image

This sounds like homework, so i'll just ask you to show me some code for the way you're doing it now (what generates garbage as you said), and i'll help you out from there.
Avatar of rojabuck
rojabuck

ASKER

Na.. not homework sorry to say i am a researcher, though as can be seen, maths isnt exactly my strong point, not to mention c! Here's the code i am attempting to use.. but the values i am getting are nothing more than sparadic to be honest:

    printf("##########\nCurrent Position: %d, %d\n",(int)current_position.x,(int)current_position.y);

    double current_direction;
    Point direction_change;

    current_direction = atan2((double)((int)current_position.y-(int)target_node.y), (double)((int)current_position.x-(int)target_node.x));

    //if ((int)current_position.x-(int)target_node.x > 0 || (int)current_position.x-(int)target_node.x < 0) {
    //    current_direction = atan((double)(((int)current_position.y-(int)target_node.y)/((int)current_position.x-(int)target_node.x)));
    //}
    //else if (((int)current_position.y-(int)target_node.y) < 0) {
    //    current_direction = (acos(-1)/180)*270;
    //}
    //else {
    //    current_direction = (acos(-1)/180)*90;
    //}


    direction_change.x = current_direction - last_direction;

    printf("Current Direction: %f\nDirection Change: %f\nLast Direction: %f\n",current_direction,direction_change.x,last_direction);

    last_direction = current_direction;

    if (direction_change.x != 0 || last_direction == 0) {
        set_array_element(&angles,num_angle_changes,direction_change);
        num_angle_changes++;
    }

    number_of_moves++;

(someone should work out how to allow copy/paste between win and linux vnc's!!)

the value i am actually after is the "direction change" value eventualy will be used to calculate the "avarage direction change". I know i am storing that value in a wierd place but there is already code in place to make an expandable array of structs used to contain x and y's and i figure i may as well simply make use of them.

Regards
Roja
ASKER CERTIFIED SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Your calculation looks reasonable.

Note atan2 returns its result in radians, whereas your graph indicates you want to express the result in degrees.

If that is the only problem, it could presumably be remedied by converting the result from atan2 with:

(res/(2*PI))*360



btw : for reference of the atan2 function :

http://www.cplusplus.com/ref/cmath/atan2.html


And maybe a clarification of the previous code :

a vector that goes from (x0,y0) to (x1,y1) would have the following direction in radians :

     atan2(y0-y1,x1-x0)
i am finding spurious results still... angles which on my diagram should give angles arround 90->135 are giving results of 290 etc..

Current Position: 149, 127
Current Direction: 296.565058
Direction Change: 0.000000
Last Direction: 296.565058
##########
Current Position: 148, 125
Current Direction: 296.565058
Direction Change: 0.000000
Last Direction: 296.565058
##########
Current Position: 148, 123
Current Direction: 296.565058
Direction Change: 0.000000
Last Direction: 296.565058
##########
Current Position: 148, 122
Current Direction: 270.000010
Direction Change: -26.565048
Last Direction: 296.565058

that line should look like:

^
  |
    |
      |
        |

which should be giving arround 110/120..

Regards
Roja
also.. a flat line:    <--------------------  is giving an angle of 140...


Current Position: 457, 364
Current Direction: 141.462701
Direction Change: -0.121870
Last Direction: 141.584571
##########
Current Position: 455, 364
Current Direction: 141.340176
Direction Change: -0.122525
Last Direction: 141.462701
##########
Current Position: 453, 364
Current Direction: 141.216993
Direction Change: -0.123183
Last Direction: 141.340176
##########
Current Position: 451, 364
Current Direction: 141.093147
Direction Change: -0.123846
Last Direction: 141.216993
##########
Current Position: 449, 364
Current Direction: 140.968634
Direction Change: -0.124513
Last Direction: 141.093147


and just for info.. a diaganal down line is giving 270..

|
|
|
|
v


any advice is most helpful.. :) Cheers so far!!

Regards
Roja
>> Current Position: 149, 127
>> Current Direction: 296.565058

What was the target node's position ?


example :

(100, 100) -> (120, 80)

should give 45 degrees. Let's try :

current_direction = atan2((double)((int)current_position.y-(int)target_node.y), (double)((int)target_node.x-(int)current_position.x))
= atan2((double)((int)100-(int)80), (double)((int)120-(int)100))
= atan2(20,20) = PI/4

this is in radians. Now conversion to degrees :

current_direction = (current_direction / (2*PI)) * 360
= ((PI/4) / (2*PI)) * 360
= (1/8) * 360
= 45

try inputting the above coordinates in your program, and see if the output is 45. If it's not, then there's some mistake in your code.
indeed it was the code (not my code to be honest hence all this issue!) Many thanks to all those who helped.. sepecialy infinity08!

Regards
Roja