It is currently April 26th, 2024, 6:26 am

ImageRotate or rounding error problem?

Report bugs with the Rainmeter application and suggest features.
User avatar
Yincognito
Rainmeter Sage
Posts: 7164
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

ImageRotate or rounding error problem?

Post by Yincognito »

First, I thought there was something wrong with my images, but then I downloaded/centered a similar image from Wikipedia...

Skin:

Code: Select all

[Variables]
Size=512

[Rainmeter]
Update=25
DynamicWindowSize=1
AccurateText=1

---Measures---

[Angle]
Measure=Calc
Formula=((360+Angle+5)%360)
DynamicVariables=1

---Meters---

[Container]
Meter=Image
W=(#Size#)
H=(#Size#)
SolidColor=0,0,0,255
DynamicVariables=1

[Circle]
Container=Container
Meter=Image
ImageName=#@#Circle.png
DynamicVariables=1

; This rotates without wobble/shaking
;W=(#Size#)
;H=(#Size#)
;TransformationMatrix=(Cos(Rad([Angle:])));(-Sin(Rad([Angle:])));(Sin(Rad([Angle:])));(Cos(Rad([Angle:])));(#Size#/2*(1-Sin(Rad([Angle:]))-Cos(Rad([Angle:]))));(#Size#/2*(1+Sin(Rad([Angle:]))-Cos(Rad([Angle:]))))

; This rotates with wobble/shaking
X=(#Size#/2*(1-Abs(Sin(Rad(-[Angle:])))-Abs(Cos(Rad(-[Angle:])))))
Y=(#Size#/2*(1-Abs(Sin(Rad(-[Angle:])))-Abs(Cos(Rad(-[Angle:])))))
W=(#Size#*(Abs(Sin(Rad(-[Angle:])))+Abs(Cos(Rad(-[Angle:])))))
H=(#Size#*(Abs(Sin(Rad(-[Angle:])))+Abs(Cos(Rad(-[Angle:])))))
ImageRotate=(-[Angle:])
Image (placed in @Resources):
Circle.png
Expected result: circle rotates without "shaking" or "wobbling"
Actual Result: shaking / wobbling is visible if you look closely at the white fill to the grey border areas
Note: I'm not sure if this is an issue based on the image meter's integer (?) dimensions, rounding errors or an unwanted "feature" of the ImageRotate option, but as you can see when using the commented TransformationMatrix part, rotation without wobbling is entirely possible and there was no need to adjust the code for rounding errors there. I would like the ImageRotate variant to work the same way in terms of visual stability.
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Re: ImageRotate or rounding error problem?

Post by death.crafter »

It wobbles cause x and y can't be decimal numbers. And rounding it will make it oscillate between two values, causing it to wobble. Try flooring or ceiling it. It may be more stable.
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 7164
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: ImageRotate or rounding error problem?

Post by Yincognito »

death.crafter wrote: October 18th, 2021, 5:11 am It wobbles cause x and y can't be decimal numbers. And rounding it will make it oscillate between two values, causing it to wobble. Try flooring or ceiling it. It may be more stable.
Yeah, I was afraid it was that. :( I tried all the Round(), Trunc() (I prefer it over Floor()) and Ceil() combinations I could think of, I even un-factored the expression to better handle the "integer parts" as per Rainmeter (i.e. the values expressing a position or dimension, which are integered by Rainmeter), but had no luck. I'm aware that what I expect isn't that logical from a technical POV - I mean one just can't make integer values to produce the effect of fractional values - but it is from a visual POV, especially when comparing with how TransformationMatrix works.

I'm not sure what is the difference between the two in terms of positioning and dimensioning (maybe TM handles this from the center of rotation out, or expects to have fractional values, similar to how Shape meters behave in certain cases?), but one thing I noticed and I find interesting is that the wobbling effect happens almost exclusively towards the left-top and right-bottom sides of the meter/image, and almost no effect (absolutely no effect actually in my actual scenario, which you probably realized is that earth globe of mine) in the right-top and left-bottom sides. Now, on a first look, this might be consistent with your idea that it's the X and Y (and less the W and H) that need some slight adjustment - I even commented out the W and H and the effect is present, so that seems to suggest the same - but even so, the effect should be seen in the latter sides of the meter/image too (just tested out by setting X=1 and Y=1 to the TransformationMatrix part, and you can see how it wobbles there as well). Strangely, those areas seem to be immune to this wobbling - I wonder why... :???:

EDIT: I just tested the unaffected sides with the TransformationMatrix part (this time properly), using:

Code: Select all

[Variables]
ShiftX=0
ShiftY=0

[Circle]
...
TransformationMatrix=(Cos(Rad([Angle:])));(-Sin(Rad([Angle:])));(Sin(Rad([Angle:])));(Cos(Rad([Angle:])));(#Size#/2*(1-Sin(Rad([Angle:]))-Cos(Rad([Angle:])))+#ShiftX#);(#Size#/2*(1+Sin(Rad([Angle:]))-Cos(Rad([Angle:])))+#ShiftY#)
OnUpdateAction=[!SetVariable ShiftX (1-#ShiftX#)][!SetVariable ShiftY (1-#ShiftY#)]
and alternatively shifting X and Y by 1 or 0 is indeed not causing a visible effect on the right-top and left-bottom sides, so you can disregard the last part of my message above.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5406
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: ImageRotate or rounding error problem?

Post by eclectic-tech »

"Meters are Rectangles ... Always were ... Always will be" ;-)

Not a solution to your issue, just my observation...
I agree that it would be desirable to have more than only 2 options for rotating.

The Image meter, unlike TransformationMatrix, has to deal with an image inside a rectangular meter.

The Image meter currently only has 2 options to rotating a meter:
1) Rotate the meter, keeping the original image size, and increasing the meter dimensions
OR
2) Resizing the image to fit inside the defined meter width and height.

Neither of these options will keep both the image position and image size; one or the other will change which cause the wobbling.
TransformationMatrix ignores the original meter size and so does not have the meter limits to deal with.

Perhaps the DEV Team can find a solution that corrects so images can remain centered and not resized.

Demo code of how ImageRotate currently deals rectangular meters (left-click to change between the 2 options)

Code: Select all

[Variables]
Size=512
ImgNum=0

[Rainmeter]
Update=64
DynamicWindowSize=1
AccurateText=1
BackgroundMode=2
SolidColor=255,0,255
SkinWidth=(sqrt(#Size#**2+#Size#**2))
SkinHeight=(sqrt(#Size#**2+#Size#**2))

---Measures---

[Angle]
Measure=Calc
Formula=((360+Angle+1)%360)
DynamicVariables=1

---Meters---

[Circle0]
Meter=Image
ImageName=#@#Circle512.png
DynamicVariables=1
LeftMouseUpAction=[!HideMeter Circle[#ImgNum]][!SetVariable ImgNum (1-#ImgNum#)][!ShowMeter Circle[#ImgNum]][!UpdateMeter *][!Redraw]

; This rotates without wobble/shaking
; W=(#Size#)
; H=(#Size#)
; TransformationMatrix=(Cos(Rad([Angle:])));(-Sin(Rad([Angle:])));(Sin(Rad([Angle:])));(Cos(Rad([Angle:])));(#Size#/2*(1-Sin(Rad([Angle:]))-Cos(Rad([Angle:]))));(#Size#/2*(1+Sin(Rad([Angle:]))-Cos(Rad([Angle:]))))

; This rotates with wobble/shaking
; W=512
; H=512
ImageRotate=(-[Angle:])
Hidden=0
ToolTipTitle=Width/Height NOT Defined
TooltipText=Meter is resized to fit the original image dimensions

[Circle1]
Meter=Image
ImageName=#@#Circle512.png
DynamicVariables=1
LeftMouseUpAction=[!HideMeter Circle[#ImgNum]][!SetVariable ImgNum (1-#ImgNum#)][!ShowMeter Circle[#ImgNum]][!UpdateMeter *][!Redraw]

; This rotates without wobble/shaking
; W=(#Size#)
; H=(#Size#)
; TransformationMatrix=(Cos(Rad([Angle:])));(-Sin(Rad([Angle:])));(Sin(Rad([Angle:])));(Cos(Rad([Angle:])));(#Size#/2*(1-Sin(Rad([Angle:]))-Cos(Rad([Angle:]))));(#Size#/2*(1+Sin(Rad([Angle:]))-Cos(Rad([Angle:]))))

; This rotates with wobble/shaking
W=512
H=512
ImageRotate=(-[Angle:])
Hidden=1
ToolTipTitle=Width/Height ARE Defined
TooltipText=Image is resized to fit the original meter dimensions

imagerotate1.png
You do not have the required permissions to view the files attached to this post.
User avatar
Yincognito
Rainmeter Sage
Posts: 7164
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: ImageRotate or rounding error problem?

Post by Yincognito »

eclectic-tech wrote: October 18th, 2021, 1:41 pmNot a solution to your issue, just my observation...
Well, your observation (which I was aware of) was helpful indeed, because it made clear what would a "half solution" look like:

Code: Select all

[Variables]
Size=512
Scale=1.5

[Rainmeter]
Update=25
DynamicWindowSize=1
AccurateText=1

---Measures---

[Angle]
Measure=Calc
Formula=((360+Angle+5)%360)
DynamicVariables=1

---Meters---

[Container]
Meter=Image
W=(#Size#*#Scale#)
H=(#Size#*#Scale#)
SolidColor=0,0,0,255
DynamicVariables=1

[Circle]
Container=Container
Meter=Image
ImageName=#@#Circle.png
ImageRotate=(-[Angle:])
TransformationMatrix=(#Scale#);0;0;(#Scale#);((#Size#*#Scale#/2)*(1-Abs(Sin(Rad(-[Angle:])))-Abs(Cos(Rad(-[Angle:])))));((#Size#*#Scale#/2)*(1-Abs(Sin(Rad(-[Angle:])))-Abs(Cos(Rad(-[Angle:])))))
DynamicVariables=1
This won't wobble. It's a half solution because it doesn't exclusively use ImageRotate, X, Y, W and H to set things up, but resorts to TransformationMatrix to set the position appropriately (and to scale things up, since I also use this in my actual scenario). I would have liked the TransformationMatrix and ImageRotate variants to be mutually exclusive, because in certain cases, one is more efficient in terms of resource usage than the other (for me, this was the ImageRotate one, apart from the wobbling). The whole point in using multiple variants for the same operation was to find the "lightest" way to perform the animation, and mixing things like this kind of makes that point a little blurry since I have no idea which part of each method is heavier on the CPU/GPU (i.e. resizing, moving, rotating, skewing, etc) - I only have a general idea about the performance each (separate) method as a whole.

Oh well, since the Earth itself wobbles in its movement in real life, I guess it doesn't hurt that much that my animation also wobbles one pixel in certain cases... :confused:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5406
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: ImageRotate or rounding error problem?

Post by eclectic-tech »

A little wobble never hurts unless it's when leaving the bar ;-)

Yes, it would be great if both methods produced the same or similar results. But to preserve backward skin compatibility it may be difficult to have the ImageRotate method be able to fit a rotating image centered in a rectangle meter without these side effects.

TransformationMatrix is currently the only way to do this for now, since it is not bound by the original meter size. You just need to set the skin dimensions large enough to prevent clipping of the rotation done by the matrix.

Maybe a member better at mathematics than me (forgot most of what I learn in 4 years of honors math classes :oops: ) can find another solution. :sly:
User avatar
Yincognito
Rainmeter Sage
Posts: 7164
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: ImageRotate or rounding error problem?

Post by Yincognito »

eclectic-tech wrote: October 18th, 2021, 4:24 pm A little wobble never hurts unless it's when leaving the bar ;-)

Yes, it would be great if both methods produced the same or similar results. But to preserve backward skin compatibility it may be difficult to have the ImageRotate method be able to fit a rotating image centered in a rectangle meter without these side effects.

TransformationMatrix is currently the only way to do this for now, since it is not bound by the original meter size. You just need to set the skin dimensions large enough to prevent clipping of the rotation done by the matrix.

Maybe a member better at mathematics than me (forgot most of what I learn in 4 years of honors math classes :oops: ) can find another solution. :sly:
Nah, the math regarding the rotation is already done long time ago, as for the rounding errors I don't think math can provide a solution, since it's ingrained into how (image) meters are built. Backward compatibility doesn't seem to be an issue here since I'm not talking about changing something existent, but rather about "extending" the positioning possibilities to fractional ones - but yeah, this wouldn't be the easiest thing to do (if possible), so I understand if things stay as they are. I guess I was hoping for this to be a bug so it can be fixed, because rounding errors are bound to happen here and there and you have to live with them.
I never wobbled when leaving a bar, even when I should have... 8-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
balala
Rainmeter Sage
Posts: 16172
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: ImageRotate or rounding error problem?

Post by balala »

Didn't follow too closely the whole discussion, however just want to add that TransformationMatrix is the best tool to rotate images (in fact any kind of meter, including Image ones). It is extremely flexible and can apply a rotate and a resize in the same time. Additionally note that it can be applied for Button, Bar, or whatever meter, not just on Image meters (as said previously as well).
Sorry if I missed something which has been said previously...


EDIT: Yeah, sorry I indeed did missed something.
User avatar
Yincognito
Rainmeter Sage
Posts: 7164
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: ImageRotate or rounding error problem?

Post by Yincognito »

balala wrote: October 18th, 2021, 5:51 pm Didn't follow too closely the whole discussion, however just want to add that TransformationMatrix is the best tool to rotate images (in fact any kind of meter, including Image ones). It is extremely flexible and can apply a rotate and a resize in the same time. Additionally note that it can be applied for Button, Bar, or whatever meter, not just on Image meters (as said previously as well).
Sorry if I missed something which has been said previously...


EDIT: Yeah, sorry I indeed did missed something.
Yeah, no problem, in this case TransformationMatrix actually behaves better than the alternative, since it doesn't produce any wobbling - a valid reason to conclude that "older" things are not necessarily worse, and shouldn't be deprecated in the future (if a similarly capable alternative isn't offered, of course). If it weren't for the drawbacks, i.e. mouse action areas (this doesn't bother me in this case) and in some cases more CPU/GPU usage than the alternative (very hard to notice now on my new laptop) I would no doubt settle on TransformationMatrix as the sole method for the animation. As it is now, I'll keep my multi-method selective approach, as it not only allows seeing which variant is lighter on resources, but it can be very easily used as a comparison tool / skin for different methods.

By the way, I owe you an apology for the conversation we had a while back on resource usage in skins. I didn't realize how hard it is to see if a skin is using more resources than it should (i.e. performance flaws in the skin design) on a newer system, compared to an older one, with the increased CPU power and the GPU usually taking some of the burden away from the CPU. I miss my old laptop in that regard, I could immediately identify which skin wasn't designed to be performance efficient - on the newer one I'll probably have to lower my CPU frequency or take the GPU into account as well to have an idea about that aspect. It might be a new system, but my drive for efficiency and performance stays the same. :D
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
balala
Rainmeter Sage
Posts: 16172
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: ImageRotate or rounding error problem?

Post by balala »

Yincognito wrote: October 18th, 2021, 6:24 pm Yeah, no problem, in this case TransformationMatrix actually behaves better than the alternative, since it doesn't produce any wobbling - a valid reason to conclude that "older" things are not necessarily worse, and shouldn't be deprecated in the future (if a similarly capable alternative isn't offered, of course). If it weren't for the drawbacks, i.e. mouse action areas (this doesn't bother me in this case) and in some cases more CPU/GPU usage than the alternative (very hard to notice now on my new laptop) I would no doubt settle on TransformationMatrix as the sole method for the animation. As it is now, I'll keep my multi-method selective approach, as it not only allows seeing which variant is lighter on resources, but it can be very easily used as a comparison tool / skin for different methods.

By the way, I owe you an apology for the conversation we had a while back on resource usage in skins. I didn't realize how hard it is to see if a skin is using more resources than it should (i.e. performance flaws in the skin design) on a newer system, compared to an older one, with the increased CPU power and the GPU usually taking some of the burden away from the CPU. I miss my old laptop in that regard, I could immediately identify which skin wasn't designed to be performance efficient - on the newer one I'll probably have to lower my CPU frequency or take the GPU into account as well to have an idea about that aspect. It might be a new system, but my drive for efficiency and performance stays the same. :D
As you see now, these days those small differences have started not to matter too much. Even if many are still using older / slower computers, more and more people are switching to new and much better systems. As this happens, the differences become to matter less and less.
And don't apologize. Those discussions are always welcomed. They (may) reveal some hidden mistakes, inadvertences, issues (and so on).