It is currently April 25th, 2024, 4:03 pm

I want to flip a clock to look like reflection on water

Get help with creating, editing & fixing problems with skins
User avatar
SilverAzide
Rainmeter Sage
Posts: 2605
Joined: March 23rd, 2015, 5:26 pm

Re: I want to flip a clock to look like reflection on water

Post by SilverAzide »

Yincognito wrote: March 21st, 2023, 7:13 pm I believe it's simply the tangent of the opposite skew angle multiplied with the vertical offset, the math seems to check out.

For example, in your code, if you use TransformationMatrix=1;0;(tan(rad(-15)));-1;(tan(rad(15))*144);290 it produces the correct result. It's the opposite skew angle because the vertical flip changes the sign of the angle, and if you move the skin in your top left corner of your screen, take a screenshot and measure the distance from the top of the image (or skin, in this case) to where the original digits end, you'll notice that 144 is precisely that height / offset.
Cool, thanks! I was actually needing this info for another skin I am using, so I'll give this a shot. I could not figure out the offset because the skin is scaled using that same TransformationMatrix (i.e., I know how to scale it, and I know how to skew it, but I could not figure out how to do both at the same time).
Gadgets Wiki GitHub More Gadgets...
User avatar
balala
Rainmeter Sage
Posts: 16169
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: I want to flip a clock to look like reflection on water

Post by balala »

SilverAzide wrote: March 21st, 2023, 8:53 pm (i.e., I know how to scale it, and I know how to skew it, but I could not figure out how to do both at the same time).
To apply two TransformationMatrix options to the same meter, you have to create both options as if each of them would be applied without the other. Then you have to multiply those matrices together, according to the corresponding rules. This procedure is a completely basic procedure in matrices operations, but obviously it's not obvious for all. Most important thing to keep in mind, is that the order of multiplication does matter this time (unlike in case of multiplication of numbers, where the order doesn't matter). If you don't know how to do this operation, there are sites which can do this for you (this for instance).
All related questions get very good answers in the Multiple Transformations in One! section of the Transformation Matrix Guide. Recommend to read it carefully, or if you're not got used to work with matrices, you probably will have to read it more times, but finally you can figure out how to do. If needed, I'll be happy to help you with this, if you are asking.
User avatar
Yincognito
Rainmeter Sage
Posts: 7164
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: I want to flip a clock to look like reflection on water

Post by Yincognito »

SilverAzide wrote: March 21st, 2023, 8:53 pm Cool, thanks! I was actually needing this info for another skin I am using, so I'll give this a shot. I could not figure out the offset because the skin is scaled using that same TransformationMatrix (i.e., I know how to scale it, and I know how to skew it, but I could not figure out how to do both at the same time).
No problem, I hope you'll be able to use the info in your other skin. In this case, I didn't even need to deal with matrix multiplication like balala mentioned, it was a matter of simple right triangle geometry. The catheti or sides of the right triangle are hypothenuse*cos(angle) for the adjacent one and hypothenuse*sin(angle) for the opposite one. To get the latter from the former (which is what we need, as the adjacent is the text height and the opposite is the text movement), you have to multiply the former with the tangent of the angle, since tan(angle)=sin(angle)/cos(angle) and the fraction dividers are reductible on such multiplications: [hypothenuse*cos(angle)] * tan(angle) = [hypothenuse*cos(angle)] * [sin(angle)/cos(angle)] = [hypothenuse*sin(angle)].

