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

Strange behavior with rotations #335

Closed
jvoigtlaender opened this Issue Aug 6, 2015 · 5 comments

Comments

Projects
None yet
3 participants
@jvoigtlaender
Contributor

jvoigtlaender commented Aug 6, 2015

Moved over from elm/compiler#665.

Consider this code:

import Graphics.Element exposing (..)
import Graphics.Collage exposing (..)
import Color exposing (..)
import Time exposing (..)
import Signal exposing (..)

blacksquare : Form
blacksquare = filled black (square 400)

yogi : Form
yogi = toForm (image 200 200 "imgs/yogi.jpg")

rotating : Form -> Time -> Form
rotating form t = rotate (degrees (inMilliseconds t)) form

canvas : Time -> Element
canvas t = collage 500 500 [rotating blacksquare t, rotating yogi t]

main : Signal Element
main = map canvas (every (20*millisecond))

One would expect that both the black square and Yogi will rotate as time progresses. Both are rotated by the same function with the same argument. But only Yogi rotates.

@mgold observed that the behavior is correct if one replaces every (20*millisecond) by foldp (+) 0 (fps 30). So maybe it is an issue with large numbers.

@jvoigtlaender

This comment has been minimized.

Show comment
Hide comment
@jvoigtlaender

jvoigtlaender Aug 6, 2015

Contributor

It must have to do with different handling of rotations for "plain" Forms and for Forms that come from Elements. In particular, the black square will rotate if one replaces its definition

blacksquare = filled black (square 400)

by

blacksquare = toForm (collage 400 400 [filled black (square 400)])

So the question is:
Why does the output rendered for rotate t (toForm (collage 400 400 [ form ])) change as t changes, while the output of rotate t form does not change as t changes (for large t)?

Contributor

jvoigtlaender commented Aug 6, 2015

It must have to do with different handling of rotations for "plain" Forms and for Forms that come from Elements. In particular, the black square will rotate if one replaces its definition

blacksquare = filled black (square 400)

by

blacksquare = toForm (collage 400 400 [filled black (square 400)])

So the question is:
Why does the output rendered for rotate t (toForm (collage 400 400 [ form ])) change as t changes, while the output of rotate t form does not change as t changes (for large t)?

@jvoigtlaender

This comment has been minimized.

Show comment
Hide comment
@jvoigtlaender

jvoigtlaender Aug 6, 2015

Contributor

Okay, so:

  • "plain" Forms are rotated with this line, while
  • Forms that are actually embedded Elements are rotated with this line.

It appears one of these two methods works fine with large numbers (for the angle by which to rotate), while the other doesn't.

Contributor

jvoigtlaender commented Aug 6, 2015

Okay, so:

  • "plain" Forms are rotated with this line, while
  • Forms that are actually embedded Elements are rotated with this line.

It appears one of these two methods works fine with large numbers (for the angle by which to rotate), while the other doesn't.

@mgold

This comment has been minimized.

Show comment
Hide comment
@mgold

mgold Aug 6, 2015

Contributor

I did some profiling and Math.sin is not any slower for large inputs than small ones. However, it's possible ctx.rotate is slow for large angles. You could try theta = form.theta % (Math.PI * 2) and see if that does anything.

Contributor

mgold commented Aug 6, 2015

I did some profiling and Math.sin is not any slower for large inputs than small ones. However, it's possible ctx.rotate is slow for large angles. You could try theta = form.theta % (Math.PI * 2) and see if that does anything.

@jvoigtlaender

This comment has been minimized.

Show comment
Hide comment
@jvoigtlaender

jvoigtlaender Aug 6, 2015

Contributor

Yes, though I put the manipulation inside the ctx.rotate-call, to avoid the theta !== 0 test being affected by that modulo computation. See https://github.com/elm-lang/core/pull/338 (closing this here).

Contributor

jvoigtlaender commented Aug 6, 2015

Yes, though I put the manipulation inside the ctx.rotate-call, to avoid the theta !== 0 test being affected by that modulo computation. See https://github.com/elm-lang/core/pull/338 (closing this here).

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 6, 2015

Member

Thank you for figuring this out, great work! :D

Member

evancz commented Aug 6, 2015

Thank you for figuring this out, great work! :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment