## News:

*NEW* Current Version on STEAM16.793

Webchat:
Visit the chat

## SIN and COS, Rotational and Circular Math.

#### Hemlos

How to use SIN and COS, for Rotational and Circular Math:
Below you will find examples of Trigonometry math...
...Functions for DRAWCIRCLE(), DRAWDISC(), and DRAWRING()
You will also find the code for a Desktop Clock, which uses internal computer clock.

Here is an example of  "How to do ROTATE"
In this example we will make a circle out of dots.
You need to make presets for the Center Position X,Y, and Radius.
Then, you need to rotate an angle, so declare a variable RotationAngle .
In order to make a circle, you need to draw it out obviously...
...we are making dots , these will need a 2 variables for both planes in XY
So lets get the program started....first declare variables, then begin the main loop:
Code (glbasic) Select
`LIMITFPS 60LOCAL DotX,DotY,RotationAngle //these are variables and dont need to be preset.LOCAL X,Y,Radius //Circle PresetsX=200 //place the center of circle hereY=200Radius=150 // This is the distance from center of circle to be drawnWHILE TRUE  //start the code`

In order to make a point spin around (X,Y), at Radius distance,
1. You multiply the Radius by the cosine of X, and add the distance X .
Always use COS for X plane.
This will always orient angle 0 to point to the right, to the positive x direction.

2. You multiply the Radius by the sine of Y, and add the distance Y . Always use SIN for Y plane.

Now we're ready to start Rotating the Angle and drawing it out.
FOR, NEXT with a SETPIXEL command will be suitable for this example:
Code ( 0 to 359=360 degrees) Select
`FOR RotationAngle=0 to 359 //360 degrees     DotX=Radius*COS(RotationAngle)+X     DotY=Radius*SIN(RotationAngle)+Y     SETPIXEL DotX,DotY,RGB(255,255,255)NEXTSHOWSCREENWEND`

Notes: you can make presets for individual Radius for both X and Y planes....to make globes etc
Make sure you declare,

//ellipse

And include those into the FOR NEXT statement.

Now we're done, here is the full code of the example above:
Code (glbasic) Select
`LIMITFPS 60LOCAL DotX,DotY,RotationAngle //these are variables and dont need to be preset.LOCAL X,Y,Radius //Circle PresetsX=200 //place the center of circle hereY=200Radius=150 // This is the distance from center of circle to be drawnWHILE TRUE  //start the codeFOR RotationAngle=0 to 359 //360 degrees     DotX=Radius*COS(RotationAngle)+X     DotY=Radius*SIN(RotationAngle)+Y     SETPIXEL DotX,DotY,RGB(255,255,255)NEXTSHOWSCREENWEND`

Nice and easy....i have added coded functions to make circles and discs using this math:
To use this function:

Code (DRAWCIRCLE() Function draws a circle with lines) Select
`FUNCTION DRAWCIRCLE: CircleColor,CircleX,CircleY,CircleRadius//draws a 36 point circle, using linesLOCAL Cir,CirXS,CirYS,CirXE,CirYEFOR Cir=0 TO 359 STEP 10 CirXS=CircleX+CircleRadius*COS(Cir) CirYS=CircleY+CircleRadius*SIN(Cir) CirXE=CircleX+CircleRadius*COS(Cir-10) CirYE=CircleY+CircleRadius*SIN(Cir-10) DRAWLINE CirXS,CirYS,CirXE,CirYE,CircleColorNEXTENDFUNCTION`

and here is a disc using the same exact math, but with polyvectors and images for skin:
To use this function, you need 2 colors, one for the center and one for the outside.
And you can skin it to with BmpSkin="image.bmp"

Code (DRAWDISC() Function creates a filled disc of specified radius) Select
`FUNCTION DRAWDISC: CircleColor1,CircleColor2,CircleX,CircleY,CircleRadius,BmpSkin//Function creates a filled disc of specified radius FOR Cir=0 TO 359 STEP 10 STARTPOLY BmpSkin,0 CirXS=CircleX+CircleRadius*COS(Cir) CirYS=CircleY+CircleRadius*SIN(Cir) CirXE=CircleX+CircleRadius*COS(Cir-10) CirYE=CircleY+CircleRadius*SIN(Cir-10) POLYVECTOR CirXS,CirYS, CirXS-CircleX-CircleRadius, CirYS-CircleY-CircleRadius, CircleColor1 POLYVECTOR CirXE,CirYE, CirXE-CircleX-CircleRadius, CirYE-CircleY-CircleRadius, CircleColor1 POLYVECTOR CircleX,CircleY, CircleX-CircleX-CircleRadius, CircleY-CircleY-CircleRadius, CircleColor2 ENDPOLY NEXTENDFUNCTION`

