Author Topic: Drawing a circle  (Read 1204 times)

LordAdef

  • Member
  • ****
  • Posts: 590
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 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:





Siekmanski

  • Member
  • *****
  • Posts: 1670
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]
.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:

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: 1088
    • abre ojos ensamblador
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
En un lugar de la Mancha de cuyo nombre no quiero acordarme

- There are 10 kind of people: those who know binary numbers and those who don't -

Siekmanski

  • Member
  • *****
  • Posts: 1670
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]
.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
« Last Edit: January 21, 2018, 11:34:19 PM by Siekmanski »
Creative coders use backward thinking techniques as a strategy.

LordAdef

  • Member
  • ****
  • Posts: 590
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: 548
  • reach for the stars
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*

LordAdef

  • Member
  • ****
  • Posts: 590
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: 1670
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: 1025
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: 1088
    • abre ojos ensamblador
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  :biggrin:
En un lugar de la Mancha de cuyo nombre no quiero acordarme

- There are 10 kind of people: those who know binary numbers and those who don't -

caballero

  • Member
  • *****
  • Posts: 1088
    • abre ojos ensamblador
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.
En un lugar de la Mancha de cuyo nombre no quiero acordarme

- There are 10 kind of people: those who know binary numbers and those who don't -

felipe

  • Member
  • ****
  • Posts: 943
  • 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: 548
  • reach for the stars
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*

LordAdef

  • Member
  • ****
  • Posts: 590
Re: Drawing a circle
« Reply #13 on: January 29, 2018, 02:35:32 PM »
Thanks Caballero, nice contribution indeed!