-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How should the speed levels in the turtle crate work? #180
Comments
Hey @sunjay, I think it is indeed a good idea to overhaul this mechanism now, in my opinion for multiple reasons:
As you can see, I'm obviously leaning towards the second proposal as well. Then supposing we go for that and in order to reach maximum flexibility, here is what we could do:
If keeping the current speed levels in order to reduce user changes required is desirable, then we could add a Also, only the linear-to-rotational automatic mapping is proposed for the enum SpeedKind {
Linear(f64),
Rotational(f64),
} This way, we could keep We could go even further by letting the user provide the arbitrary function used to convert from linear to rotational speeds and vice-versa, while still keeping a default one. That may be a bit too much however, considering the scope of this issue. All these proposed changes would require breaking a lot of things and overhauling most of the |
Thanks for providing your thoughts @PaulDance. I definitely see the logic behind your proposals and I share your concerns about overcomplicating this API. Overall, I am okay with making breaking changes here. We don't need to have integer speed levels. LOGO has no concept of speed (lines are drawn instantaneously). This was a concept added by the Python implementation. It's better to make these kinds of changes now. I'm glad we're discussing it. Here's a proposal that merges both of our ideas, but makes it far less flexible in an attempt to keep it simple:
Leaving things unspecified gives us some opportunity to change the inner implementation details as long as we don't change any of the behaviour of the resulting program. Having only one value but not specifying its unit allows us to choose a reasonable mapping to both translation speed and rotation speed. I don't think most users will want to care about specifying precise/different values for translation and rotation speed. If they do, this API leaves the option open for us to provide another type later that allows them to do that. e.g. a As for the question of how we decide the mapping between speed value and translation/rotation speed: the goal should be for the translation and rotation speed to "feel" roughly the same. That is, if I set the speed to
This creates a notion of "moving by 1 px" and "rotating by 1 px" which I am hoping will turn out to be quite intuitive and fulfill the goal stated above. We can always figure out something else if this doesn't work. Unfortunately, the speed API is so important that we don't have the luxury of marking |
I think most of what you proposed is a good idea, but also that some details will reveal themselves upon implementing the changes. |
The Python turtle module has 10 speed levels. The turtle crate started with 10 speed levels, but after getting impatient with how slow many drawings were, I changed that to 25 speed levels.
Recently, while working on the new architecture in #173, I realized that because of physics (
time = distance / speed
) and because of IPC latency, there is a limit to how much increasing the speed can decrease the time it takes to draw an image:Image generated with data collected from
examples/speedtest.rs
before the changes in #173As you can see, after level 10, changing the speed impacts the time less and less. This is frustrating as a user because it means that 15 of the speed levels are pretty much useless. In #173, I rewrote the code so that changing the speed has a linear effect on the time:
Image generated with data collected from
examples/speedtest.rs
after the changes in #173I thought this would be better, but it turns out to be even worse because now there is barely any visible difference between speed levels. The difference is always the same, but that turns out to not be all that intuitive because I guess our brains expect the
time = distance / speed
equation from physics.Proposals
Proposal 1: We should go back to having 10 speed levels, just like the Python turtle module. We should set the speed to increase linearly and go back to
time = distance / speed
. We can play with the graphs shown above until we get a curve that provides a reasonable distribution of different times. Having two speed levels that result in almost the same time isn't very useful.Proposal 2: Instead of a hardcoded set of 10 levels, the speed should become an actual quantity in pixels / second (or some other unit). That way the user is free to set their speed to whatever they want and there will be no limits. I like this idea because of the flexibility it provides, but it will be breaking compatibility with the Python turtle module and other turtle implementations. (Compatibility isn't an explicit goal, but it is nice to have.) It's also important to note that the speed value is used for rotation too, so we may have to think about how to map a speed to both px / sec and rad / sec.
So far, I am leaning towards Proposal 2. I think it's better to make that kind of breaking change now and give users the most flexibility. We will still have the speed strings (e.g. "slow", "normal", etc.). That means that there is an easier to teach option in addition to all the flexibility. We may even be able to come up with something to make that proposal backwards compatible so we would have both the speed levels and the ability to specify an absolute speed in px / sec or rad / sec.
Thoughts on as well as alternative proposals for what we should do are welcome.
Questions
These are questions that need to be resolved by the end of this:
The code, examples, and documentation then need to be updated with what we decide.
The text was updated successfully, but these errors were encountered: