Hi guys,
First of all, I tried to do it on my own... But I never used FPU or anything except integers in masm.
I searched and found many possible examples here, But I sincerely need a straight algo so I can use it and learn from it.
I need to draw an Fuel gaude indicator.
I provide:
. the centre x , y coords
. the radius
. the angle (or rads, whatever)
So the algo can return the x , y coord for the given angle.
I know this is cold breakfast for all of you... I saw some JJ´s code that look quite clear but there were some MasmBasic there, I´m using Masm only.
The goal is to animate this nice Gauge pointer below:
(https://www.dropbox.com/s/k5qtjay5pm61mbw/gauge.bmp?raw=1)
PI_2 = 6.283185308 ;2*pi
Total_Steps = 360 ;Steps for a complete rotation
Degree = 45
Z_rotation:
s = sin( Degree / Total_Steps * PI_2 )
c = cos( Degree / Total_Steps * PI_2 )
x = 0.0
y = -1.0 ; length of your gauge indicator.
x_new = ( c * x ) - ( s * y )
y_new = ( s * x ) + ( c * y )
x_new = 0.7071
y_new = -0.7071
axis:
Y
+
|
|
X- _______ +
|
|
-
Notice that the Y value is negative 1.0.
This is because the origin of the screen you draw to is "left top" and not "left bottom"
Now you can translate both vectors of de gauge indicator to the position on the screen you want it to be.
So infact you rotate the vector at screen position 0,0 and than add the final screen x,y positions to it.
You only need to rotate one vector because the origin vector will always be 0,0
An example how to do the calculations ( not optimized )
.data
PI_2 real4 0.0
Total_Steps real4 360.0 ; full rotation
Rot_Angle real4 45.0 ; in degrees
C_ real4 0.0
S_ real4 0.0
Needle_X real4 0.0
Needle_Y real4 -1.0
New_X real4 0.0
New_Y real4 0.0
.code
fldpi
fadd st(0),st(0)
fstp PI_2
fld Rot_Angle
fdiv Total_Steps
fmul PI_2
fsincos
fstp C_
fstp S_
fld Needle_X
fmul C_
fld Needle_Y
fmul S_
fsubp
fstp New_X
fld Needle_X
fmul S_
fld Needle_Y
fmul C_
faddp
fstp New_Y
Now you can draw a line between both vectors.
And because X is 0.0 you can simplify the calculations by not calculating the X rotation:
fldpi
fadd st(0),st(0)
fstp PI_2
fld Rot_Angle
fdiv Total_Steps
fmul PI_2
fsincos
fstp C_
fstp S_
fld Needle_Y
fmul S_
fchs
fstp New_X
fld Needle_Y
fmul C_
fstp New_Y
Since your app is not time critical, why don't use the GDI api for that? Since the center is always the same, you just need to calculate the extreme of the needle. If you need an example, tell us
This is a fast routine that calculates the screen coordinates for the Gauge indicator in integer values.
.data
RotationMagic real4 0.01745329252222222222222222222 ; 1/360 * 2*Pi
.code
CalculateGauge proc Xpos:DWORD,Ypos:DWORD,Radius:DWORD,Angle:DWORD
fild Angle ; in degrees
fmul RotationMagic
fsincos
fimul Radius
fchs
fiadd Ypos
fistp dword ptr [esp-8]
fimul Radius
fiadd Xpos
fistp dword ptr [esp-4]
mov eax,dword ptr [esp-4] ; New_X
mov ecx,dword ptr [esp-8] ; New_Y
ret
CalculateGauge endp
; calculates the angle in 32 bit integer values.
invoke CalculateGauge,100,100,60,45 ; returns New_X in eax and New_Y in ecx
result is: 142,58
Now you can draw a line between (100,100) and (142,58)
Edit: a faster version
Really thanks Marinus!!
It was an incredible time saver. I admit I had already spent a lot of time... but handling the Maths, and the FPU new stuff was above my pay check.
Your proc will serve me as a way to study FPU, which I was doing reading masm32 help file. This practical example will help me a lot.
Caballero, thanks too! In fact, would you show me your alternative? I'm sure there will be someone like me search for similar help.
I'll let you know as soon as the toy starts doing its thing!
bresenhams circle algorithm is maybe an alternative
I already inserted Marinus´s Algo, couldn´t resist.. not ready yet but it´s already working and showing with precision my Fuel level. Check it out:
http://masm32.com/board/index.php?topic=6200.msg73621#msg73621 (http://masm32.com/board/index.php?topic=6200.msg73621#msg73621)
Marinus, I took the freedom to repost your algo there, ok? Just to register the development in case someone in the future wanted to have a look (due credit given, of course).
:t Share & Enjoy!
Hi,
If you can live with limited precision, you might just make some
images of the gauge at different levels and copy the closest on to
the screen. For instance, if 12.5% accuracy is adequate, make
nine images from zero to full. ( 0.0, 0.125. 0.25, 0.375,... 1.0 )
That might allow a "prettier" looking gauge. More accuracy will
require more images, so perhaps not an option for you?
Cheers,
Steve N.
> Caballero, thanks too! In fact, would you show me your alternative? I'm sure there will be someone like me search for similar help.
If it can wait to this weekend, I will try to do anything :biggrin:
Well, here is my little contribution to this subject. You can resize the window. Everything with GDI functions. Full masm32 source code.
Hey caballero that's a great contribution, thanks a lot! :icon14: :icon14:
Quote from: caballero on January 28, 2018, 05:53:13 AM
Well, here is my little contribution to this subject. You can resize the window. Everything with GDI functions. Full masm32 source code.
very nice Clock Caballero,would be nice to replace windows original Clock with :t
Thanks Caballero, nice contribution indeed!