Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 01:35 28 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : donut for picomite or MMB4W etc

Author Message
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6100
Posted: 07:10am 17 Aug 2023
Copy link to clipboard 
Print this post

Should run on any mmbasic with LCD screen and MMB4W.

 ' donut
 ' https://www.a1k0n.net/2011/07/20/donut-math.html
 OPTION EXPLICIT
 OPTION DEFAULT INTEGER
 CONST theta_spacing = 0.07
 CONST phi_spacing   = 0.02
 
 DIM FLOAT R1 = 1
 DIM FLOAT R2 = 2
 DIM FLOAT K2 = 5
 CONST screen_width = 320
 CONST screen_height = 240
 
 ' Calculate K1 based on screen size: the maximum x-distance occurs
 ' roughly at the edge of the torus, which is at x=R1+R2, z=0.  we
 ' want that to be displaced 3/8ths of the width of the screen, which
 ' is 3/4th of the way from the center to the side of the screen.
 ' screen_width*3/8 = K1*(R1+R2)/(K2+0)
 ' screen_width*K2*3/(8*(R1+R2)) = K1
 DIM FLOAT K1 = screen_width*K2*2/(8*(R1+R2))
 
SUB render_frame(A AS FLOAT, B AS FLOAT)
 ' precompute sines and cosines of A and B
 LOCAL FLOAT cosA = COS(A), sinA = SIN(A)
 LOCAL FLOAT cosB = COS(B), sinB = SIN(B)
 LOCAL FLOAT costheta, sintheta
 LOCAL FLOAT cosphi , sinphi
 LOCAL FLOAT theta, phi
 LOCAL FLOAT circlex, circley, x,y, z, ooz, L
 LOCAL INTEGER xp, yp
 CLS
 
 ' theta goes around the cross-sectional circle of A torus
 FOR theta=0 TO 2*PI STEP theta_spacing
   ' precompute sines and cosines of theta
   costheta = COS(theta) : sintheta = SIN(theta)
   
   ' phi goes around the center of revolution of A torus
   FOR phi=0 TO 2*PI STEP phi_spacing
     ' precompute sines and cosines of phi
     cosphi = COS(phi) : sinphi = SIN(phi)
     
     ' the x,y coordinate of the circle, before revolving (factored
     ' out of the above equations)
     circlex = R2 + R1*costheta
     circley = R1*sintheta
     
     ' final 3D (x,y,z) coordinate after rotations, directly from
     ' our math above
     x = circlex*(cosB*cosphi + sinA*sinB*sinphi) - circley*cosA*sinB
     y = circlex*(sinB*cosphi - sinA*cosB*sinphi) + circley*cosA*cosB
     z = K2 + cosA*circlex*sinphi + circley*sinA
     ooz = 1/z  ' "one over z"
     
     ' x and y projection.  note that y is negated here, because y
     ' goes up in 3D space but down on 2D displays.
     xp = INT(screen_width/2 + K1*ooz*x)
     yp = INT(screen_height/2 - K1*ooz*y)
     
     ' calculate luminance.  ugly, but correct.
     L = cosphi*costheta*sinB - cosA*costheta*sinphi
     L = 0.7*(L - sinA*sintheta + cosB*(cosA*sintheta - costheta*sinA*sinphi))
     ' L ranges from -sqrt(2) to +sqrt(2).  If it's < 0, the surface
     ' is pointing away from us, so we won't bother trying to plot it.
     IF (L > 0) THEN
       BOX xp,yp,3,3,1,RGB(L*255,L*255,L*255)
     ENDIF
   NEXT
 NEXT
 
END SUB
 
 render_frame(1,1)
DO:LOOP



I failed in my attempt to get the ASCII version running.

Jim
VK7JH
MMedit   MMBasic Help
 
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1114
Posted: 09:27am 17 Aug 2023
Copy link to clipboard 
Print this post

Nice .. just tested on MMB4W

To keep it flexible, I just changed two lines :

CONST screen_width = MM.HRES
CONST screen_height = MM.VRES



Cheers
Mart!n
'no comment
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3150
Posted: 02:40pm 17 Aug 2023
Copy link to clipboard 
Print this post

On a 480x320 ILI9488 by a picomite, with BMP file converted to JPG:


PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6100
Posted: 09:45pm 17 Aug 2023
Copy link to clipboard 
Print this post

