Adventures in Rotation
Alex Tweedly
alex at tweedly.net
Sun Dec 4 20:04:55 EST 2005
Bill Marriott wrote:
>Ok, as our regular viewers know, I'm trying to mimic with Rev a pretty
>little clock distributed with Konfabulator. The way K. does this clock is to
>create little PNGs for each of the elements (second hand, minute hand, rim,
>background), package them up in XML, and animate (rotate) them in
>JavaScript.
>
>Attempt 4 (revised): revRotatePoly an irregular polygon
>
>So, I drew myself a pretty minute hand and then wrote a script.
>
>Code used:
>
>on mouseUp
> repeat with i = 1 to 360
> revRotatePoly the long ID of graphic "minuteHand",1
> wait for 50 milliseconds
> end repeat
>end mouseUp
>
>(I know the "wait for" method was not what I was going to use in my eventual
>stack, for performance reasons, but I just wanted to test out spinning it.)
>
>Well, running this script was a shocker. It had the effect of crumpling my
>pretty minute hand into a little ball. If you'd like to see what happens, go
>to revOnline under my space, "MerryOtter" -- the stack is, "Fun with
>revRotatePoly"
>
>
>
I rather like that effect - though it certainly shouldn't be called
"rotate" :-)
>My clock hand *is* pretty fancy, it's got 56 points. But the same thing
>happens with graphics of only 3 points. Open the stack and try the simplest
>kind of clock hand you could imagine with
><snip>
>
>
>#13) General flakiness. I would definitely say revCrumplePoly is a better
>name for the revRotatePoly command. Is there any situation where
>revRotatePoly could be useful? Not if it does this. Totally bugged. (I
>suspect the reason why is that Rev doesn't have fractional coordinates?
>Could such a limitation really result in such dramatic distortion? If this
>is the case, then Rev should store fractionals, but render to integers.)
>
>
>
I think your suspicion is entirely correct. I think it would be
generally very helpful if Rev would allow non-integer co-ords in the
points list, and simply round to integers before drawing.
I change the code to
> put the points of grc "minuteHand" into tPoints
> repeat with i = 1 to 360
> set the lockScreen to true
> set the points of grc "minuteHand" to tPoints
> revRotatePoly the long ID of graphic "minuteHand", i --
> note the change from "1" to "i" here
> set the lockScreen to false
> set the thumbposition of scrollbar "spinProgress" to i
> wait for 50 milliseconds
> end repeat
and it now does what it's intended to do. Though I really dislike what
it's intended to do - rotate the object, then translate it so as to keep
the top left of the bounding rectangle of the rotated shape the same.
We had a thread on rotating polygons back in March (to save you cracking
out the trig books), here is the code modified to use the rotate handler
I suggested then. Note this is written to emphasize readability rather
than performance - could probably be made faster if needed.
> on mouseUp
> put the points of grc "minuteHand" into tPoints
> repeat with i = 1 to 360
> set the lockScreen to true
> set the points of grc "minuteHand" to tPoints
> myRotatePoly the name of grc "minuteHand", i, 0, 24
> -- revRotatePoly the long ID of graphic "minuteHand", i
> set the lockScreen to false
> set the thumbposition of scrollbar "spinProgress" to i
> wait for 50 milliseconds with messages
> end repeat
> set the points of grc "minuteHand" to tPoints
> end mouseUp
>
> on myRotatePoly pGraphic, pAngle, basex, basey
> put the topLeft of pGraphic into tTopLeft
> put myPoints(pGraphic, basex, basey) into tPoints -- returns
> the list of points, relative to the base point
> put the loc of pGraphic into tLoc
> put sin(pAngle * (pi / 180)) into tSinAngle
> put cos(pAngle * (pi / 180)) into tCosAngle
> put (number of items of tPoints) div 2 into tNumItems
> repeat with i = 1 to tNumItems
> put (item (i + (i - 1)) of tPoints) into tCurrentH -- + item 1
> of the center
> put (item (i + i) of tPoints) into tCurrentV -- + item 2 of
> the center
> put trunc((tCosAngle * tCurrentH) - (tSinAngle * tCurrentV))
> into tTempH
> put trunc((tSinAngle * tCurrentH) + (tCosAngle * tCurrentV))
> into tTempV
> put tTempH + basex into tCurrentH -- and add back the base
> x and y
> put tTempV + basey into tCurrentV
> put tCurrentH,tCurrentV & comma after tFinalPoints
> end repeat
> delete last char of tFinalPoints
> set the points of pGraphic to tFinalPoints
> end myRotatePoly
>
> function myPoints pGraphic, basex, basey
> put the number of lines in the points of pGraphic into tNumPoints
> put empty into tResult
> put the points of pGraphic into tPoints
> put basex into tStartlH
> put basey into tStartV
>
> replace cr with comma in tPoints
> if last char of tPoints is comma then delete last char of tPoints
> repeat with i = 1 to tNumPoints
> put (item (i + (i - 1)) of tPoints) - tStartlH into tCurrentH
> put (item (i + i) of tPoints) - tStartV into tCurrentV
> put tCurrentH,tCurrentV & comma after tResult
> end repeat
> delete last char of tResult
> return tResult
> end myPoints
--
Alex Tweedly http://www.tweedly.net
--
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.1.362 / Virus Database: 267.13.11/191 - Release Date: 02/12/2005
More information about the use-livecode
mailing list