It is used exactly like the examples above:

Code (DrawRing() Function draws a ring with adjustable width..  inside and outside radius) Select
`FUNCTION DRAWRING: Color1,Color2,CircleX,CircleY,OutsideRadius,InsideRadius,BmpSkin FOR Cir=0 TO 359 STEP 10 STARTPOLY BmpSkin CirX1=CircleX+OutsideRadius*COS(Cir) CirY1=CircleY+OutsideRadius*SIN(Cir) CirX2=CircleX+OutsideRadius*COS(Cir-10) CirY2=CircleY+OutsideRadius*SIN(Cir-10) CirX3=CircleX+InsideRadius*COS(Cir-10) CirY3=CircleY+InsideRadius*SIN(Cir-10) CirX4=CircleX+InsideRadius*COS(Cir) CirY4=CircleY+InsideRadius*SIN(Cir) POLYVECTOR CirX1,CirY1,CirX1,CirY1,Color1 POLYVECTOR CirX2,CirY2,CirX2,CirY2,Color1 POLYVECTOR CirX3,CirY3,CirX3,CirY3,Color2 POLYVECTOR CirX4,CirY4,CirX4,CirY4,Color2 ENDPOLY NEXTENDFUNCTION`

This is a full screen Analog Clock, it is syncronized with your computers time...can be a great screen saver.
Read the readme in the zipfile, for info on how to make it into a screen saver.