This one should run on the picomiteVGA in 640 x 480 mode.
 ' donut
 ' https://www.a1k0n.net/2011/07/20/donut-math.html
 OPTION EXPLICIT
 OPTION DEFAULT INTEGER
 CONST theta_spacing = 0.07
 CONST phi_spacing   = 0.02
 
 DIM FLOAT R1 = 1
 DIM FLOAT R2 = 2
 DIM FLOAT K2 = 5
 CONST screen_width = 160
 CONST screen_height = 120
 
 ' Calculate K1 based on screen size: the maximum x-distance occurs
 ' roughly at the edge of the torus, which is at x=R1+R2, z=0.  we
 ' want that to be displaced 3/8ths of the width of the screen, which
 ' is 3/4th of the way from the center to the side of the screen.
 ' screen_width*3/8 = K1*(R1+R2)/(K2+0)
 ' screen_width*K2*3/(8*(R1+R2)) = K1
 DIM FLOAT K1 = screen_width*K2*2/(8*(R1+R2))
 
SUB render_frame(A AS FLOAT, B AS FLOAT)
 ' precompute sines and cosines of A and B
 LOCAL FLOAT cosA = COS(A), sinA = SIN(A)
 LOCAL FLOAT cosB = COS(B), sinB = SIN(B)
 LOCAL FLOAT costheta, sintheta
 LOCAL FLOAT cosphi , sinphi
 LOCAL FLOAT theta, phi
 LOCAL FLOAT circlex, circley, x,y, z, ooz, L
 LOCAL INTEGER xp, yp, n
 CLS
 
 ' theta goes around the cross-sectional circle of A torus
 FOR theta=0 TO 2*PI STEP theta_spacing
   ' precompute sines and cosines of theta
   costheta = COS(theta) : sintheta = SIN(theta)
   
   ' phi goes around the center of revolution of A torus
   FOR phi=0 TO 2*PI STEP phi_spacing
     ' precompute sines and cosines of phi
     cosphi = COS(phi) : sinphi = SIN(phi)
     
     ' the x,y coordinate of the circle, before revolving (factored
     ' out of the above equations)
     circlex = R2 + R1*costheta
     circley = R1*sintheta
     
     ' final 3D (x,y,z) coordinate after rotations, directly from
     ' our math above
     x = circlex*(cosB*cosphi + sinA*sinB*sinphi) - circley*cosA*sinB
     y = circlex*(sinB*cosphi - sinA*cosB*sinphi) + circley*cosA*cosB
     z = K2 + cosA*circlex*sinphi + circley*sinA
     ooz = 1/z  ' "one over z"
     
     ' x and y projection.  note that y is negated here, because y
     ' goes up in 3D space but down on 2D displays.
     xp = INT(screen_width/2 + K1*ooz*x)*4
     yp = INT(screen_height/2 - K1*ooz*y)*4
     
     ' calculate luminance.  ugly, but correct.
     L = cosphi*costheta*sinB - cosA*costheta*sinphi
     L = 0.7*(L - sinA*sintheta + cosB*(cosA*sintheta - costheta*sinA*sinphi))
     ' L ranges from -sqrt(2) to +sqrt(2).  If it's < 0, the surface
     ' is pointing away from us, so we won't bother trying to plot it.
     IF (L > 0) THEN
       ' box xp,yp,3,3,1,rgb(L*255,L*255,L*255)
       FOR n = 0 TO 15
         IF L*15 > n THEN
           PIXEL xp+(n\4),yp+(n MOD 4),RGB(WHITE)
         ELSE
           'pixel xp+(n\4),yp+(n mod 4),rgb(black)
         ENDIF
       NEXT n
     ENDIF
   NEXT
 NEXT
 
END SUB
 
 render_frame(1,1)
DO:LOOP



very crude dithering used.

Jim
VK7JH
MMedit   MMBasic Help
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6100
Posted: 09:47am 18 Aug 2023
Copy link to clipboard 
Print this post

Last one, I promise.
Runs on just about anything with ASCII art output to an attached VT terminal.
 ' donut
 ' https://www.a1k0n.net/2011/07/20/donut-math.html
 OPTION EXPLICIT
 OPTION DEFAULT INTEGER
 CONST theta_spacing = 0.07
 CONST phi_spacing   = 0.02
 
 DIM FLOAT R1 = 1
 DIM FLOAT R2 = 2
 DIM FLOAT K2 = 3
 CONST screen_width = 80
 CONST screen_height = 36
 
 ' Calculate K1 based on screen size: the maximum x-distance occurs
 ' roughly at the edge of the torus, which is at x=R1+R2, z=0.  we
 ' want that to be displaced 3/8ths of the width of the screen, which
 ' is 3/4th of the way from the center to the side of the screen.
 ' screen_width*3/8 = K1*(R1+R2)/(K2+0)
 ' screen_width*K2*3/(8*(R1+R2)) = K1
 DIM FLOAT K1 = screen_width*K2*2/(16*(R1+R2))
 
