### Author Topic: Drawing a circle  (Read 2228 times)

• Member
• Posts: 642
##### Drawing a circle
« on: January 21, 2018, 04:10:50 PM »
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 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:

#### Siekmanski

• Member
• Posts: 2014
##### Re: Drawing a circle
« Reply #1 on: January 21, 2018, 07:20:58 PM »
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 )
Code: [Select]
`.dataPI_2        real4 0.0Total_Steps real4 360.0 ; full rotationRot_Angle   real4 45.0  ; in degreesC_          real4 0.0S_          real4 0.0Needle_X    real4 0.0Needle_Y    real4 -1.0New_X       real4 0.0New_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:

Code: [Select]
`    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`
« Last Edit: January 21, 2018, 10:18:50 PM by Siekmanski »
Creative coders use backward thinking techniques as a strategy.

#### caballero

• Member
• Posts: 1363
• Matrix - Noah
##### Re: Drawing a circle
« Reply #2 on: January 21, 2018, 08:25:42 PM »
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
The logic of the error is hidden among the most unexpected lines of the program

#### Siekmanski

• Member
• Posts: 2014
##### Re: Drawing a circle
« Reply #3 on: January 21, 2018, 10:01:22 PM »
This is a fast routine that calculates the screen coordinates for the Gauge indicator in integer values.

Code: [Select]
`.dataRotationMagic real4 0.01745329252222222222222222222 ; 1/360 * 2*Pi.codeCalculateGauge 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    retCalculateGauge 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
« Last Edit: January 21, 2018, 11:34:19 PM by Siekmanski »
Creative coders use backward thinking techniques as a strategy.

• Member
• Posts: 642
##### Re: Drawing a circle
« Reply #4 on: January 22, 2018, 03:02:05 AM »
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!

#### daydreamer

• Member
• Posts: 1161
• I also want a stargate
##### Re: Drawing a circle
« Reply #5 on: January 22, 2018, 05:39:00 AM »
bresenhams circle algorithm is maybe an alternative
Quote from Flashdance
Nick  :  When you give up your dream, you die
*wears a flameproof asbestos suit*
Gone serverside programming p:  :D
I love assembly,because its legal to write
princess:lea eax,luke
:)

• Member
• Posts: 642
##### Re: Drawing a circle
« Reply #6 on: January 22, 2018, 06:01:27 AM »
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

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).

#### Siekmanski

• Member
• Posts: 2014
##### Re: Drawing a circle
« Reply #7 on: January 22, 2018, 06:39:41 AM »
:t Share & Enjoy!
Creative coders use backward thinking techniques as a strategy.

#### FORTRANS

• Member
• Posts: 1065
##### Re: Drawing a circle
« Reply #8 on: January 23, 2018, 01:00:08 AM »
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

• Member
• Posts: 1363
• Matrix - Noah
##### Re: Drawing a circle
« Reply #9 on: January 23, 2018, 02:21:59 AM »
> 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
The logic of the error is hidden among the most unexpected lines of the program

#### caballero

• Member
• Posts: 1363
• Matrix - Noah
##### Re: Drawing a circle
« Reply #10 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.
The logic of the error is hidden among the most unexpected lines of the program

#### felipe

• Member
• Posts: 1265
• Eagles are just great!
##### Re: Drawing a circle
« Reply #11 on: January 29, 2018, 03:32:51 AM »
Hey caballero that's a great contribution, thanks a lot!  :icon14: :icon14:
Felipe.

#### daydreamer

• Member
• Posts: 1161
• I also want a stargate
##### Re: Drawing a circle
« Reply #12 on: January 29, 2018, 04:49:56 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
« Last Edit: January 29, 2018, 06:30:17 AM by daydreamer2 »
Quote from Flashdance
Nick  :  When you give up your dream, you die
*wears a flameproof asbestos suit*
Gone serverside programming p:  :D
I love assembly,because its legal to write
princess:lea eax,luke
:)