使硬币减速旋转的代码无法正常工作
Posted
技术标签:
【中文标题】使硬币减速旋转的代码无法正常工作【英文标题】:Code for decelerating rotation of a coin not working properly 【发布时间】:2017-03-11 20:30:17 【问题描述】:我正在尝试模拟硬币的旋转。一个完整的旋转被建模为一个参数从 1 到 -1 再回到 1 的变化,1 是直硬币,-1 是倒置硬币。硬币应该逐渐减速。该函数的参数是硬币在停止前要转半圈的次数,运动应该采取的帧数,以及硬币旋转的初始速度(每帧转半圈)。
首先我用公式2*(displacement - initial_v*time) / time*time
计算减速度的值。然后我创建一个包含每帧距离值的列表。这里出了点问题,因为值真的很高。 (我省略了将位置值限制在 1 和 -1 之间的代码部分,因为在到达该点之前出现问题)。
def animate_rotation(n_half_turns, n_frames, speed):
"""
First I calculate the appropriate deceleration given distance d, initial velocity t_0, and time t
Then I find the position value per frame by calculating the distance given the found acceleration
"""
displacement = n_half_turns # every half turn is a movement from 1 to -1, i.e. 2 units
v = speed # this is the initial speed, i.e. n of half turns per frame
time = n_frames
position = 1
deceleration = 2 * (displacement - v * time) / time*time
#distance traveled from initial position for each frame
frame_distance = []
for i in range(n_frames):
position += v
frame_distance.append(position)
v += deceleration
#the rest of the code transforms the values so that they are between 1 and -1. I eliminated this part because things go wrong before it.
animate_rotation(1, 10, 1)
我希望 new_dist 列表以 n_frames 帧数(new_dist 列表的长度)中的 n_half_turns 值从一定速度开始并适当减速。然而,我在运行代码时得到的更像是一个寓言:首先位置增加,然后超出 n_half_turns,然后又回到它。 new_dist 列表为:
[1, 1.8200000000000003, 2.4600000000000004, 2.9200000000000004, 3.2, 3.3000000000000007, 3.2200000000000006, 2.960000000000001, 2.520000000000001, 1.9000000000000012]
【问题讨论】:
你错过了正确的缩进,还有How to Ask 对不起,我是新来的网站。我应该如何更改问题的主体以符合如何提问?我之前阅读了该页面,我认为我的问题符合指南。我也不确定如何增加代码块的缩进。 问题在于大量的解释和代码。最好能提供minimal reproducible example 我修改了它,希望它更符合标准。感谢当地海关的帮助! 在没有阅读的情况下回复了反对票和赞成票,只是为了减少和收听 cmets 的努力。现在居然发现了一个可疑的东西!! 【参考方案1】:可能是部分答案(可能还有其他问题)但至少这个公式是错误的:
2 * (displacement - v * time) / time*time
因为除法优先于乘法,所以它等价于
2 * (displacement - v * time)
当你想要它时:
2 * (displacement - v * time) / (time*time)
快速演示:
>>> 1/4*4
1.0
>>> 1/(4*4)
0.0625
另外,在你的循环中,更多的是物理方面的东西:
for i in range(n_frames):
position += position * v
frame_distance.append(position)
v += v * deceleration
没有意义。如果我理解正确,每次迭代都是经过的时间。因此,您只需添加速度,而不是速度与位置的乘积,从而将速度应用于位置,这就解释了为什么您的位置会飙升。
速度变化也是如此。我的建议:
for i in range(n_frames):
position += v
frame_distance.append(position)
v += deceleration
通过所有这些修复,我得到了一组好看的值,不确定它们是否正常,但看起来更好:
[1.0, 1.0984, 1.1952, 1.2904, 1.384, 1.476, 1.5664, 1.6552, 1.7424, 1.8279999999999998, 1.912, 1.9943999999999997, 2.0751999999999997, 2.1544, 2.2319999999999998, 2.308, 2.3823999999999996, 2.4551999999999996, 2.5263999999999993, 2.595999999999999, 2.6639999999999993, 2.730399999999999, 2.795199999999999, 2.8583999999999987, 2.9199999999999986, 2.9799999999999986, 3.0383999999999984, 3.0951999999999984, 3.1503999999999985, 3.2039999999999984, 3.2559999999999985, 3.3063999999999982, 3.355199999999998, 3.4023999999999983, 3.447999999999998, 3.491999999999998, 3.534399999999998, 3.575199999999998, 3.614399999999998, 3.651999999999998, 3.687999999999998, 3.7223999999999977, 3.7551999999999977, 3.7863999999999978, 3.8159999999999976, 3.8439999999999976, 3.8703999999999974, 3.8951999999999973, 3.918399999999997, 3.9399999999999973, 3.959999999999997, 3.9783999999999966, 3.9951999999999965, 4.010399999999997, 4.023999999999997, 4.035999999999996, 4.046399999999997, 4.055199999999996, 4.062399999999997, 4.067999999999996, 4.071999999999996, 4.074399999999995, 4.075199999999995, 4.074399999999995, 4.071999999999996, 4.067999999999996, 4.062399999999995, 4.055199999999996, 4.046399999999995, 4.035999999999996, 4.023999999999996, 4.010399999999995, 3.9951999999999948, 3.978399999999995, 3.959999999999995, 3.9399999999999946, 3.9183999999999943, 3.8951999999999942, 3.8703999999999943, 3.843999999999994, 3.815999999999994, 3.786399999999994, 3.755199999999994, 3.722399999999994, 3.687999999999994, 3.651999999999994, 3.614399999999994, 3.575199999999994, 3.534399999999994, 3.4919999999999938, 3.4479999999999937, 3.402399999999994, 3.3551999999999937, 3.306399999999994, 3.2559999999999936, 3.2039999999999935, 3.1503999999999936, 3.0951999999999935, 3.0383999999999936, 2.9799999999999933]
【讨论】:
哦,对,这很有意义。更新后的代码中的 new_dist 仍然上升到 6933.400093777868,我希望它上升到 2。position += position * v
?你确定吗?它将 position*v 添加到现有位置。您不想将经过时间*速度添加到位置吗? v += v * deceleration
也是如此
position += v
实际上会更有意义(不是物理专家,但我编写了一些游戏)。
哦,是的,它现在看起来确实好多了。编辑是有道理的。由于某种原因,它仍然没有按预期运行 - 特别是,该位置超出了预期的数字,然后又回到了预期的数字。例如,当运行Animate_rotation(1,10,0.5)时,位置是[1.0,1.42,1.759999999999,229999999999999,22999999999994,2.29999999999994,2.29999999999994,2.29999999999994,2.25999999999993,2.11999999999999,411999999999999,011999999999999,1.8999999999999,1.8999999999999]。这似乎比以前更现实,因为它是一个寓言,但这不是我的本意。以上是关于使硬币减速旋转的代码无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章