Ive been tinkering...its getting bigger and more colorful.
Render At 800x600 fullscreen.
Code (Main Clock Code) Select
`// --------------------------------- //// Project: DesktopClock// Start: Thursday, August 14, 2008// IDE Version: 5.341//compile into fullscreen mode...looks cool LOCAL sx,sy,h,w GETSCREENSIZE sx,sy GETFONTSIZE w,h LOCAL cx=sx/2 LOCAL cy=sy/2 AUTOPAUSE FALSE ALPHAMODE -1WHILE TRUE SYSTEMPOINTER FALSE drawwater()dosfx=dosfx+1IF dosfx>3 THEN dosfx=0IF dosfx=0 velx=RND(4)-2 vely=RND(4)-2 cx2=cx cx=cx2+velx cy2=cy cy=cy2+velyENDIF IF cy>400 THEN cy=400 IF cx>600 THEN cx=600 IF cx<200 THEN cx=200 IF cy<200 THEN cy=200 IF fup=0;  fx1=fx1-1; IF fx1<1; fup=1;ENDIF; ENDIF IF fup=1;  fx1=fx1+1; IF fx1>250; fup=0;ENDIF;ENDIF    sxf(RGB(1,1,1),RGB(-fx1,1,1),cx,cy,170,66) DRAWRING(RGB(20,20,fx1),RGB(-fx1,20,20),cx,cy,245,195) DRAWRING(RGB(-fx1,20,20),RGB(20,20,fx1),cx,cy,195,170) DRAWCIRCLE(RGB(1,1,1),cx,cy,66) DRAWCIRCLE(RGB(fx1,1,1),cx,cy,200) DRAWCIRCLE(RGB(1,1,fx1),cx,cy,240)  IF KeyBoardIO()>-1 THEN END //seconds hand STARTPOLY -1 //DRAWLINE cx,cy,cx+200*COS(secs*6-90),cy+200*SIN(secs*6-90),RGB(RND(200)+20,RND(200)+20,RND(200)+20) //secs POLYVECTOR cx+200*COS(secs*6-90),cy+200*SIN(secs*6-90),cx+200*COS(secs*6-90),cy+200*SIN(secs*6-90),RGB(255,255,fx1) POLYVECTOR cx+10*COS(secs*6-180),cy+10*SIN(secs*6-180),cx+10*COS(secs*6-180),cy+10*SIN(secs*6-180),RGB(1,1,1) POLYVECTOR cx+10*COS(secs*6),cy+10*SIN(secs*6),cx+10*COS(secs*6),cy+10*SIN(secs*6),RGB(1,1,1) ENDPOLY //minutes hand STARTPOLY -1 //DRAWLINE cx,cy,cx+166*COS(mins*6-90),cy+166*SIN(mins*6-90),RGB(RND(200)+20,0,0)//mins POLYVECTOR cx+150*COS(mins*6-90),cy+150*SIN(mins*6-90),cx+200*COS(mins*6-90),cy+200*SIN(mins*6-90),RGB(255,255,fx1) POLYVECTOR cx+10*COS(mins*6-180),cy+10*SIN(mins*6-180),cx+10*COS(mins*6-180),cy+10*SIN(mins*6-180),RGB(1,1,1) POLYVECTOR cx+10*COS(mins*6),cy+10*SIN(mins*6),cx+10*COS(mins*6),cy+10*SIN(mins*6),RGB(1,1,1) ENDPOLY // hours hand STARTPOLY -1 //DRAWLINE cx,cy,cx+122*COS(hrs*30-90),cy+122*SIN(hrs*30-90),RGB(0,0,RND(200)+20) //hours POLYVECTOR cx+100*COS(hrs*30-90),cy+100*SIN(hrs*30-90),cx+200*COS(hrs*30-90),cy+200*SIN(hrs*30-90),RGB(255,255,fx1) POLYVECTOR cx+10*COS(hrs*30-180),cy+10*SIN(hrs*30-180),cx+10*COS(hrs*30-180),cy+10*SIN(hrs*30-180),RGB(1,1,1) POLYVECTOR cx+10*COS(hrs*30),cy+10*SIN(hrs*30),cx+10*COS(hrs*30),cy+10*SIN(hrs*30),RGB(1,1,1) ENDPOLY DRAWDISC(RGB(1,1,1),RGB(255,255,fx1),cx,cy,22) DRAWCIRCLE(RGB(1,1,1),cx,cy,22) FOR i= 1 TO 12 //draw little lines and numbers DRAWLINE cx+200*COS(i*30),cy+200*SIN(i*30),cx+210*COS(i*30),cy+210*SIN(i*30),RGB(1,fx1,1) PRINT i,cx+225*COS(i*30-90)-8,cy+225*SIN(i*30-90)-h/2-2 NEXT LET secs1=MID\$(PLATFORMINFO\$("TIME"),18,1) LET secs2=MID\$(PLATFORMINFO\$("TIME"),17,1) LET mins1=MID\$(PLATFORMINFO\$("TIME"),15,1) LET mins2=MID\$(PLATFORMINFO\$("TIME"),14,1) LET hrs1 =MID\$(PLATFORMINFO\$("TIME"),12,1) LET hrs2 =MID\$(PLATFORMINFO\$("TIME"),11,1) secs=secs2*10 secs=secs+secs1 mins=mins2*10 mins=mins+mins1 hrs=hrs2*10 hrs=hrs+hrs1 IF hrs=0 THEN hrs=12  IF hrs>12;   hrs=hrs-12; pm\$="pm"   ELSE pm\$="am" ENDIF PRINT MID\$(PLATFORMINFO\$("TIME"),0,10),2,2+fx1 IF mins<10 PRINT hrs+":0"+mins+" "+pm\$,20,25+fx1 ELSE PRINT hrs+":"+mins+" "+pm\$,20,25+fx1 ENDIF //tick=ASC(MID\$(PLATFORMINFO\$("TIME"),18,1)) SHOWSCREENWENDFUNCTION DRAWRING: Col1,Col2,CircleX,CircleY,OutsideRadius,InsideRadius FOR Cir=0 TO 359 STEP 10 STARTPOLY -1 CirX1=CircleX+OutsideRadius*COS(Cir) CirY1=CircleY+OutsideRadius*SIN(Cir) CirX2=CircleX+OutsideRadius*COS(Cir-10) CirY2=CircleY+OutsideRadius*SIN(Cir-10) CirX3=CircleX+InsideRadius*COS(Cir-10) CirY3=CircleY+InsideRadius*SIN(Cir-10) CirX4=CircleX+InsideRadius*COS(Cir) CirY4=CircleY+InsideRadius*SIN(Cir) POLYVECTOR CirX1,CirY1,CirX1,CirY1,Col2 POLYVECTOR CirX2,CirY2,CirX2,CirY2,Col2 POLYVECTOR CirX3,CirY3,CirX3,CirY3,Col1 POLYVECTOR CirX4,CirY4,CirX4,CirY4,Col1 ENDPOLY NEXTENDFUNCTIONFUNCTION sxf: Col1,Col2,CircleX,CircleY,OutsideRadius,InsideRadiusSTATIC sf FOR Cir=0 TO 359 STEP 20 STARTPOLY -1 sf=sf+1 Cir=Cir+sf CirX1=CircleX+OutsideRadius*COS(Cir) CirY1=CircleY+OutsideRadius*SIN(Cir) CirX2=CircleX+OutsideRadius*COS(Cir-10) CirY2=CircleY+OutsideRadius*SIN(Cir-10) CirX3=CircleX+InsideRadius*COS(Cir-10) CirY3=CircleY+InsideRadius*SIN(Cir-10) CirX4=CircleX+InsideRadius*COS(Cir) CirY4=CircleY+InsideRadius*SIN(Cir) POLYVECTOR CirX1,CirY1,CirX1,CirY1,Col2 POLYVECTOR CirX2,CirY2,CirX2,CirY2,Col2 POLYVECTOR CirX3,CirY3,CirX3,CirY3,Col1 POLYVECTOR CirX4,CirY4,CirX4,CirY4,Col1 ENDPOLY NEXT FOR Cir=359 TO 0 STEP 20 STARTPOLY -1 sf=sf-1 Cir=Cir+sf+90 CirX1=CircleX+OutsideRadius*COS(Cir) CirY1=CircleY+OutsideRadius*SIN(Cir) CirX2=CircleX+OutsideRadius*COS(Cir-10) CirY2=CircleY+OutsideRadius*SIN(Cir-10) CirX3=CircleX+InsideRadius*COS(Cir-10) CirY3=CircleY+InsideRadius*SIN(Cir-10) CirX4=CircleX+InsideRadius*COS(Cir) CirY4=CircleY+InsideRadius*SIN(Cir) POLYVECTOR CirX1,CirY1,CirX1,CirY1,Col2 POLYVECTOR CirX2,CirY2,CirX2,CirY2,Col2 POLYVECTOR CirX3,CirY3,CirX3,CirY3,Col1 POLYVECTOR CirX4,CirY4,CirX4,CirY4,Col1 ENDPOLY NEXT IF sf>360 THEN sf=0ENDFUNCTIONFUNCTION DRAWDISC: CircleColor1,CircleColor2,CircleX,CircleY,CircleRadius FOR Cir=0 TO 359 STEP 10 STARTPOLY -1 CirXS=CircleX+CircleRadius*COS(Cir) CirYS=CircleY+CircleRadius*SIN(Cir) CirXE=CircleX+CircleRadius*COS(Cir-10) CirYE=CircleY+CircleRadius*SIN(Cir-10) CirXO=CircleX CirYO=CircleY POLYVECTOR CirXS,CirYS,CirXS,CirYS,CircleColor1 POLYVECTOR CirXE,CirYE,CirXE,CirYE,CircleColor1 POLYVECTOR CirXO,CirYO,CirXO,CirYO,CircleColor2 ENDPOLY NEXTENDFUNCTIONFUNCTION DRAWCIRCLE: CircleColor,CircleX,CircleY,CircleRadius//draws a 36 point circleLOCAL Cir,CirXS,CirYS,CirXE,CirYEFOR Cir=0 TO 359 STEP 10 CirXS=CircleX+CircleRadius*COS(Cir) CirYS=CircleY+CircleRadius*SIN(Cir) CirXE=CircleX+CircleRadius*COS(Cir-10) CirYE=CircleY+CircleRadius*SIN(Cir-10) DRAWLINE CirXS,CirYS,CirXE,CirYE,CircleColorNEXTENDFUNCTION// ------------------------------------------------------------- //// ---  KeyBoardIO  --- detect any key press...0 to 299// returns instance of key pressed..one time...preventing repeated input// waits till button is released...then returns that keycode.// its in this program to check if any key is pressed, and end program.// ------------------------------------------------------------- //FUNCTION KeyBoardIO: LOCAL i STATIC K,SENDKWAIT,SKB K=-1 FOR i=0 TO 299 IF KEY(i) THEN K=i NEXT IF (K=-1) AND (SENDKWAIT=TRUE); SENDKWAIT=FALSE; RETURN SKB; ENDIF IF K>-1; SENDKWAIT=TRUE; SKB=K; K=-1; ENDIF RETURN KENDFUNCTIONFUNCTION drawwater:STATIC z1,z2FOR y = 0 TO 600 STEP 60FOR x= 0 TO 800 STEP 80y1=y-3STARTPOLY -1POLYVECTOR x+RND(3)-3,y1+RND(3),x,y,RGB(RND(99),x/9+y/9,x/9+y/9)POLYVECTOR x+RND(3)-3,y1+60+RND(3)+3,x,y,RGB(RND(99),x/9+y/9,x/7+y/9)POLYVECTOR x+80+RND(3)+3,y1+60+RND(3)+3,x,y,RGB(RND(99),x/9+y/9,x/9+y/7)POLYVECTOR x+80+RND(3)+3,y1+RND(3)-3,x,y,RGB(RND(99),x/9+y/9,x/9+y/9)ENDPOLYNEXTNEXTENDFUNCTION`

