As part of the never ending Weather station project I’m making a rotary dial morph that can be used to display things such as barometers, speedometers, vu meters, clocks, compasses etc - pretty much anything where a needle thing rotates about a pivot in order to point to a value on a scale.
Clearly one can be ultra simplistic and use a LineMorph over a CircleMorph but that isn't terribly pretty. Right now I have things set up to simply add submorphs to build whatever background and borders and tick marks are wanted, plus the needle. With an ImageMorph (or should it be a SketchMorph?) providing a picture of the dial/scale/frame it can look quite nice. However, the needle is a problem. A simple Line or PolygonMorph can be used and then it is possible to set the rotationCenter such that subsequent #rotationDegrees: make it turn about that centre. So far, so good. I’d prefer to allow arbitrary morphs for the needle - again, an image would be good in a lot of cases - but I cannot for the life of me find how to make general morphs rotate about a set point. I can use #rotationCenter: and the value is stuck in the extension as expected. If I use the halo rotate after doing that the new center point is clearly shown in the right place BUT it still rotates about the center of the bounds. I can’t find any illuminating usages of #rotationCenter to show how the new center point is used and certainly nothing that makes it look like it is ever treated as the pivot. I’ve dug into using asFlexShell and friends with no improvement. I’ve searched through the swiki. I’ve compared a 5.0 image with the 6alpha image. To cause further concern pretty much all the rotate related code I can find seems to be in the EToys package, which may mean it would go away when we make a more typical release image. Isn’t rotating morphs a relatively basic part of using them? What have I missed, or looked at without actually seeing? tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Strange OpCodes: LTT: Lose Timing Track |
how about | secondHand | On 4/6/17 6:07 PM, tim Rowledge wrote:
As part of the never ending Weather station project I’m making a rotary dial morph that can be used to display things such as barometers, speedometers, vu meters, clocks, compasses etc - pretty much anything where a needle thing rotates about a pivot in order to point to a value on a scale. Clearly one can be ultra simplistic and use a LineMorph over a CircleMorph but that isn't terribly pretty. Right now I have things set up to simply add submorphs to build whatever background and borders and tick marks are wanted, plus the needle. With an ImageMorph (or should it be a SketchMorph?) providing a picture of the dial/scale/frame it can look quite nice. However, the needle is a problem. A simple Line or PolygonMorph can be used and then it is possible to set the rotationCenter such that subsequent #rotationDegrees: make it turn about that centre. So far, so good. I’d prefer to allow arbitrary morphs for the needle - again, an image would be good in a lot of cases - but I cannot for the life of me find how to make general morphs rotate about a set point. I can use #rotationCenter: and the value is stuck in the extension as expected. If I use the halo rotate after doing that the new center point is clearly shown in the right place BUT it still rotates about the center of the bounds. I can’t find any illuminating usages of #rotationCenter to show how the new center point is used and certainly nothing that makes it look like it is ever treated as the pivot. I’ve dug into using asFlexShell and friends with no improvement. I’ve searched through the swiki. I’ve compared a 5.0 image with the 6alpha image. To cause further concern pretty much all the rotate related code I can find seems to be in the EToys package, which may mean it would go away when we make a more typical release image. Isn’t rotating morphs a relatively basic part of using them? What have I missed, or looked at without actually seeing? tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Strange OpCodes: LTT: Lose Timing Track |
Thanks Bob,
> On 06-04-2017, at 3:52 PM, Bob Arning <[hidden email]> wrote: > > | secondHand | > secondHand _ Morph new extent: 3@50; color: Color yellow. > holder _ Morph new extent: 1@1; position: 100@100. > secondHand bottomRight: 0@0. > holder openInWorld. > flex _ holder addFlexShell. > holder addMorph: secondHand. > 1 to: 30 do: [ :i | > flex angle: Float pi * (i/30.0) negated. > World displayWorldSafely. > (Delay forSeconds: 1) wait > ]. > flex explore That’s… interesting. So by putting the morph I care about into a ‘fake morph’ that doesn’t even enclose it and rotating that in a TransformationMorph it does pretty much what I need. Really clever and completely not what I’d ever expect. Has to be a more easily usable approach that we can come up with to do this, surely. What is the purpose of the entire rotationCenter thing if not to make it be the center of any following rotations? tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim May the bugs of many programs nest on your hard drive. |
In reply to this post by timrowledge
Hi Tim,
We made a nice analog gauge with rotating needle for our app and used NCLineMorph from the Connectors package because it draws gorgeous -- anti-aliased, and we set the rotation center a little down from one end, so it looks good. Here's the code: initializeNeedle needle := (NCLineMorph vertices: { Point x: (self center x + 1) y: (self bounds origin y + 1). Point x: (self center x + 1) y: (self bounds corner y - 4) } color: Color white borderWidth: 2 borderColor: Color white) rotationCenter: 0.5@0.9; yourself On Thu, Apr 6, 2017 at 5:07 PM, tim Rowledge <[hidden email]> wrote: > As part of the never ending Weather station project I’m making a rotary dial morph that can be used to display things such as barometers, speedometers, vu meters, clocks, compasses etc - pretty much anything where a needle thing rotates about a pivot in order to point to a value on a scale. > > Clearly one can be ultra simplistic and use a LineMorph over a CircleMorph but that isn't terribly pretty. Right now I have things set up to simply add submorphs to build whatever background and borders and tick marks are wanted, plus the needle. With an ImageMorph (or should it be a SketchMorph?) providing a picture of the dial/scale/frame it can look quite nice. > > However, the needle is a problem. A simple Line or PolygonMorph can be used and then it is possible to set the rotationCenter such that subsequent #rotationDegrees: make it turn about that centre. So far, so good. I’d prefer to allow arbitrary morphs for the needle - again, an image would be good in a lot of cases - but I cannot for the life of me find how to make general morphs rotate about a set point. I can use #rotationCenter: and the value is stuck in the extension as expected. If I use the halo rotate after doing that the new center point is clearly shown in the right place BUT it still rotates about the center of the bounds. I can’t find any illuminating usages of #rotationCenter to show how the new center point is used and certainly nothing that makes it look like it is ever treated as the pivot. > > I’ve dug into using asFlexShell and friends with no improvement. I’ve searched through the swiki. I’ve compared a 5.0 image with the 6alpha image. To cause further concern pretty much all the rotate related code I can find seems to be in the EToys package, which may mean it would go away when we make a more typical release image. Isn’t rotating morphs a relatively basic part of using them? > > What have I missed, or looked at without actually seeing? > > tim > -- > tim Rowledge; [hidden email]; http://www.rowledge.org/tim > Strange OpCodes: LTT: Lose Timing Track > > > |
In reply to this post by timrowledge
Well, here's a different approach that uses
a Form for the moving hand.
| f pt elapsed start morph deg f2 | On 4/6/17 7:23 PM, tim Rowledge wrote:
Thanks Bob,On 06-04-2017, at 3:52 PM, Bob Arning [hidden email] wrote: | secondHand | secondHand _ Morph new extent: 3@50; color: Color yellow. holder _ Morph new extent: 1@1; position: 100@100. secondHand bottomRight: 0@0. holder openInWorld. flex _ holder addFlexShell. holder addMorph: secondHand. 1 to: 30 do: [ :i | flex angle: Float pi * (i/30.0) negated. World displayWorldSafely. (Delay forSeconds: 1) wait ]. flex exploreThat’s… interesting. So by putting the morph I care about into a ‘fake morph’ that doesn’t even enclose it and rotating that in a TransformationMorph it does pretty much what I need. Really clever and completely not what I’d ever expect. Has to be a more easily usable approach that we can come up with to do this, surely. What is the purpose of the entire rotationCenter thing if not to make it be the center of any following rotations? tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim May the bugs of many programs nest on your hard drive. |
In reply to this post by timrowledge
One more - with an arbitrary morph
| secondHand flex pos elapsed start rads
| On 4/6/17 7:23 PM, tim Rowledge wrote:
Thanks Bob,On 06-04-2017, at 3:52 PM, Bob Arning [hidden email] wrote: | secondHand | secondHand _ Morph new extent: 3@50; color: Color yellow. holder _ Morph new extent: 1@1; position: 100@100. secondHand bottomRight: 0@0. holder openInWorld. flex _ holder addFlexShell. holder addMorph: secondHand. 1 to: 30 do: [ :i | flex angle: Float pi * (i/30.0) negated. World displayWorldSafely. (Delay forSeconds: 1) wait ]. flex exploreThat’s… interesting. So by putting the morph I care about into a ‘fake morph’ that doesn’t even enclose it and rotating that in a TransformationMorph it does pretty much what I need. Really clever and completely not what I’d ever expect. Has to be a more easily usable approach that we can come up with to do this, surely. What is the purpose of the entire rotationCenter thing if not to make it be the center of any following rotations? tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim May the bugs of many programs nest on your hard drive. |
I think I’m starting to make sense of these damned transformation morphs, though it’s a bit confusing in some areas.
> On 06-04-2017, at 7:43 PM, Bob Arning <[hidden email]> wrote: > | secondHand flex pos elapsed start rads | > > pos _ 100@100. > secondHand _ (StringMorph contents: 'seconds') color: Color magenta. > flex _ TransformationMorph new. > flex addMorph: secondHand. > secondHand position: 0@0. > flex position: pos. > flex offset: secondHand position. > flex openInWorld explore. > start _ Time millisecondClockValue. > [elapsed _ Time millisecondClockValue - start. elapsed < 60000] whileTrue: [ > rads _ Float twoPi * (elapsed \\ 60000) / 60000. > flex angle: rads negated. > World displayWorldSafely. This is much more like it. No strange intermediate morphs masquerading as our friend. It’s as if it all makes sense. Briefly, at least, whilst the drugs keep their hold. If we change to | secondHand flex pos | pos := 500@200. secondHand := (RectangleMorph new extent: 10@100) color: Color red. flex := TransformationMorph new. flex addMorph: secondHand. secondHand position: -5@ -100. “<— set the bottom centre to be at the parent’s 0@0" flex position: pos. "flex offset: 0@0. <— don’t seem to need this" flex openInWorld explore. start := Time millisecondClockValue. [elapsed := Time millisecondClockValue - start. elapsed < 60000] whileTrue: [ rads := Float twoPi * (elapsed \\ 60000) / 60000. flex angle: rads negated. World displayWorldSafely. (Delay forMilliseconds: 100) wait ] … then we get a nice chubby needle rotating about the middle of its bottom edge, which is a typical want if we have a simple morph-drawn needle. There does seem to be some odd behaviour when one changes the offset and rotates things; the bounds can end up moving in not-yet obvious ways and then things get confusing. Fiddling with the `secondHand position: ` seems to work ok as a way to choose any point as the pivot, which is what we’d need for an image of an ornate needle we want to use. Like this one - http://www.cjhclocks.com/images/uploads/large/barometer_silver-face_404.jpg Of course, one of the next tricks is to find someone with the ‘shoop skills to take an image like that and separate out the needle and dial face as separate images. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Strange OpCodes: RDL: Rotate Disk Left |
photoshop is for sissies. use squeak ;-)
| secondHand flex pos elapsed rads start
fancy bottomHalf smaller | On 4/7/17 2:18 PM, tim Rowledge wrote:
I think I’m starting to make sense of these damned transformation morphs, though it’s a bit confusing in some areas.On 06-04-2017, at 7:43 PM, Bob Arning [hidden email] wrote: | secondHand flex pos elapsed start rads | pos _ 100@100. secondHand _ (StringMorph contents: 'seconds') color: Color magenta. flex _ TransformationMorph new. flex addMorph: secondHand. secondHand position: 0@0. flex position: pos. flex offset: secondHand position. flex openInWorld explore. start _ Time millisecondClockValue. [elapsed _ Time millisecondClockValue - start. elapsed < 60000] whileTrue: [ rads _ Float twoPi * (elapsed \\ 60000) / 60000. flex angle: rads negated. World displayWorldSafely.This is much more like it. No strange intermediate morphs masquerading as our friend. It’s as if it all makes sense. Briefly, at least, whilst the drugs keep their hold. If we change to | secondHand flex pos | pos := 500@200. secondHand := (RectangleMorph new extent: 10@100) color: Color red. flex := TransformationMorph new. flex addMorph: secondHand. secondHand position: -5@ -100. “<— set the bottom centre to be at the parent’s 0@0" flex position: pos. "flex offset: 0@0. <— don’t seem to need this" flex openInWorld explore. start := Time millisecondClockValue. [elapsed := Time millisecondClockValue - start. elapsed < 60000] whileTrue: [ rads := Float twoPi * (elapsed \\ 60000) / 60000. flex angle: rads negated. World displayWorldSafely. (Delay forMilliseconds: 100) wait ] … then we get a nice chubby needle rotating about the middle of its bottom edge, which is a typical want if we have a simple morph-drawn needle. There does seem to be some odd behaviour when one changes the offset and rotates things; the bounds can end up moving in not-yet obvious ways and then things get confusing. Fiddling with the `secondHand position: ` seems to work ok as a way to choose any point as the pivot, which is what we’d need for an image of an ornate needle we want to use. Like this one - http://www.cjhclocks.com/images/uploads/large/barometer_silver-face_404.jpg Of course, one of the next tricks is to find someone with the ‘shoop skills to take an image like that and separate out the needle and dial face as separate images. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Strange OpCodes: RDL: Rotate Disk Left |
Nice.
But the code blocks the UI for 60 seconds. :-( --Hannes On 4/7/17, Bob Arning <[hidden email]> wrote: > photoshop is for sissies. use squeak ;-) > > > | secondHand flex pos elapsed rads start fancy bottomHalf smaller | > > fancy _ Form extent: 500@100 depth: 32. > fancy fillColor: Color white. > fancy getCanvas > fillOval: (5@5 extent: 90@90) color: Color black; > fillOval: (0@15 extent: 70@70) color: Color white; > fillRectangle: (400@20 extent: 60@60) color: Color black; > fillOval: (300@(-348) extent: 400@400) color: Color white; > fillRectangle: (90@48 extent: 400@4) color: Color black. > bottomHalf _ fancy copy: (0@0 extent: fancy width @ (fancy height > // 2)). > bottomHalf flipVertically. > bottomHalf displayOn: fancy at: 0@(fancy height//2). > fancy replaceColor: Color white withColor: Color transparent. > > pos _ 500@200. > smaller _ fancy magnify: fancy boundingBox by: 0.25 smoothing: 2. > secondHand _ smaller asMorph. > flex _ TransformationMorph new. > flex addMorph: secondHand. > secondHand position: smaller boundingBox center negated. > flex position: pos. > flex openInWorld explore. > start _ Time millisecondClockValue. > [elapsed _ Time millisecondClockValue - start. elapsed < 60000] > whileTrue: [ > rads _ Float twoPi * (elapsed \\ 60000) / 60000. > flex angle: rads negated. > World displayWorldSafely. > (Delay forMilliseconds: 100) wait > ] > > > On 4/7/17 2:18 PM, tim Rowledge wrote: >> I think I’m starting to make sense of these damned transformation morphs, >> though it’s a bit confusing in some areas. >> >>> On 06-04-2017, at 7:43 PM, Bob Arning <[hidden email]> wrote: >>> | secondHand flex pos elapsed start rads | >>> >>> pos _ 100@100. >>> secondHand _ (StringMorph contents: 'seconds') color: Color >>> magenta. >>> flex _ TransformationMorph new. >>> flex addMorph: secondHand. >>> secondHand position: 0@0. >>> flex position: pos. >>> flex offset: secondHand position. >>> flex openInWorld explore. >>> start _ Time millisecondClockValue. >>> [elapsed _ Time millisecondClockValue - start. elapsed < 60000] >>> whileTrue: [ >>> rads _ Float twoPi * (elapsed \\ 60000) / 60000. >>> flex angle: rads negated. >>> World displayWorldSafely. >> This is much more like it. No strange intermediate morphs masquerading as >> our friend. It’s as if it all makes sense. Briefly, at least, whilst the >> drugs keep their hold. >> >> If we change to >> | secondHand flex pos | >> >> pos := 500@200. >> secondHand := (RectangleMorph new extent: 10@100) color: Color red. >> flex := TransformationMorph new. >> flex addMorph: secondHand. >> secondHand position: -5@ -100. “<— set the bottom centre to be at the >> parent’s 0@0" >> flex position: pos. >> "flex offset: 0@0. <— don’t seem to need this" >> flex openInWorld explore. >> start := Time millisecondClockValue. >> [elapsed := Time millisecondClockValue - start. elapsed < 60000] >> whileTrue: [ >> rads := Float twoPi * (elapsed \\ 60000) / 60000. >> flex angle: rads negated. >> World displayWorldSafely. >> (Delay forMilliseconds: 100) wait >> ] >> … then we get a nice chubby needle rotating about the middle of its bottom >> edge, which is a typical want if we have a simple morph-drawn needle. >> There does seem to be some odd behaviour when one changes the offset and >> rotates things; the bounds can end up moving in not-yet obvious ways and >> then things get confusing. >> >> Fiddling with the `secondHand position: ` seems to work ok as a way to >> choose any point as the pivot, which is what we’d need for an image of an >> ornate needle we want to use. Like this one - >> http://www.cjhclocks.com/images/uploads/large/barometer_silver-face_404.jpg >> >> Of course, one of the next tricks is to find someone with the ‘shoop >> skills to take an image like that and separate out the needle and dial >> face as separate images. >> >> tim >> -- >> tim Rowledge; [hidden email]; http://www.rowledge.org/tim >> Strange OpCodes: RDL: Rotate Disk Left >> >> >> > > |
In reply to this post by Bob Arning-2
> On 07-04-2017, at 12:09 PM, Bob Arning <[hidden email]> wrote: > > photoshop is for sissies. use squeak ;-) Nice. |head hat flex| head := CircleMorph new extent: 40@40. head color: Color salmon lighter twiceLighter twiceLighter. head position: 200@200. head openInWorld. hat := Form extent: 45@35 depth: 32. hat fillColor: Color transparent. hat getCanvas fillRectangle: (10@0 extent: 25@30) color: Color black; fillOval: (0@28 extent: 45@7) color: Color black. hat := hat asMorph. hat position: 30@ -40. flex := TransformationMorph new. flex addMorph: hat. flex position: 195@170. flex openInWorld. 0 to: -30 by: -2 do:[:v| flex rotationDegrees: v. (Delay forMilliseconds: 50) wait. World displayWorldSafely]. -30 to: 0 by: 2 do:[:v| flex rotationDegrees: v. (Delay forMilliseconds: 50) wait. World displayWorldSafely]. (Delay forMilliseconds: 1500) wait. flex delete. head delete I must admit at first I thought you were proposing an image filtering operation until I noticed the lack of filename. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Useful random insult:- He's not a complete idiot -- some parts are missing. |
Cool! Be sure to post a picture of the gizmo
when it's finished. On 4/7/17 6:11 PM, tim Rowledge wrote:
On 07-04-2017, at 12:09 PM, Bob Arning [hidden email] wrote: photoshop is for sissies. use squeak ;-)Nice. |head hat flex| head := CircleMorph new extent: 40@40. head color: Color salmon lighter twiceLighter twiceLighter. head position: 200@200. head openInWorld. hat := Form extent: 45@35 depth: 32. hat fillColor: Color transparent. hat getCanvas fillRectangle: (10@0 extent: 25@30) color: Color black; fillOval: (0@28 extent: 45@7) color: Color black. hat := hat asMorph. hat position: 30@ -40. flex := TransformationMorph new. flex addMorph: hat. flex position: 195@170. flex openInWorld. 0 to: -30 by: -2 do:[:v| flex rotationDegrees: v. (Delay forMilliseconds: 50) wait. World displayWorldSafely]. -30 to: 0 by: 2 do:[:v| flex rotationDegrees: v. (Delay forMilliseconds: 50) wait. World displayWorldSafely]. (Delay forMilliseconds: 1500) wait. flex delete. head delete I must admit at first I thought you were proposing an image filtering operation until I noticed the lack of filename. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Useful random insult:- He's not a complete idiot -- some parts are missing. |
On 07-04-2017, at 3:40 PM, Bob Arning <[hidden email]> wrote: Still need to work out a good way to lay out the markings, ticks, lettering etc. Or, do that ‘shooping to just cheat and use an image grabbed from the net. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Useful random insult:- So dumb, he faxes face up. |
Free forum by Nabble | Edit this page |