Donut in C
Series: blog
Andy Sloane has written a nice explanation how to write the donut.c without the math library.
In short he does it by using a fixed rotation matrix for each iteration step with normalization between.
i,j,k,x,y,o,N;
main(){float z[1760],a
#define R(t,x,y) f=x;x-=t*y\
;y+=t*f;f=(3-x*x-y*y)/2;x*=f;y*=f;
=0,e=1,c=1,d=0,f,g,h,G,H,A,t,D;char
b[1760];for(;;){memset(b,32,1760);g=0,
h=1;memset(z,0,7040);for(j=0;j<90;j++){
G=0,H=1;for(i=0;i<314;i++){A=h+2,D=1/(G*
A*a+g*e+5);t=G*A *e-g*a;x=40+30*D
*(H*A*d-t*c);y= 12+15*D*(H*A*c+
t*d);o=x+80*y;N =8*((g*a-G*h*e)
*d-G*h*a-g*e-H*h *c);if(22>y&&y>
0&&x>0&&80>x&&D>z[o]){z[o]=D;b[o]=(N>0
?N:0)[".,-~:;=!*#$@"];}R(.02,H,G);}R(
.07,h,g);}for(k=0;1761>k;k++)putchar
(k%80?b[k]:10);R(.04,e,a);R(.02,d,
c);usleep(15000);printf('\n'+(
" donut.c! \x1b[23A"));}}
/*no math lib needed
.@a1k0n 2021.*/I strongly suggest to also check out the original donut.c article from 2011.
If you want to dig a bit deeper into the “graphic” part, read the logo animation article, too.
This is a post in the blog series.
Other posts in this series:
- March 11, 2025 - calculator challenges
- March 11, 2025 - phishing and countermeasure
- January 30, 2025 - more resources for learning and using git (2)
- January 19, 2025 - on reliability of services
- January 13, 2025 - outdated infrastructure references
- November 20, 2024 - connect remotely to a Linux machine
- November 14, 2024 - on Traefik ingress stuck in progressing in ArgoCD
- September 7, 2024 - common mistakes in Go
- September 5, 2024 - minimal perfect hashing
- August 14, 2024 - Kubernetes stalk
- August 11, 2024 - A/B testing
- July 26, 2024 - Kubernetes Security - CtF style learning & pentesting
- July 3, 2024 - probabilistic database lookup
- June 25, 2024 - deleting stuck namespace in kubernetes
- May 2, 2024 - random points on spheres
- April 27, 2024 - Kubernetes Network Policies
- March 10, 2024 - hints for using ssh
- March 9, 2024 - notes from creating TLS setups
- November 29, 2023 - about "being glue"
- November 29, 2023 - the POSIX test command
- November 20, 2023 - data visualization pitchfalls
- November 19, 2023 - digital logic
- November 19, 2023 - expenses of Signal in 2023
- November 1, 2023 - aspell and markdown
- October 31, 2023 - emoji and grapheme clusters
- October 31, 2023 - layerform
- October 31, 2023 - Platform Engineering talk from Liz at gotoCPH
- October 29, 2023 - risks of embedded bare repositories
- October 28, 2023 - Donut in C
- October 19, 2023 - introduction-to-golang
- October 11, 2023 - cache-strategy-from-http-to-db
- August 11, 2023 - cloud native software engineering
- August 10, 2023 - thread modelling 101 (DE)
- August 9, 2023 - Cloudland 2023
- July 21, 2023 - IGER - Intergalaktische Erfahrungsreise 2023
- July 5, 2023 - Conflict-free Replicated Data Type
- June 27, 2023 - voronoi diagrams
- June 19, 2023 - wireguard
- June 15, 2023 - GPN21
- May 16, 2023 - a crypto near miss
- May 3, 2023 - OpenAI: Multimodal Neurons
- April 24, 2023 - programming language playground
- April 19, 2023 - load balancing
- April 17, 2023 - calculus exercise
- April 17, 2023 - eBPF
- April 6, 2023 - clustering: BanditPAM
- April 5, 2023 - binding Haskell to Rust
- March 30, 2023 - awk tech notes
- March 20, 2023 - AI vs AI: Glaze
- March 6, 2023 - how to parse RegExp
- March 1, 2023 - how to write a spell corrector
- February 27, 2023 - LPI DevOps Tools Engineer Certification
- February 21, 2023 - ChatGPT explained
- February 10, 2023 - FosDem 2023 recordings
- January 28, 2023 - Hello World
- January 24, 2023 - mainless C++
- January 19, 2023 - !!Con
- January 9, 2023 - resources for learning git
- January 9, 2023 - text to speech with python
- November 30, 2022 - DevOps road map
- November 4, 2022 - Kubernetes Security - book and learning environment
- September 19, 2022 - yubikey details
- September 9, 2022 - learning by doing: writing network services
- August 30, 2022 - FrosCon2022: How to PullRequest
- July 22, 2022 - cache awareness
- June 29, 2022 - quantum computing 101
- May 30, 2022 - GPN20: alerting
- April 27, 2022 - SE-Linux game
- April 21, 2022 - sorting algorithms
- April 19, 2022 - evil compiler
- April 19, 2022 - reasons to master git cli
- April 13, 2022 - bash pipe - how to fail
- March 8, 2022 - CVE-2022-0492 for fun
- February 21, 2022 - caches, what can go wrong and to to deal with it
- February 17, 2022 - HashiTalks2022
- February 8, 2022 - average of integers
- February 7, 2022 - FosDem 2022 artifacts
- January 26, 2022 - systemd by example
- January 20, 2022 - jsoniq
- January 20, 2022 - shell dotfiles and when they are used
- January 9, 2022 - rC3 nowhere suggestions
- December 16, 2021 - pitfalls in performance monitoring
- December 10, 2021 - explain shell
- November 25, 2021 - PackagingCon
- November 8, 2021 - Real World OCaml
- November 1, 2021 - inject by unicode
- October 26, 2021 - ARM only buffer overflow
- October 21, 2021 - functional basics in pictures
- October 13, 2021 - high performance computing 101
- October 5, 2021 - how to script in bash
- July 30, 2021 - serialization of algebraic data types
- July 29, 2021 - write up: from stolen laptop to inside the company network
- July 2, 2021 - Playlist from Karlsruher Entwicklertag 2021
- June 23, 2021 - distributed systems reading list
- June 23, 2021 - memory leak with C++ runtime
- June 16, 2021 - homomorphic encryption
- June 14, 2021 - command-line-secrets
- June 7, 2021 - kubeinvaders for k8s chaos engineering
- June 4, 2021 - large scale systemdesign
- June 3, 2021 - implicit differenciation
- May 19, 2021 - computing fibonacci the dynamic way