Bonus code from clock program:
Want to detect a key pressed AND Released ? Once?
Reports only once...after key is released...fantastic for user inputs.
This code prevents key press getting reported multiple times.
It only reports back which key is pressed one time, and only after the key is released.
If no keys are pressed then KeyBoardIO() = -1
Check for keys pressed like this:
KeyPressed=KeyBoardIO()
if KeyPressed > -1 then key was pressed and released, and afterwards resets back to value=-1
if KeyPressed = -1 then no keys has been pressed and released
Code (  key detection function ) Select
`// ------------------------------------------------------------- //// ---  KeyBoardIO  --- detect any key press...great for user inputs// waits till button is released...then returns that keycode.// ------------------------------------------------------------- //FUNCTION KeyBoardIO: LOCAL i STATIC K,SENDKWAIT,SKB K=-1 FOR i=0 TO 299 IF KEY(i) THEN K=i NEXT IF (K=-1) AND (SENDKWAIT=TRUE); SENDKWAIT=FALSE; RETURN SKB; ENDIF IF K>-1; SENDKWAIT=TRUE; SKB=K; K=-1; ENDIF RETURN KENDFUNCTION `

Bing ChatGpt is pretty smart

#### Schranz0r

#1
That's awesome
Nice work!
I DGArray's

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

