![]() |
Forum Index : Microcontroller and PC projects : CMM2 Barnsley Fern CSUB version
Author | Message | ||||
Sasquatch![]() Guru ![]() Joined: 08/05/2020 Location: United StatesPosts: 376 |
Here is a CSUB version of the Barnsley Fern fractal for the CMM2. It renders ~150X faster than the pure MMBasic version. This is an example of a self-similar fractal. In theory you could zoom in "forever" and it would still look the same. In reality it would just take "forever" to render. ![]() This Demo is interactive and will respond to the following Keys: I - Zoom In O - Zoom Out Q - Quit the program 'CSUB demo of Barnsley's fern 'Renders ~150X faster than pure MMBasic version 'This demo will render continuously until Q)uit 'Press I key to Zoom in 'Press O key to Zoom out 'Press Q key to Quit Mode 1,8 Zoom = 1.0 Seed% = &hAAAAAAAA CLS 'Draw a white pixel in the cente of the screen Pixel 400,300,RGB(white) Do Fern(40000,Zoom,Seed%) K$ = Inkey$ If K$ <> "" Then If K$ = "i" or K$ = "I" Then Zoom = Zoom * 2 : CLS : Pixel 400,300,RGB(white) If K$ = "o" or K$ = "O" Then Zoom = Zoom / 2 : CLS : Pixel 400,300,RGB(white) If K$ = "q" or K$ = "Q" then END EndIf Loop End 'CSUB version of Barnsley's Fern ' 'Fern(Iterations%,Zoom!,Seed%) ' 'Note that this Sub stores it's state in Seed and can be called repeatedly - ' it will continue to render as long as the Seed is not the same on each call. 'Caution: I have found that calling for more than 40,000 iterations - ' can interfere with MMBasic background functions such as reading keyboard 'Higher Zoom factor will take some time to render 'File fern.bas written 10-08-2020 13:11:17 CSUB fern 00000000 'Fern B098B580 60F8AF00 607A60B9 E9D368FB 46132300 68BB627B 2300E9D3 2306E9C7 0200F04F E9C74BA6 F04F2310 4BA40200 230EE9C7 681B687B 687B65BB 657B681B 681B687B 687B653B 64FB681B 65FB2300 6CFBE0E3 6DBB617B 6D3B613B 6D7B64FB 693B653B 697B657B 697A02DB 617B4053 0A1B697B 4053697A 697A617B 405A6DBB 0CDB6DBB 65BB4053 4A8E6DBB D3244293 7B10ED97 6B68ED9F 6B06EE27 7B0EED97 5B67ED9F 7B05EE27 7B07EE36 7B0CED87 7B10ED97 6B64ED9F 6B06EE27 7B0EED97 5B5DED9F 7B05EE27 7B07EE36 6B60ED9F 7B06EE37 7B0AED87 6DBBE067 42934A7A 6DBBD928 42934A77 ED97D224 ED9F7B10 EE276B5A ED976B06 ED9F7B0E EE275B59 EE367B05 ED877B07 ED977B0C ED9F7B10 EE276B56 ED976B06 ED9F7B0E EE275B55 EE367B05 ED9F7B07 EE376B54 ED877B06 E03A7B0A 4A656DBB D9284293 4A626DBB D8244293 7B10ED97 6B4DED9F 6B06EE27 7B0EED97 5B44ED9F 7B05EE27 7B47EE36 7B0CED87 7B10ED97 6B47ED9F 6B06EE27 7B0EED97 5B46ED9F 7B05EE27 7B07EE36 6B33ED9F 7B06EE37 7B0AED87 F04FE00D F04F0200 E9C70300 ED97230C ED9F7B0E EE276B3E ED877B06 E9D77B0A E9C7230C E9D72310 E9C7230A 4B45230E ED97681B ED9F7B10 EE276B37 ED976B06 EE267B06 ED9F7B07 EE376B35 EEFD7B06 ED975BC7 EEB17B0E EE376B04 ED9F7B46 EE276B31 ED976B06 EE267B06 ED9F7B07 EE366B2F EEFD7B47 F44F7BC7 EE1742C8 EE151A90 47980A90 33016DFB 6DFA65FB 429A6A7B AF17F6FF 687B6DBA BF00601A 46BD3760 BF00BD80 8000F3AF 33333333 3FEB3333 47AE147B 3FA47AE1 47AE147B BFA47AE1 9999999A 3FF99999 33333333 BFC33333 1EB851EC 3FD1EB85 0A3D70A4 3FD0A3D7 EB851EB8 3FCEB851 C28F5C29 3FDC28F5 9999999A 3FC99999 D70A3D71 3FCD70A3 C28F5C29 3FCC28F5 47AE147B 3FC47AE1 00000000 40590000 00000000 40790000 00000000 40490000 00000000 4072C000 3FF00000 26666666 147AE147 028F5C28 08000338 End CSUB And the 'C' source code: // Barnsley's Fern CSUB #include "ARMCFunctions.h" void Fern(long long int *Iter,MMFLOAT *Zoom,int *Seed) { int i; unsigned int StateA,StateB,StateC,StateD,Temp,StateS; double X,Y,NextX,NextY; int It = *Iter; double Z = *Zoom; X = 1; Y = 1; // Seed the 128bits for the PSRG StateA = *Seed; StateB = *Seed; StateC = *Seed; StateD = *Seed; // Loop through the specified number of iterations for(i = 0;i < It;i++) { // inline version of XorShift128 PSRG Temp = StateD; StateS = StateA; StateD = StateC; StateC = StateB; StateB = StateS; Temp ^= Temp << 11; Temp ^= Temp >> 8; StateA = Temp ^ StateA ^ (StateA >> 19); // Now let's draw some fern if (StateA >= 0x26666666) { NextX = (0.85 * X) + (0.04 * Y); NextY = (-0.04 * X) + (0.85 * Y) + 1.6; } else if ((StateA >= 0x147AE148) && (StateA < 0x26666666)) { NextX = (-0.15 * X) + (0.28 * Y); NextY = (0.26 * X) + (0.24 * Y) + 0.44; } else if ((StateA >= 0x28F5C29) && (StateA < 0x147AE148)) { NextX = (0.2 * X) - (0.26 * Y); NextY = (0.23 * X) + (0.22 * Y) + 1.6; } else { NextX = 0.0; NextY = 0.16 * Y; } X = NextX; Y = NextY; // Draw a green pixel at the current coordinates DrawPixel((X * 100.0 * Z) + 400.0,300.0 - ((Y - 5.0) * 50.0 * Z),0x006400); } // save the state in the Seed on exit in case we are called again *Seed = StateA; } Edited 2020-08-11 06:19 by Sasquatch -Carl |
||||
twofingers Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1526 |
Hi Carl, it looks beautiful. Very nice! ![]() Thank you! I think we need many CSUB examples. Kind regards Michael causality ≠correlation ≠coincidence |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
Hi Carl, Can I include your CSub version of the Barnsley Fern on the Welcome Tape ? Best wishes, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Sasquatch![]() Guru ![]() Joined: 08/05/2020 Location: United StatesPosts: 376 |
Sure thing, I just put up a few of my experiments in case someone else finds them interesting. You can use anything I have posted here on the TBS. -Carl |
||||
Sasquatch![]() Guru ![]() Joined: 08/05/2020 Location: United StatesPosts: 376 |
Here is an updated version of the CSUB Barnsley Fern V1.1 I have made the following changes: Fixed the USB keyboard issues Added command key reminders to the bottom of the screen Modified to work at other screen resolutions i.e Mode 9,8 This will likely be the final version of this program 'C' Source code included in .zip file CSubFern.zip -Carl |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
Hi Carl, Reading between the lines, was the "hang" that was reported just that the program was unresponsive to the USB keyboard and I didn't notice since I was using a connection to the serial console? Regards, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Sasquatch![]() Guru ![]() Joined: 08/05/2020 Location: United StatesPosts: 376 |
YES! I believe it was running, just not processing input from some USB keyboards. Both the USB Keyboard and the serial console have an issue if the CSUB does not allow MMBasic to process background functions often enough. So it's really an issue of CSUBS that take longer than about 1ms to process need to cooperate with MMBasic by calling the RoutineChecks() function frequently. Some USB keyboards seem WAY more sensitive to this issue than others, and I'm not sure why. I have some USB keyboards that work flawlessly even if the CSUB processes several seconds. I finally found one cheap USB keyboard that exhibits the problems that users have reported with the MandelbrotEXP and CSubFern programs. I'm tempted to throw the %$%(#* keyboard away, but now it's useful for testing. I put the fixes into the MandelbrotEXP program a while ago and am now just getting around to patching the CSUBFern program. I have a "final" version of the 8bit color MandelbrotEXP almost ready. Now I am working on a full 16bit color version that computes "partial iterations" for smooooth color shading. Edited 2020-09-13 08:13 by Sasquatch -Carl |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |