Afforess / Factorio-Stdlib

Factorio Standard Library Project
ISC License
162 stars 45 forks source link

Added Position.offset_along_linevec function #131

Closed kyranf closed 5 years ago

kyranf commented 6 years ago

Added Position.offset_along_linevec function for finding a point between two points along the line vector with an adjustable offset away from target position.

Nexela commented 6 years ago

I will merge this manually, Here is the final output

function Position.offset_along_line(pos1, pos2, distance_from_pos2)
    pos1, pos2 = Position(pos1), Position(pos2)

    local angle = pos1:atan(pos2)
    local veclength = pos1:distance(pos2) - distance_from_pos2

    -- From source_position, project the point along the vector at angle, and veclength
    pos1.x = pos1.x + math.cos(angle) * veclength
    pos1.y = pos1.y + math.sin(angle) * veclength

    return pos1
end
Nexela commented 6 years ago

Hmmm, I am not getting what I think I should be getting....

print(Position.offset_along_line({0, 0}, {0, 10}, 5)) == {x = 3.0615158845559e-016, y = 5}

Should return {0, 5}, Also might be worth it to format out a few decimal places :P

kyranf commented 6 years ago

@Nexela there is potential issues with atan rather than atan2, with handling 0 values and signs in different quadrants..

{x = 3.0615158845559e-016, y = 5} ~= x =0, y=5. Obviously 3.06e-16 is approximately 0, but there is floating point math involved and a 'line' gradient approaching issues with vertical/horizontal and atan function return values ..

Nexela commented 6 years ago

It is using atan2 just a typo on the post. Also shows how well I know fp math. Consider it added.

On Thu, Aug 30, 2018, 3:13 AM kyranf notifications@github.com wrote:

@Nexela https://github.com/Nexela there is potential issues with atan rather than atan2, with handling 0 values and signs in different quadrants..

{x = 3.0615158845559e-016, y = 5} ~= x =0, y=5. Obviously 3.06e-16 is approximately 0, but there is floating point math involved and a 'line' gradient approaching issues with vertical/horizontal and atan function return values ..

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Afforess/Factorio-Stdlib/pull/131#issuecomment-417214325, or mute the thread https://github.com/notifications/unsubscribe-auth/ANUy4Hl30NY3e1HreDDifKXMh4W5RMNRks5uV5CugaJpZM4WRGNh .

Nexela commented 6 years ago

Can you re-target your PR to data_library_0.17

Here is what the final result will be

--- Returns the position along line between source and target, at the distance from target
-- @tparam Concepts.Position pos1 where the line starts and extends from.
-- @tparam Concepts.Position pos2 where the line ends and is offset back from.
-- @tparam number distance backwards from pos1 for the new position.
-- @treturn Concepts.Position a point along line between source and target, at requested offset back from target.
function Position.offset_along_line(pos1, pos2, distance_from_pos2)
    pos1, pos2 = Position(pos1), Position(pos2)

    local angle = pos1:atan2(pos2)
    local veclength = pos1:distance(pos2) - distance_from_pos2

    -- From source_position, project the point along the vector at angle, and veclength
    pos1.x = pos1.x + math.round_to(math.cos(angle) * veclength, 10)
    pos1.y = pos1.y + math.round_to(math.sin(angle) * veclength, 10)

    return pos1
end

print(Position.offset_along_line({0, 0}, {0, 10}, 5)) == {x = 0, y = 5}

Nexela commented 5 years ago

Merged from other PR