Search code examples
c++sfmltrigonometry

Calculating end point of line not working


I two rectangles with an angle displaying a line, and I want the second ones position to be the end point of the first one.
The origin of the lines is the start point, and I can get the angle via a function(I am using the SFML library for defining/displaying the rectangles).

The first part of the Code looks like this, I tested it and it's working as it should:

// Make two lines(constructor arguments are width/height)
sf::RectangleShape line1 = sf::RectangleShape(1, 10);
sf::RectangleShape line2 = sf::RectangleShape(1, 10);

// Rotate lines(angle in DEG), and set origin to the middle point
line1.setRotation(30);
line2.setRotation(10);
line1.setOrigin(0.5, 0);
line2.setOrigin(0.5, 0);

Now here comes the part where the problem arises. I try to use cos() and sin() functions to calculate the new position of the second line, however they end up being somewhere else completely.

// get angle and convert to RAD, get length (also tested, works as intended)
float angle = M_PI/180 * line1.getRotation;
float length = line1.getSize().y;

// set position of first line to end of second line
line2.setPosition(cos(angle) * length, sin(angle) * length);

What am I doing wrong? As far as my understanding of trigonometry goes everything should be correct. The angle is correct, aswell as the length. I really have no clue why this isn't working.


Solution

  • You are creating lines that looks like at angle 0:

    line drooping downwards

    This is because the width is 1, height is 10, and the origin is (0.5, 0), note that this example shows y increasing downwards, not upwards.

    But you are using maths that calculates the end point like this at angle 0:

    line drooping rightwards

    This is because x equals cos(0) * length, which equals 1 * length and y equals sin(0) * length, which equals 0 * length which equals 0, thus the end point is at (length, 0) towards the right.

    The solution is to either alter the math, or the lines so that they both are the same at different angles.

    Here is a solution that makes the lines horizontal instead of vertical:

    // Make two lines(constructor arguments are width/height)
    sf::RectangleShape line1 = sf::RectangleShape({ 10, 1 });
    sf::RectangleShape line2 = sf::RectangleShape({ 10, 1 });
    
    // Rotate lines(angle in DEG), and set origin to the middle point
    line1.setRotation(90 + 30);
    line2.setRotation(90 + 10);
    line1.setOrigin(0, 0.5);
    line2.setOrigin(0, 0.5);
    
    // get angle and convert to RAD, get length (also tested, works as intended)
    float angle = M_PI / 180 * line1.getRotation();
    float length = line1.getSize().x;
    
    // set position of first line to end of second line
    line2.setPosition(cos(angle) * length, sin(angle) * length);
    

    and here is a solution that changes the maths instead:

    // set position of first line to end of second line
    line2.setPosition(-sin(angle) * length, cos(angle) * length);
    

    This produces the following result, with the origin marked in red, and the y going downwards:

    result