Get position-X from distance traveled within bounds
I have two blue dots moving in opposite directions. I got a limit on the size of the x-axis in which points can move. In this example, it is 300 units (150 in any direction from 0)
Each blue dot starts at 0 (in the center) and is given the total distance each dot has moved. I'm having trouble writing a function that returns the resulting X-position to me. The figure below shows a blue dot. The red line indicates the boundaries in which the ball can move, think of red lines as walls and blue dots as balls bouncing.
My goal is to create a function that returns this value to me in python.
In my function, you will see that I have a dir argument which is for defining the direction of the ball movement (left or right)
Below is my attempt at solving this, but it is not entirely correct. It doesn't seem to work when there are leftovers from%.
def find_position(dir=1, width=10, traveled=100):
dist = traveled
x = dist % (width*0.5)
print x
find_position(dir=1, width=300, traveled=567)
find_position(dir=1, width=300, traveled=5)
find_position(dir=-1, width=300, traveled=5)
find_position(dir=-1, width=300, traveled=325)
>> output
117.0
5.0
5.0
25.0
>> should be
-33.0
5.0
-5.0
25.0
source to share
With %
and absolute value:
Code:
def find_position(direction=1, width=10, traveled=100):
half_width = width / 2
t = abs((traveled + half_width) % (2 * width) - width) - half_width
return -t * direction
Test code:
assert int(find_position(direction=1, width=300, traveled=567)) == -33.0
assert int(find_position(direction=1, width=300, traveled=5)) == 5
assert int(find_position(direction=-1, width=300, traveled=5)) == -5
assert int(find_position(direction=-1, width=300, traveled=325)) == 25
source to share
The following will be done, the m sign indicates the direction (you can easily make it more general by doing 150 and 300 parameters):
def x(m):
d = 150 + m
# what matters the most is whether it bounced even times or odd times
return (1 if d // 300 % 2 == 0 else -1) * (d % 300 - 150)
assert x(567) == -33
assert x(-325) == 25
assert x(-100) == -100
assert x(-150) == -150
assert x(-160) == -140
assert x(-300) == 0
assert x(-310) == 10
assert x(-450) == 150
assert x(-460) == 140
assert x(100) == 100
assert x(150) == 150
assert x(160) == 140
assert x(300) == 0
assert x(310) == -10
assert x(450) == -150
assert x(460) == -140
source to share
Here is my code for your problem. I left a comment in the code to make it clearer. But shouldn't you expect the X coordinate to be -25 when it passes -325, starting at 0?
def find_position(dir=1, width=10, traveled=100):
# coordinate translation
curr_X = 150
if traveled >= width:
# remove periodicity in distance traveled
dist = traveled % width * dir
else:
dist = traveled * dir
new_X = ( dist + curr_X ) % width
# translate coordinate back to original configuration
new_X = new_X - width * 0.5
return new_X
assert find_position(dir=1, width=300, traveled=567) == -33
assert find_position(dir=1, width=300, traveled=5) == 5
assert find_position(dir=-1, width=300, traveled=5) == -5
assert find_position(dir=-1, width=300, traveled=325) == -25
source to share
def find_position(dir=1, width=10, traveled=100):
# If we have traveled less than half the width, just return
# the traveled distance
if traveled < (width / 2):
return traveled * dir
dist = traveled % width
# If the remainder is less than half the board, we know we are not
# "halfway" around the board, so we can just return the distance again
if dist <= (width / 2):
return dist * dir
# Here we have wrapped around the final round, so we subtract the width
# of the board to get the final distance
return (width - dist) * dir * -1
Output:
>>> find_position(dir=1, width=300, traveled=567)
-33
>>> find_position(dir=1, width=300, traveled=5)
5
>>> find_position(dir=-1, width=300, traveled=5)
-5
>>> find_position(dir=-1, width=300, traveled=325)
-25
source to share