SUB render_frame(A AS FLOAT, B AS FLOAT)
 ' precompute sines and cosines of A and B
 LOCAL FLOAT cosA = COS(A), sinA = SIN(A)
 LOCAL FLOAT cosB = COS(B), sinB = SIN(B)
 LOCAL FLOAT costheta, sintheta
 LOCAL FLOAT cosphi , sinphi
 LOCAL FLOAT theta, phi
 LOCAL FLOAT circlex, circley, x,y, z, ooz, L
 LOCAL INTEGER xp, yp, n
 ' cls
 PRINT CHR$(27)+"[2J";
 ' theta goes around the cross-sectional circle of A torus
 FOR theta=0 TO 2*PI STEP theta_spacing
   ' precompute sines and cosines of theta
   costheta = COS(theta) : sintheta = SIN(theta)
   
   ' phi goes around the center of revolution of A torus
   FOR phi=0 TO 2*PI STEP phi_spacing
     ' precompute sines and cosines of phi
     cosphi = COS(phi) : sinphi = SIN(phi)
     
     ' the x,y coordinate of the circle, before revolving (factored
     ' out of the above equations)
     circlex = R2 + R1*costheta
     circley = R1*sintheta
     
     ' final 3D (x,y,z) coordinate after rotations, directly from
     ' our math above
     x = circlex*(cosB*cosphi + sinA*sinB*sinphi) - circley*cosA*sinB
     y = circlex*(sinB*cosphi - sinA*cosB*sinphi) + circley*cosA*cosB
     z = K2 + cosA*circlex*sinphi + circley*sinA
     ooz = 1/z  ' "one over z"
     
     ' x and y projection.  note that y is negated here, because y
     ' goes up in 3D space but down on 2D displays.
     xp = INT(screen_width/2 + K1*ooz*x)
     yp = INT(screen_height/2 - K1*ooz*y)+5
     
     ' calculate luminance.  ugly, but correct.
     L = cosphi*costheta*sinB - cosA*costheta*sinphi
     L = 0.7*(L - sinA*sintheta + cosB*(cosA*sintheta - costheta*sinA*sinphi))
     ' L ranges from -sqrt(2) to +sqrt(2).  If it's < 0, the surface
     ' is pointing away from us, so we won't bother trying to plot it.
     IF L > 0 THEN
       PRINT CHR$(27)+"["+STR$(yp)+";"+STR$(xp)+"H"+MID$(".,-~:;=!*#$@@@@",L*11+1,1);
     ENDIF
   NEXT
 NEXT
 
END SUB
 
 render_frame(1,1)
 PRINT CHR$(27)+"[1;1H"
DO:LOOP




                           $$@@@@@@@@$
                         $$$$$$$$$@@@@@$
                        $$$$$$$$$$$$$$$@$s
                       $###$$*****!!$$$$$$s
                      #####**!!!!!!!!!$$$$$
                     ####**!!!!=!===;;==####
                    ####**!!!====;;;;;;;;####
                    ****!!!!===;;;;::::::;***
                   *****!!!===;;;:~~~~~~~~*!**
                   *!!!!!!===;;::~~~-----~~!=!
                  *!!!!!====;;::~~--,,...,-=;=
                  *!!!!!===;;;:~~-,..   ..-~;;=
                  !!=!!===;;;:~~-,,      ..-~:;
                  !==!===;;;::~--,.       .--~;
                  !======;;;::~--.         -,-:
                  =;;====;;;:~~-,.        .-.,~
                  =;;===;;;::~~-,       .,-~..~
                  =;:==;;;:::~--,.     ~:::;;.~
                  =;::=;;;:::~~-,.     !!==;;.
                   ;:~=;;;:::~~-,,,-  ###*!=..
                   ;~~-;;;::::~~---~=*@@$#!;.-
                   ;:~-;;;;::::~~~~;!#@@$#!..
                    :~-,;;;:::::~::=!#$$#!:.
                     ~-,,;:::::::;;=!###!:..
                      -,.:::::::;;;=!!!=:..
                       -,.::::::;;;===;-..
                        ,,.:::::::;::-..
                         -...~~~~~~..,.
                            .....,..


Looks better on a black background.

Jim
VK7JH
MMedit   MMBasic Help
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 396
Posted: 10:23am 18 Aug 2023
Copy link to clipboard 
Print this post

Just tried it on the PicoVGA, really cool! I think the dithering is kind of interesting...

Greetings
Daniel
 
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1114
Posted: 10:28am 18 Aug 2023
Copy link to clipboard 
Print this post

I    the ASCII Version
'no comment
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024