#### BumbleBee

#2
It looks and works very good, Hemlos. What a pity. It's just a PC clock. Cause my wife needs a new kitchen clock. The old one (i mean the clock, not my wife) stopped working last week.

Cheers
The day will come...

CPU Intel(R) Core(TM) i5-3570k, 3.4GHz, AMD Radeon 7800 , 8 GB RAM, Windows 10 Home 64Bit

#3
brilliant !!

#### Hemlos

#4

Bing ChatGpt is pretty smart

#### mentalthink

HI Hemlos, I don´t look this thraed before, but explained perfectly!!!...

I´m glad if you can make some tutorials but whit more complex Maths... you are good whit Maths..

#### sf-in-sf

#6
As I used it again today, here is a brief summary. How to rotate a point around the 0,0 origin?
your point is P(x,y). Write it as a complex number, a +ib    i.e. a=x and b=y. When you rotate this point by an angle theta, you multiply this complex number by e^(i theta) = cos(theta) +i sin(theta).
You end up with a rotated point P2{X,Y} with X = a cos(theta) - b sin(theta)  and Y = b cos(theta) + a sin(theta).
If you want to rotate something anywhere in the xy plane, first "move" it to the 0,0 origin, rotate it, and then put it back where it was.
Good luck!

PS X and Y are AXES not planes.
EDIT// // // sorry, X is my favorite plane: "X plane" is a superb flight simulator, FAA certified.
On the day the atom is a cube I will start believing in the square pixel.

#### erico

All book marked! so much good info!