I got one more bonus for this particular case though: no more factors or multipliers to account for font glyph side bearings, simply set negative paddings for the text to get rid of the bearings and then the TM formulas can use the plain [TextMeter:YH] which now is stricly the text bounding box (at least in terms of height, didn't bother with the width):

Code: Select all

[Variables]
fontName=SegoeUI
colorText=255,255,255

[Rainmeter]
Update=1000
AccurateText=1
SkinHeight=280
SkinWidth=550

[measureTime]
Measure=Time
Format=%H:%M:%S

[styleTitle]
StringAlign=Center
StringCase=Upper
StringStyle=Bold
StringEffect=Shadow
FontEffectColor=255,0,0,0
FontFace=#fontName#
FontSize=100
AntiAlias=1
Padding=0,-49,0,-32

[meterTitle]
Meter=String
MeterStyle=styleTitle
MeasureName=measureTime
X=260
Y=0
FontColor=#ColorText#,200
Text=%1

[meterTitleFlip]
Meter=String
MeterStyle=styleTitle
MeasureName=measureTime
X=260
Y=0
Text=%1
FontColor=#ColorText#,100
TransformationMatrix=1;0;(tan(rad(-15)));-1;([meterTitle:YH]*tan(rad(15)));([meterTitle:YH]*2+0)
InlineSetting=GradientColor | 90 | #colorText#,100 ; 0.0 | #colorText#,0 ; 0.75 | #colorText#,0 ; 1.0
DynamicVariables=1
The +0 is the vertical gap between original and reflection, I let it there for clarity. The paddings will have to be adjusted if the font or its size changes. In theory, everything could be "parameterized" by creating the appropriate variables and using them in the corresponding places, e.g. create fontPadding=0,(-#fontSize#*0.49),0,(-#fontSize#*0.32) to use it like Padding=#fontPadding#, or create widthRatio=0.67 and charCount=8 to use them like X=(#fontSize#*#widthRatio#*#charCount#/2) on [meterTitle], but these are just various ways to write these things and don't help in avoiding value adjustments on changing the font anyway.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
SilverAzide
Rainmeter Sage
Posts: 2605
Joined: March 23rd, 2015, 5:26 pm

Re: I want to flip a clock to look like reflection on water

Post by SilverAzide »

balala wrote: March 21st, 2023, 9:16 pm
Yincognito wrote: March 21st, 2023, 11:22 pm
Thanks for the tips, guys. Somehow I'm still doing something wrong. When I skew something, then try to offset the skewing to get the "origin" of the shape back to it's original location, I'm off by some number of pixels even tho I think I have all the angles worked out. I suspect I'm missing something basic, but I can't figure out what (I think the Transformation Guide section titled "What the heck is Rainmeter doing?!" is what I'm running into, but with a skew). When I get time, I'll see if I can post something in a new thread, so this one won't get hijacked more than it already is... (Sorry OP!)
Gadgets Wiki GitHub More Gadgets...
User avatar
Yincognito
Rainmeter Sage
Posts: 7164
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: I want to flip a clock to look like reflection on water

Post by Yincognito »

SilverAzide wrote: March 22nd, 2023, 12:26 pm Thanks for the tips, guys. Somehow I'm still doing something wrong. When I skew something, then try to offset the skewing to get the "origin" of the shape back to it's original location, I'm off by some number of pixels even tho I think I have all the angles worked out. I suspect I'm missing something basic, but I can't figure out what (I think the Transformation Guide section titled "What the heck is Rainmeter doing?!" is what I'm running into, but with a skew). When I get time, I'll see if I can post something in a new thread, so this one won't get hijacked more than it already is... (Sorry OP!)
Does this help?

Code: Select all

[Variables]
Update=25
Zoom=1.0
Width=200
Height=100
Size=(Sqrt(#Width#**2+#Height#**2))
OffsetX=((#Size#-#Width#)/2)
OffsetY=((#Size#-#Height#)/2)
CenterX=(#Width#/2)
CenterY=(#Height#/2)
Angle=0
AngleIncrement=1
BackgroundColor=0,0,0,128
Color=255,240,0,255

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

---Measures---

[Angle]
Disabled=1
Measure=Calc
Formula=((Angle+#AngleIncrement#)%360)
OnUpdateAction=[!SetVariable Angle [Angle]][!UpdateMeter Image][!Redraw]
DynamicVariables=1

---Meters---

[Box]
Meter=Image
W=(#Size#*#Zoom#)
H=(#Size#*#Zoom#)
SolidColor=#BackgroundColor#
DynamicVariables=1

; Form: TransformationMatrix={scale x};{skew y};{skew x};{scale y};{move x};{move y}
; Zoom: TransformationMatrix=#Zoom#;0;0;#Zoom#;0;0
;       TransformationMatrix=#Zoom#;0;0;#Zoom#;((1-#Zoom#)*[#CURRENTSECTION#:X]);((1-#Zoom#)*[#CURRENTSECTION#:Y])
;       TransformationMatrix=#Zoom#;0;0;#Zoom#;((1-#Zoom#)*([#CURRENTSECTION#:X]+[#CURRENTSECTION#:W]/2));((1-#Zoom#)*([#CURRENTSECTION#:Y]+[#CURRENTSECTION#:H]/2))
; Tilt: TransformationMatrix=(Cos(Rad(#Angle#)));(-Sin(Rad(#Angle#)));(Sin(Rad(#Angle#)));(Cos(Rad(#Angle#)));((#OffsetX#+#CenterX#)-(#OffsetX#+#CenterX#)*Cos(Rad(#Angle#))-(#OffsetY#+#CenterY#)*Sin(Rad(#Angle#)));((#OffsetY#+#CenterY#)+(#OffsetX#+#CenterX#)*Sin(Rad(#Angle#))-(#OffsetY#+#CenterY#)*Cos(Rad(#Angle#)))
; More: 
; | zoomx  skewx  movex |   | zooma  skewa  movea |   | zoomx*zooma+skewx*skewb+movex*0  zoomx*skewa+skewx*zoomb+movex*0  zoomx*movea+skewx*moveb+movex*1 |
; | skewy  zoomy  movey | x | skewb  zoomb  moveb | = | skewy*zooma+zoomy*skewb+movey*0  skewy*skewa+zoomy*zoomb+movey*0  skewy*movea+zoomy*moveb+movey*1 |
; |   0      0      1   |   |   0      0      1   |   |     0*zooma+    0*skewb+    1*0      0*skewa+    0*zoomb+    1*0      0*movea+    0*moveb+    1*1 |

[Scale]
Meter=String
X=0r
Y=0r
SolidColor=0,255,0,255
Padding=5,2,5,2
AntiAlias=1
Text=S
UpdateDivider=-1
MouseScrollUpAction=[!SetVariable Zoom (Clamp(#Zoom#+0.1,0.1,10))][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetVariable Zoom (Clamp(#Zoom#-0.1,0.1,10))][!UpdateMeter *][!Redraw]
DynamicVariables=1

[Rotate]
Meter=String
X=5R
Y=0r
SolidColor=0,0,255,255
Padding=5,2,5,2
AntiAlias=1
Text=R
UpdateDivider=-1
MouseScrollUpAction=[!SetVariable AngleIncrement (Clamp(#AngleIncrement#+1,0,360))][!UpdateMeasure Angle][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetVariable AngleIncrement (Clamp(#AngleIncrement#-1,0,360))][!UpdateMeasure Angle][!UpdateMeter *][!Redraw]
DynamicVariables=1

[Image]
Meter=Image
SolidColor=#Color#
X=#OffsetX#
Y=#OffsetY#
W=#Width#
H=#Height#
; Zoom & Tilt
TransformationMatrix=(Cos(Rad(#Angle#))*#Zoom#);(-Sin(Rad(#Angle#))*#Zoom#);(Sin(Rad(#Angle#))*#Zoom#);(Cos(Rad(#Angle#))*#Zoom#);(((#OffsetX#+#CenterX#)-(#OffsetX#+#CenterX#)*Cos(Rad(#Angle#))-(#OffsetY#+#CenterY#)*Sin(Rad(#Angle#)))*#Zoom#);(((#OffsetY#+#CenterY#)+(#OffsetX#+#CenterX#)*Sin(Rad(#Angle#))-(#OffsetY#+#CenterY#)*Cos(Rad(#Angle#)))*#Zoom#)
; Skew
TransformationMatrix=1;(Tan(Rad(-#Angle#)));(Tan(Rad(-#Angle#)));1;(Tan(Rad(#Angle#))*([Image:Y]+#CenterY#));(Tan(Rad(#Angle#))*([Image:X]+#CenterX#))
LeftMouseUpAction=[!UnpauseMeasure Angle][!ToggleMeasure Angle][!UpdateMeasure Angle][!SetVariable Angle [Angle]][!SetVariable AngleIncrement 1]
MiddleMouseUpAction=[!TogglePauseMeasure Angle]
DynamicVariables=1
It's a simple sample skin I wrote a long time ago and improved over time. I used it now as a base to add the "skew only" ability as per the description of your objective (if I understood it correctly, that is) - you only have to comment the Zoom & Tilt TM and let the Skew TM uncommented in the [Image] meter.

As always with my skins, you can animate or scale via clicks and scrollings. You can set the origin by changing the CenterX or CenterY variables at the top, and you can perform the X or Y skewing exclusively by, say, multiplying the angle of the other axis (i.e. the axis you want to cancel out) with 0 in the TM string, according to the form of the option in the comments. Also in the comments, you can find some other potentially useful TM info, along with an already performed multiplication using the notations that correspond to the actions Rainmeter is doing for the respective matrix positions.

If it doesn't help, by all means, open a thread for that specific scenario and we'll surely get to the bottom of it. ;-)

P.S. I believe it should work with using the "normal" -Sin and Sin in the 2nd and 3rd position of the TM option, but you'd have to multiply the movements with another variation of the trigonometric functions accordingly too, so I let the Tan version you used earlier, given its overall simplicity.
Last edited by Yincognito on March 22nd, 2023, 6:41 pm, edited 1 time in total.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
balala
Rainmeter Sage
Posts: 16169
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: I want to flip a clock to look like reflection on water

Post by balala »

SilverAzide wrote: March 22nd, 2023, 12:26 pm When I get time, I'll see if I can post something in a new thread, so this one won't get hijacked more than it already is... (Sorry OP!)
TransformationMatrix is definitely not an easy option. Especially not, if you want to apply more effects to a meter, by one single TransformationMatrix. The math involved can give headache to anyone. But if you open a new topic with your question, I definitely will try to find a solution. Not sure will succeed, but at least I'll try. I am a huge "fan" of this extremely powerful option, I love it and already applied it many times, in many different circumstances, so let's see...