master
Miloslav Ciz 2 years ago
parent f7e0fb4b27
commit 556653d6e4

@ -18,6 +18,7 @@ Here is a list of some acronyms:
- **[ANCAP](ancap.md)** (anarcho capitalist)
- **[ANPAC](anpac.md)** (anarcho pacifist)
- **[ANSI](ansi.md)** (american national standards institute)
- **[AO](ao.md)** (ambient occlusion)
- **[API](api.md)** (application programming interface)
- **[ARM](arm.md)** (advanced [RISC](risc.md) machines)
- **[ARPANET](arpanet.md)** (advanced research projects agency network)
@ -58,6 +59,7 @@ Here is a list of some acronyms:
- **[CPU](cpu.md)** (central processing unit)
- **[CRC](crc.md)** (cyclic redundancy check)
- **[CRT](crt.md)** (cathode ray tube)
- **[CSG](csg.md)** (constructive solid geometry)
- **[CSS](css.md)** (cascading style sheet)
- **[CSV](csv.md)** (comma separated values)
- **[DAC](dac.md)** (digital analog converter)
@ -112,6 +114,7 @@ Here is a list of some acronyms:
- **[GBPS](gbps.md)** (GB per second)
- **[GCC](gcc.md)** (GNU compiler collection)
- **[GDB](gdb.md)** (GNU debugger)
- **[GI](gi.md)** (global illumination)
- **[GIB](gib.md)** (gibibyte)
- **[GIF](gif.md)** (graphics interchange format)
- **[GIGO](gigo.md)** (garbage in garbage out)
@ -240,6 +243,7 @@ Here is a list of some acronyms:
- **[OSI](osi.md)** ([open source](open_source.md) initiative)
- **[P2P](p2p.md)** (peer to peer)
- **[PB](pb.md)** (petabyte, petabit, personal best)
- **[PBR](pbr.md)** (physically based rendering)
- **[PC](pc.md)** (personal computer, political correctness)
- **[PD](pd.md)** ([public domain](public_domain.md))
- **[PDF](pdf.md)** (portable document format)
@ -281,6 +285,7 @@ Here is a list of some acronyms:
- **[SAF](saf.md)** (smallabstractfish)
- **[SCL](smallchesslib)** (smallchesslib)
- **[SD](sd.md)** (standard definition, secure digital)
- **[SDF](sdf.md)** (signed distance function)
- **[SDK](sdk.md)** (software development kit)
- **[SDL](sdl.md)** (simple directmedia layer)
- **[SEO](seo.md)** (search engine optimization)

@ -60,7 +60,7 @@ Notice that *x*, *divisor counter* and *currently checked number* are [variables
| | | |
| V | |
--------------<------------- |
V
V no
divisor count = 2 ? ------
| |
| yes |
@ -107,8 +107,8 @@ int main(void)
printf("number of divisors: %d\n",divisors);
if (divisors == 2)
puts("It is a prime!");
if (divisors == 2)
puts("It is a prime!");
return 0;
}

@ -0,0 +1,3 @@
# Apple
Apple is a [terrorist](terrorism.md) organization and one of the biggest [American](usa.md) computer fashion [corporations](corporation.md), infamously founded by [Steve Jobs](steve_jobs.md), it creates and sells overpriced, abusive, highly consumerist electronic devices.

@ -1,6 +1,6 @@
# Bill Gates
William "Bill" Gates (28.10.1955 -- hopefully soon) is a [mass murderer and rapist](entrepreneur.md) (i.e. [capitalist](capitalism.md)) who started [Micro$oft](microsoft.md).
William "Bill" Gates (28.10.1955 -- hopefully soon) is a [mass murderer and rapist](entrepreneur.md) (i.e. [capitalist](capitalism.md)) who established and led the terrorist organization [Micro$oft](microsoft.md).
He is really dumb, only speaks one language and didn't even finish university. He also has no moral values, but that goes without saying for any rich businessman. He was owned pretty hard in [chess](chess.md) by Magnus Carlsen on some shitty TV show.

@ -32,7 +32,7 @@ During covid chess has experienced boom among normies and [YouTube](youtube.md)
{[This](https://www.youtube.com/watch?v=DpXy041BIlA) is an absolutely amazing video about weird chess algorithms :) ~drummyfish}
Chess have a very strong relationship with computers, computers help people play chess, train their skills but also analyze positions, create and search game databases and find new play styles. The game also provides a nice framework for machine learning.
Chess have a very strong relationship with computers, computers help people play chess, train their skills but also analyze positions, perform research about chess, create and search game databases and find new play styles. The game also provides a nice framework for machine learning.
There is a great online Wiki focused on programming chess engines: https://www.chessprogramming.org.
@ -40,7 +40,7 @@ Chess software is usually separated to **libraries**, **chess engines** and **fr
For communication between different engines and frontends there exist standards such as XBoard (engine protocol), UCI (another engine protocol), FEN (way of encoding a position as a string), PGN (way of encoding games as strings) etc.
Computers have already surpassed the best humans in their strength (we can't exactly compute an engine's Elo as it depends on hardware used, but generally the strongest would rate high above 3000). As of 2021 the strongest chess engine is considered to be the [FOSS](foss.md) engine [Stockfish](stockfish.md), with other strong engines being e.g. Leela Chess Zero (also FOSS) or AlphaZero ([proprietary](proprietary.md), by [Google](google.md)). [GNU Chess](gnu_chess.md) is a reasonably strong [free software](free_software.md) engine by [GNU](gnu.md). There are world championships for chess engines such as the *Top Chess Engine Championship* or *World Computer Chess Championship*. [CCRL](https://ccrl.chessdom.com/ccrl/4040/) is a list of chess engines along with their Elo ratings. Despite the immense strength of modern engines, there are still very specific situation in which humans beat the computer (shown e.g. in [this](https://www.youtube.com/watch?v=R9IZWgArWUE) video).
Computers have already surpassed the best humans in their playing strength (we can't exactly compute an engine's Elo as it depends on hardware used, but generally the strongest would rate high above 3000 FIDE). As of 2021 the strongest chess engine is considered to be the [FOSS](foss.md) engine [Stockfish](stockfish.md), with other strong engines being e.g. Leela Chess Zero (also FOSS) or AlphaZero ([proprietary](proprietary.md), by [Google](google.md)). [GNU Chess](gnu_chess.md) is a reasonably strong [free software](free_software.md) engine by [GNU](gnu.md). There are world championships for chess engines such as the *Top Chess Engine Championship* or *World Computer Chess Championship*. [CCRL](https://ccrl.chessdom.com/ccrl/4040/) is a list of chess engines along with their Elo ratings. Despite the immense strength of modern engines, there are still very specific situation in which humans beat the computer (shown e.g. in [this](https://www.youtube.com/watch?v=R9IZWgArWUE) video).
The first chess computer that beat the world champion (at the time Gary Kasparov) was famously [Deep Blue](deep_blue.md) in 1997. [Alan Turing](turing.md) himself has written a chess playing algorithm but at his time there were no computers to run it, so he executed it by hand -- nowadays the algorithm has been implemented on computers (there are bots playing this algorithm e.g. on lichess).
@ -54,10 +54,14 @@ Playing strength is not the only possible measure of chess engine quality, of co
Programming chess is a [fun](fun.md) and enriching experience and is therefore recommended as a good exercise. There is nothing more satisfying than writing a custom chess engine and then watching it play on its own.
The core of chess programming is writing the [AI](ai.md), everything else, i.e. implementing the rules, communication protocols etc., is pretty straightforward (still a good exercise for beginner programmers). Nevertheless one has to pay a great attention to eliminating as many bugs as possible; really, the importance of writing automatic tests can't be stressed enough as debugging the AI will be hard enough and can become unmanageable with small bugs creeping in.
The core of chess programming is writing the [AI](ai.md), everything else, i.e. implementing the rules, communication protocols etc., is pretty straightforward (but still a good programming exercise). Nevertheless one has to pay a great attention to eliminating as many bugs as possible; really, the importance of writing automatic tests can't be stressed enough as debugging the AI will be hard enough and can become unmanageable with small bugs creeping in.
The AI itself works in almost all cases on the same principle: firstly we implement so called static **evaluation function** -- a function that takes a chess position and outputs its evaluation number which say how good the position is for white vs black (positive number favoring white, negative black). This function considers a number of factors such as total material of both players, pawn structure, king safety, piece mobility and so on (in new engines this function is often a learned [neural network](neural_network.md), but it may very well be written by hand). Secondly we implement a **search** algorithm that recursively searches the game tree and looks for a move that will lead to the best result, i.e. to position for which the evaluation function gives the best value. This basic principle, especially the search part, gets very complex as there are many possible weaknesses and optimizations.
Exhaustively searching the tree to great depths is not possible due to astronomical numbers of possible move combinations, so the engine has to limit the depth quite greatly. Normally it will search all moves to a small depth (e.g. 2 or 3 half moves or *plys*) and then extend the search for interesting moves such as exchanges or checks. Maybe the greatest danger of searching algorithms is so called **horizon effect** which has to be addressed somehow (e.g. by detecting quiet positions, so called *quiescence*). If not addressed, the horizon effect will make an engine misevaluate certain moves by stopping the evaluation at certain depth even if the played out situation would continue and lead to a vastly different result (imagine e.g. a queen taking a pawn which is guarded by another pawn; if the engine stops evaluating after the pawn take, it will think it's a won pawn, when in fact it's a lost queen). There are also many techniques for reducing the number of searched tree nodes and speeding up the search, for example pruning methods such as **alpha-beta** (which subsequently works best with correctly ordering moves to search), or **transposition tables** (remembering already evaluated position so that they don't have to be evaluated again when encountered by a different path in the tree).
Many other aspects come into the AI design such as opening books (databases of best opening moves), endgame tablebases (databases of winning moves in simple endgames), heuristics in search, clock management, pondering (thinking on opponent's move), learning from played games etc. For details see the above linked chess programming wiki.
Many other aspects come into the AI design such as opening books (databases of best opening moves), endgame tablebases (databases of winning moves in simple endgames), heuristics in search, clock management, pondering (thinking on opponent's move), learning from played games etc. For details see the above linked chess programming wiki.
## Rules
TODO

@ -0,0 +1,7 @@
# Collision
Collision happens when two or more things want to occupy the same spot. This situation usually needs to be addressed somehow; then we talk about **collision resolution**. In [programming](programming.md) there are different types of collisions, for example:
- **[hash](hash.md) collision**: When two items produce the same hash, they will map to the same index in a [hash table](hash_table.md). Typical solution is to have a [list](list.md) at each table index so that multiple items can fit there.
- **collision of bodies in a [physics engine](physics_engine.md)**: See [collision_detection](collision_detection.md). These collision are resolved by separating the bodies and updating their velocities so that they "bounce off" as in [real life](irl.md).
- **request collision**: General situation in which multiple clients request access to something that can be used only by one client at a time, e.g. a communication [bus](bus.md). Resolution is usually done by some kind of [arbiter](arbiter.md) who decides, by whatever algorithm, who to grant the access to.

@ -0,0 +1,21 @@
# Collision Detection
Collision detection is an essential problem e.g. of simulating physics of mechanical bodies in [physics engines](physics_engine.md) (but also elsewhere), it tries to detect whether (and also how) geometric shapes overlap. Here we'll be talking about the collision detection in physics engine, but the problem appear in other contexts too (e.g. [frustum culling](frustum_culling.md) in [computer graphics](graphics.md)). Collision detection potentially leads to so called *collision resolution*, a different stage that tries to deal with the detected collision (separate the bodies, update their velocities, make them "bounce off"). Physics engines are mostly divided into 2D and 3D ones so we also normally either talk about 2D or 3D collision detection (3D being, of course, a bit more complex).
There are two main types of collision detection:
- **[discrete](discrete.md)**: Detecting collisions only at discrete points in time (each engine tick or "frame") -- this is easier but can result in detecting the collisions in wrong ways or missing them completely (imagine a fast flying object that in one moment is wholly in front of a wall and at the next instant wholly behind it). Nevertheless this is completely usable, one just has to be careful enough about the extreme cases.
- **[continuous](continuous.md)**: Detecting collisions considering the continuous motion of the bodies (still done at discrete ticks but [analytically](analytical.md) considering the whole motion since the last tick) -- this is more difficult to program and more costly to compute, but also correctly detects collisions even in extreme cases. Sometimes engines perform discrete detection by default and use continuous detection in special cases (e.g. when speeds become very high or in other error-prone situations). Continuous detection can be imagined as a collision detection of a higher dimensional bodies where the added dimension is time -- e.g. detecting collisions of 2D spheres becomes detecting collisions of "tubes" in 3D space. If you don't want to go all the way to implementing continuous collisions, you may consider an in-between solution by detecting collisions in smaller steps (which may also be done only sometimes, e.g. only for high speed bodies or only when an actual discrete collision is detected).
Collision detection is non-trivial because we need to detect not only the presence of the collision but also its parameters which are typically the exact **point of collision, collision depth and collision [normal](normal.md)** -- these are needed for subsequently resolving the collision (typically the bodies will be shifted along the normal by the collision depth to become separated and [impulses](impulse.md) will be applied at the collision point to update their velocities). We also need to detect **general cases**, i.e. collisions of whole volumes (imagine e.g. a tiny cuboid inside an arbitrarily rotated bigger cone). This is very hard and/or expensive for some complex shapes such as general 3D triangle meshes (which is why we approximate them with simpler shapes). We also want the detection algorithm to be at least reasonably **fast** -- for this reason collision detection mostly happens in two phases:
- **broad phase**: Quickly estimates which bodies MAY collide, usually with [bounding volumes](bounding_volume.md) (such as spheres or [axis aligned bounding boxes](aabb.md)) or space indexing and algorithms such as *[sweep and prune](sweep_and_prune.md)*. This phase quickly opts-out of checking collision of objects that definitely CANNOT collide because they're e.g. too far away.
- **narrow phase**: Applying the precise, expensive collision detection on the potentially colliding pairs of bodies determined in the broad phase. This yields the real collisions.
In many cases it is also important to correctly detect the **order of collisions** -- it may well happen a body collides not with one but with multiple bodies at the time of collision detection and the computed behavior may vary widely depending on the order in which we consider them. Imagine that body *A* is colliding with body *B* and body *C* at the same time; in [real life](real_life.md) *A* may have first collided with *B* and be deflected so that it never hits *C*, or the other way around, or it might have collided with both. In continuous collision detection we know the order as we also have exact time coordinate of each collision (even though the detection itself is still computed at discrete time steps), i.e. we know which one happened first. With discrete collisions we may use [heuristics](heuristic.md) such as the direction in which the bodies are moving, but this may fail in certain cases (considering e.g. rotations).
**On shapes**: general rule is that **mathematically simpler shapes are better for collision detection**. Spheres (or circles in 2D) are the best, they are stupidly simple -- a collision of two spheres is simply decided by their [distance](distance.md) (i.e. whether the distance of their center points is less that the sum of the radia of the spheres), which also determines the collision depth, and the collision normal is always aligned with the vector pointing from one sphere center to the other. So **if you can, use spheres** -- it is even worth using multiple spheres to approximate more complex shapes if possible. [Capsules](capsule.md) ("extruded spheres"), infinite planes, half-planes, infinite cylinders (distance from a line) and axis-aligned boxes are also pretty simple. Cylinders and cuboids with arbitrary rotation are bit harder. Triangle meshes (the shape most commonly used for real-time 3D models) are very difficult but may be [approximated](approximation.md) e.g. by a [convex hull](convex_hull.md) which is manageable (a convex hull is an intersection of a number of half-spaces) -- if we really want to precisely collide full 3D meshes, we may split each one into several convex hulls (but we need to write the non-trivial splitting algorithm of course). Also note that you need to write a detection algorithm for any possible pair of shape types you want to support, so for *N* supported shapes you'll need *N * (N + 1) / 2* detection algorithms.
{ In theory we may in some cases also think about using iterative/numerical methods to find collisions, i.e. starting at some point between the bodies and somehow stepping towards their intersection until we're close enough. Another ideas I had was to use [signed distance functions](sdf.md) for representing static environments, it could have some nice advantages. But I'm really not sure how well or whether it would really work. ~drummyfish }
TODO: some actual algorithms

@ -33,6 +33,8 @@ Going for the simple technology doesn't necessarily have to mean we have to give
At the moment it's just me, [drummyfish](drummyfish.md). This started as a collaborative wiki name *based wiki* but after some disagreements I forked it (everything was practically written by me at that point) and made it my own wiki where I don't have to make any compromises or respect anyone else's opinions. I'm not opposed to the idea of collaboration but I bet we disagree on something in which case I probably don't want to let you edit this. I also resist allowing contributions because with multiple authors the chance of legal complications grows, even if the work is under a free license or waiver (refer to e.g. the situation where some Linux developers were threatening to withdraw their code contribution license). But you can totally fork this wiki, it's [public domain](cc0.md).
If you want to contribute to the cause, just create your own website, spread the ideas you liked here -- you may or may not refer to LRS, everything's up to you. Start creating software with LRS philosophy if you can -- together we can help evolve and spread our ideas in a decentralized way, without me or anyone else being an authority, a potential censor. That's the best way forward I think.
### Since it is public domain, can I take this wiki and do anything with it? Even something you don't like, like sell it or rewrite it in a different way?
Yes, you can do anything... well, anything that's not otherwise illegal like falsely claiming authorship (copyright) of the original text. This is not because I care about being credited, I don't (you DON'T have to give me any credit), but because I care about this wiki not being owned by anyone. You can however claim copyright to anything you add to the wiki if you fork it, as that's your original creation.

@ -1,3 +1,3 @@
# Firmware
Firmware is a type of very basic [software](software.md) that's usually preinstalled on a device from factory and serves to provide the most essential functionality of the device. On simple devices, like mp3 players or remote controls, firmware may be all that's ever needed for the devices functioning, while on more complex ones, such as [personal computers](pc.md), firmware (e.g. [BIOS](bios.md) or [UEFI](uefi.md)) allows basic configuration, allows installation of more complex software (such as an [operating system](os.md)) and possibly provides functions that the installed software can use. Firmware is typically not meant to be rewritten by the user and is installed in some kind of memory that's not very easy to rewrite, it may even be hard-wired in which case it becomes something on the very boundary of software and [hardware](hardware.md).
Firmware is a type of very basic [software](software.md) that's usually preinstalled on a device from factory and serves to provide the most essential functionality of the device. On simple devices, like mp3 players or remote controls, firmware may be all that's ever needed for the device's functioning, while on more complex ones, such as [personal computers](pc.md), firmware (e.g. [BIOS](bios.md) or [UEFI](uefi.md)) allows basic configuration and installation of more complex software (such as an [operating system](os.md)) and possibly provides functions that the installed software can use. Firmware is normally not meant to be rewritten by the user and is installed in some kind of memory that's not very easy to rewrite, it may even be hard-wired in which case it becomes something on the very boundary of software and [hardware](hardware.md).

@ -0,0 +1,5 @@
# Gatekeeping
[Soyence](soyence.md) practices gatekeeping, they

@ -16,7 +16,7 @@ With [open source](open_source.md) it is relatively easy to make money and earn
Working for [free software](free_software.md) organizations such as the [FSF](fsf.md) is a better way of making living, even though still not perfect: FSF has been facing some criticism of growing corruption and from the [LRS](lrs.md) point of view they do not address many issues of software such as [bloat](bloat.md), [public domain](public_domain.md) etc.
## Way of Making Money with LRS
## Way of Making Money With LRS
Considering all things mentioned above, here are some concrete things of making money on LRS. Keep in mind that a lot of services (PayPal, Patreon etc.) listed here may possibly be [proprietary](proprietary.md) and unethical, so always check them out and consider free alternatives such as [Liberapay](liberapay.md). The methods are following:

@ -6,7 +6,7 @@ Welcome to [Less Retarded Wiki](lrs_wiki.md), an encyclopedia only I can edit. B
This is a Wiki for [less retarded software](lrs.md) (LRS) and related topics, mainly those of [politics](politics.md) and [society](society.md), idealization of which LRS should help achieve. LRS Wiki is a new, refreshing wiki without [political correctness](political_correctness.md).
**We love all living beings. Even you.** We want to create technology that truly and maximally helps you.
**We love all living beings. Even you.** We want to create technology that truly and maximally helps you. We want to move towards society that's not based on [competition](competition.md) but rather on [collaboration](collaboration.md).
This wiki is **NOT** a satire.

@ -0,0 +1,7 @@
# Micro$oft
Micro$soft (officially Microsoft, MS) is a terrorist organization, [software](software.md) [corporation](corporation.md) named after it's founder's dick -- it is, along with [Google](google.md), [Apple](apple.md) [et al](et_al.md) one of the biggest organized crime groups in history, best known for holding the world captive with its highly abusive "[operating system](os.md)" called [Windows](windows.md), as well as for leading an aggressive war on [free software](free_software.md) and utilizing many unethical and/or illegal business practices such as destroying any potential competition with the [*Embrace Extend Extinguish*](eee.md) strategy.
Microsoft is unfortunately among the absolutely most powerful entities in the world (that sucks given they're also among the most hostile ones) -- likely more powerful than any government and most other corporations, it is in their power to **immediately destroy any country** with the push of a button, it's just a question of when this also becomes their interest. This power is due to them having **complete control over almost absolute majority of personal computers in the world** (and therefore by extension over all devices, infrastructure, organization etc.), through their [proprietary](proprietary.md) ([malware](malware.md)) "[operating system](os.md)" [Windows](windows.md) that has built-in [backdoor](backdoor.md), allowing Microsoft immediate access and control over practically any computer in the world. The backdoor "feature" isn't even hidden, it is officially and openly admitted (it is euphemistically called [auto updates](autoupdate.md)). Microsoft prohibits studying and modification of Windows under threats including physical violence (tinkering with Windows violates its [EULA](eula.md) which is a lawfully binding license, and law can potentially be enforced by police using physical force). Besides legal restrictions Microsoft applies high [obfuscation](obfuscation.md), [bloat](bloat.md), [SAASS](saass.md) and other techniques preventing user freedom and defense against terrorism, and forces its system to be installed in schools, governments, power plants, hospitals and basically on every computer anyone buys. Microsoft can basically (for most people) turn off the [Internet](internet.md), electricity, traffic control system etc. Therefore every hospital, school, government and any other institution has to bow to Microsoft.
TODO: it would take thousands of books to write just a fraction of all the bad things, let's just add the most important ones

@ -1,10 +1,12 @@
# Technological Minimalism
Technological minimalism is a philosophy of designing technology to be as simple as possible while still achieving given goal. Minimalism is one of the most (if not the most) important concepts in [programming](programming.md) technology in general. Minimalism goes against complexity of technology which always brings huge cost and dangers, e.g. the cost of maintenance and further development, obscurity, inefficiency ("[bloat](bloat.md)", wasting resources), the increased risk of bugs, errors and failure.
*No gain, no pain.*
Technological minimalism is a philosophy of designing technology to be as simple as possible while still achieving given goal. Minimalism is one of the most (if not the most) important concepts in [programming](programming.md) technology in general. **Minimalism is necessary for [freedom](freedom.md)** as a free technology can only be that over which no one has a monopoly, i.e. which many people and small parties can utilize, study and modify with affordable effort. Minimalism goes against the creeping overcomplexity of technology which always brings huge costs and dangers, e.g. the cost of [maintenance](maintenance.md) and further development, obscurity, inefficiency ("[bloat](bloat.md)", wasting resources), consumerism, the increased risk of bugs, errors and failure.
There is a so called *[airplane rule](airplane_rule.md)* that states a plane with two engines has twice as many engine problems than a plane with a single engine.
Up until recently in history every engineer would tell you that *the better machine is that with fewer moving parts*. This still seems to hold in mathematics, an area inhabited by the smartest people, where there is a tendency to look for the most minimal equations -- such equations are considered [beautiful](beauty.md). Science also knows this rule as the Occam's razor. In technology invaded by aggressive commercialization the situation is different, minimalism lives only in the underground and is ridiculed by the mainstream propaganda. Some of the minimalist movements, terms and concepts include:
Up until recently in history every engineer would tell you that *the better machine is that with fewer moving parts*. This still seems to hold e.g. in mathematics, a field not yet so spoiled by huge commercialization and mostly inhabited by the smartest people -- there is a tendency to look for the most minimal equations -- such equations are considered [beautiful](beauty.md). Science also knows this rule as the Occam's razor. In technology invaded by aggressive commercialization the situation is different, minimalism lives only in the underground and is ridiculed by the mainstream propaganda. Some of the minimalist movements, terms and concepts include:
- [suckless](suckless.md)
- [Unix philosophy](unix_philosophy.md)
@ -12,4 +14,14 @@ Up until recently in history every engineer would tell you that *the better mach
- [countercomplex](countercomplex.md)
- [less retarded software](lrs.md)
Under [capitalism](capitalism.md) technological minimalism dies with possibly only the "shallow" kind of minimalism ([pseudominimalism](pseudominimalism.md)) surviving. This so called "minimalism" tries to make things look minimal only aesthetically and hides ugly overcomplicated internals under this facade. [Apple](apple.md) is known for this [shit](shit.md).
Under [capitalism](capitalism.md) technological minimalism is suppressed in the mainstream as it goes against corporate interests, i.e. those of having monopoly control over technology, even if such technology is "[FOSS](foss.md)" (which then becomes just a cool brand, see [openwashing](openwashing.md)). We may, at best, encounter a "shallow" kind of minimalism, so called [pseudominimalism](pseudominimalism.md) which only tries to make things appear minimal, e.g. aesthetically, and hides ugly overcomplicated internals under the facade. [Apple](apple.md) is famous for this [shit](shit.md).
**Does minimalism mean we have to give up the nice things?** Well, not really, it is more about giving up the [bullshit](bullshit.md), and changing an attitude. **We can still have technology for entertainment**, just a non-consumerist one -- instead of consuming 1 new game per month we may rather focus on creating deeper games that may last longer, e.g. those of a *simple to learn, hard to master* kind and building communities around them, or on modifying existing games rather than creating new ones from scratch over and over. Sure, technology would LOOK different, our computer interfaces may become less of a thing of fashion, our games may rely more on aesthetics than realism, but ultimately minimalism can be seen just as trying to achieve the same effect while minimizing waste. If you've been made addicted to bullshit such as buying a new GPU each month so that you can run games at 1000 FPS at progressively higher resolution then of course yes, you will have to suffer a bit of a withdrawal just as a heroin addict suffers when quitting the drug, but just as him in the end you'll be glad you did it.
## Importance Of Minimalism: Simplicity Brings Freedom
It can't be stressed enough that minimalism is absolutely required for technological freedom, i.e. people having, in **practical** ways, control over their tools. While in today's society it is important to have legal freedoms, i.e. support [free software](free_software.md), we must not forget that this isn't enough, a freedom on paper means nothing if it can't be practiced. We need both legal AND [de facto](de_facto.md) freedom over technology, the former being guaranteed by a free [license](license.md), the latter by minimalism. Minimal, simple technology will increase the pool of people and parties who may practice the legal freedoms -- i.e. those to use, study, modify and share -- and therefore ensure that the technology will be developed according to what people need, NOT according to what a corporation needs (which is usually the opposite).
Even if a user of software is not a programmer himself, it is important he chooses to use minimal tools because that makes it more likely his tool can be repaired or improved by SOMEONE from the people. Some people naively think that if they're not programmers, it doesn't matter if they have access and rights to the program's source code, but indeed that is not the case. You want to choose tools that can easily be analyzed and repaired by someone, even if you yourself can't do it.
Minimalism and simplicity increases freedom even of [proprietary](proprietary.md) technology which can be seen e.g. on [games](game.md) for old systems such as [GameBoy](gameboy.md) or [DOS](dos.md) -- these games, despite being proprietary, can and are easily and plentifully played, modified and shared by the people, DESPITE not being free legally, simply because it is easy to handle them due to their simplicity. This just further confirms the correlation of freedom and minimalism.

@ -10,12 +10,13 @@ These are mainly for [C](c.md), but may be usable in other languages as well.
- **gprof is a utility you can use to profile your code**.
- **`<stdint.h>` has fast type nicknames**, types such as `uint_fast32_t` which picks the fastest type of at least given width on given platform.
- **Keywords such as `inline`, `static` and `const` can help compiler optimize well**.
- **Optimize the bottlenecks!** Optimizing in the wrong place is a complete waste of time. If you're optimizing a part of code that's taking 1% of your program's run time, you will never speed up your program by more than that 1% even if you speed up the specific part by 10000%.
- **Optimize the [bottlenecks](bottleneck.md)!** Optimizing in the wrong place is a complete waste of time. If you're optimizing a part of code that's taking 1% of your program's run time, you will never speed up your program by more than that 1% even if you speed up the specific part by 10000%. Bottlenecks are usually inner-most loops of the main program loop, you can identify them with [profiling](profiling.md).
- **You can almost always trade space (memory usage) for time (CPU demand) and vice versa** and you can also fine-tune this. You typically gain speed by precomputation (look up tables, more demanding on memory) and memory with compression (more demanding on CPU).
- **Learn about [dynamic programming](dynamic_programming.md)**.
- **Avoid branches (ifs)**. They break prediction and instruction preloading and are often source of great performance losses. Don't forget that you can compare and use the result of the operation without using any branching (e.g. `x = (y == 5) + 1;`).
- **Use iteration instead of [recursion](recursion.md)** if possible (calling a function is pretty expensive).
- **Avoid branches (ifs)** if you can (remember [ternary operators](ternary_operator.md), loop conditions etc. are branches as well). They break prediction in CPU pipelines and instruction preloading and are often source of great performance losses. Don't forget that you can many times compare and use the result of operations without using any branching (e.g. `x = (y == 5) + 1;` instead of `x = (y == 5) ? 2 : 1;`).
- **Use iteration instead of [recursion](recursion.md)** if possible (calling a function costs something).
- **You can use good-enough [approximations](approximation.md) instead of completely accurate calculations**, e.g. taxicab distance instead of Euclidean distance, and gain speed or memory without trading.
- **Use quick opt-out conditions**: many times before performing some expensive calculation you can quickly check whether it's even worth performing it and potentially skip it. For example in physics [collision detections](collision_detection.md) you may first quickly check whether the bounding spheres of the bodies collide before running an expensive precise collision detection -- if bounding spheres of objects don't collide, it is not possible for the bodies to collide and so we can skip further collision detection.
- **Operations on static data can be accelerated with accelerating structures** ([look-up tables](lut.md) for functions, [indices](indexing.md) for database lookups, spatial grids for collision checking, ...).
- **Use powers of 2** whenever possible, this is efficient thanks to computers working in binary. Not only may this help nice utilization and alignment of memory, but mainly multiplication and division can be optimized by the compiler to mere bit shifts which is a tremendous speedup.
- **Write [cache-friendly](cache-friendly.md) code** (minimize long jumps in memory).

@ -1,21 +1,23 @@
# Physics Engine
Physics engine is a [software](software.md) (usually a [library](library.md)) whose purpose is to simulate physical laws of mechanics, i.e. things such as forces, [rigid](rigid_body.md) and [soft](soft_body.md) body collisions, particle motion, fluid dynamics etc.
Physics engine is a [software](software.md) (usually a [library](library.md)) whose purpose is to simulate physics laws of mechanics, i.e. things such as forces, [rigid](rigid_body.md) and [soft](soft_body.md) body collisions, [particle](particle.md) motion, fluid dynamics etc.
{ When it comes to classic 3D rigid body physics engines, they're extremely hard to make, much more than for example an advanced 3D rendering engine, especially when you want to make them [LRS](lrs.md) (without floating point, ...) and/or general and somewhat physically correct (being able to simulate e.g. the Dzhanibekov effect, satisfying all the conservation laws, continuous collision detection etc.). Good knowledge of mechanics and things like [quaternions](quaternion.md) and 3D rotations is just the beginning, difficulties arise in every aspect of the engine, and of those there are many. As I've found, 32 bit fixed point is not enough for a general engine (even though it is enough for a rendering engine), you'll run into precision problems as you need to represent both relatively high and low energies. You'll also run into stability issues such as stable contacts, situations with multiple objects stacked on top of each other starting to bounce on their own etc. Even things such as deciding in what order to resolve collisions are very difficult, they can lead to many bugs such as a car not being able to drive on a straight road made of several segments. Collision detection alone for all combinations of basic shapes (sphere, cuboid, cylinder, capsule, ... let alone general triangle mesh) are hard as you want to detect general cases (not only e.g. surface collisions) and you want to extract all the parameters of the collisions (collision point, normal etc.) AND you want to make it fast. And of course you'll want to add acceleration structures and many other thing on top. So think twice before deciding to write your own physics engine.
{ When it comes to classic 3D rigid body physics engines, they're extremely hard to make, much harder than for example an advanced 3D rendering engine, especially when you want to make them [LRS](lrs.md) (without floating point, ...) and/or general and somewhat physically correct (being able to simulate e.g. the Dzhanibekov effect, satisfying all the conservation laws, continuous collision detection etc.). Good knowledge of mechanics and things like [quaternions](quaternion.md) and 3D rotations is just the beginning, difficulties arise in every aspect of the engine, and of those there are many. As I've found, 32 bit fixed point is not enough for a general engine (even though it is enough for a rendering engine), you'll run into precision problems as you need to represent both relatively high and low energies. You'll also run into stability issues such as stable contacts, situations with multiple objects stacked on top of each other starting to bounce on their own etc. Even things such as deciding in what order to resolve collisions are very difficult, they can lead to many bugs such as a car not being able to drive on a straight road made of several segments. Collision detection alone for all combinations of basic shapes (sphere, cuboid, cylinder, capsule, ... let alone general triangle mesh) are hard as you want to detect general cases (not only e.g. surface collisions) and you want to extract all the parameters of the collisions (collision location, depth, normal etc.) AND you want to make it fast. And of course you'll want to add acceleration structures and many other thing on top. So think twice before deciding to write your own physics engine.
A sane approach may be to write a simplified engine specifically for your program, e.g. many times you get away with creating an engine that doesn't work with rigid bodies but some simple meshes made of spheres connected by springs. That's super simple, doable and probably [good enough](good_enough.md). ~drummyfish }
A sane approach may be to write a simplified engine specifically for your program, for example a Minecraft-like game may just need non-rotating capsules in a voxel environment, that's not that hard. You may perhaps get away with a bit of cheating, e.g. simulating rigid bodies as really stiff soft bodies, it may not be as efficient and precise but it's simpler to program. It may be [good enough](good_enough.md). ~drummyfish }
Physics engine is a wide term even though one usually imagines the traditional 3D rigid body engine used in games such as [GTA](gta.md). These engines may nevertheless have different purposes, features and even basic paradigms, some may e.g. be specialized just for computing precise ballistic trajectories for the army, some may serve for simulating weather etc. Some common classifications and possible characteristics of physics engines follow:
- **[2D](2d.md) vs [3D](3d.md)**: 2D engines are generally much more simple to implement than 3D, for example because of much more simple math for rotations and collision detections.
- **[2D](2d.md) vs [3D](3d.md)**: 2D engines are generally much more simple to implement than 3D, for example because of much more simple math for rotations and collision detection. Graphics and physics are usually loosely interconnected (though they should be [decoupled](coupling.md)) in that the way in which we represent graphics (2D, general 3D, [BSP](bsp.md), [voxels](voxel.md), ...) usually also determines how we compute physics, so that there may also exist e.g. "[pseudo 3D](pseudo_3d.md)" physics engines as part of "pseudo 3D" renderers, e.g. the one used in [Doom](doom.md) etc.
- **[real time](real_time.md) vs [offline](offline.md)**: Real-time ones are mostly intended to be used in the entertainment industry, i.e. [games](game.md), movies etc. as they can compute somewhat realistic looking results quickly but for the price of dropping high accuracy (they use many [approximations](approximation.md)). Scientific engines may prefer to be offline and taking longer time to compute more precise results.
- **[rigid body](rigid_body.md) vs [soft body](soft_body.md)**: Rigid body engines don't allow bodies to deform while soft body ones do -- in real life all bodies are soft, but neglecting this detail and considering shapes rigid can have benefits (such as being able to consider the body as a whole and not having to simulate all its individual points). Of course, a complex engine may implement both rigid and soft body physics.
- **paradigm**: The basic approach to implementing the simulation, e.g. being [impulse](impulse.md)-based (applying impulses to correct errors), constraint-based (solving equations to satisfy imposed constraints), penalty-based (trying to find equilibriums of forces) etc.
- **[discrete](discrete.md) vs [continuous](continuous.md) collision detection**: Discrete collision detection only detects collisions at single points in time (at each engine tick) and are simple than those implementing continuous collision detection. Discrete engine are less accurate, consider e.g. that a very fast moving object can pass through a wall because at one instant it is in front of it while at the next tick it is behind it. Continuous collisions won't allow this to happen, but are more difficult to program, may be slower etc. For games discrete collisions are usually [good enough](good_enough.md).
- **features: fluid, cloth, particles, [ragdoll](ragdoll.md), [inverse kinematics](inverse_kinematics.md), [GPU](gpu.md) acceleration, [determinism](determinism.md), [voxels](voxel.md), ...**: These are a number of additional features the engine can have such as the ability to simulate fluids (which itself is a huge field of its own) or cloths.
- **features: fluid, cloth, particles, [ragdoll](ragdoll.md), [inverse kinematics](inverse_kinematics.md), [GPU](gpu.md) acceleration, [determinism](determinism.md), [voxels](voxel.md), [acceleration](acceleration.md) [data structures](data_structure.md) ...**: These are a number of additional features the engine can have such as the ability to simulate fluids (which itself is a huge field of its own) or cloths, some go as far as e.g. integrating motion-captured animations of humans with physics to create smooth realistic animations e.g. of running over walking pedestrians with a car and so on.
A typical physics engine will work something like this: we create a so called **physics world**, a [data structure](data_structure.md) that represents the space in which the simulation takes place (it is similar to a [scene](scene.md) in rendering engines). We then populate this world with physics elements such as rigid bodies (which can have attributes such as mass, elasticity etc.). These bodies are normally basic geometric shapes such as spheres, cylinders, boxes or capsules, or objects composed of several such basic shapes. This is unlike with rendering engines in which we normally have triangle meshes -- in physics engines triangle meshes are extremely slow to process, so for the sake of a physics engine we approximate this mesh with some of the above basic shapes (for example a creature in a game that's rendered as a hi-poly 3D model may in the physics engine be something as simple as a plain sphere). Furthermore the bodies can be **[static](static.md)** (cannot move, this is sometimes done by setting the mass to infinity) or **[dynamic](dynamic.md)** (can move); static bodies normally represent the environment (e.g. the game level), dynamic ones the entities in it (player, NPCs, projectiles, ...). Making a body static has performance benefits as its movement doesn't have to be calculated and the engine can also precalculate some things for it that will make e.g. collision detections faster. We then simulate the physics of the world in so called *ticks* (similar to [frames](frame.md) in rendering); in simple cases one tick can be equivalent to one rendering frame, but properly it shouldn't be so (physics shouldn't be affected by the rendering speed, and also for the physics simulation we can usually get away with smaller "[FPS](fps.md)" than for rendering, saving some performance). Usually one tick has set some constant time length (e.g. 1/60th of a second). In each tick the engine performs a **collision detection**, i.e. it finds out which bodies are touching or penetrating other bodies (this is accelerated with things such as [bounding spheres](bounding_sphere.md)). Then it performs so called **collision resolution**, i.e. updating the positions, velocities and forces so that the bodies no longer collide and react to these collisions as they would in the real world (e.g. a ball will bounce after hitting the floor). There can be many more things, for example **constraints**: we may e.g. say that one body must never get further away from another body than 10 meters (imagine it's tied to it by a rope) and the engine will try to make it so that this always holds. The engine will also offer a number of other functions such as casting rays and calculating where it hits (obviously useful for shooter games).
A typical physics engine will work something like this: we create a so called **physics world**, a [data structure](data_structure.md) that represents the space in which the simulation takes place (it is similar to a [scene](scene.md) in rendering engines). We then populate this world with physics elements such as rigid bodies (which can have attributes such as mass, elasticity etc.). These bodies are normally basic geometric shapes such as spheres, cylinders, boxes or capsules, or objects composed of several such basic shapes. This is unlike with rendering engines in which we normally have triangle meshes -- in physics engines triangle meshes are extremely slow to process, so for the sake of a physics engine we approximate this mesh with some of the above basic shapes (for example a creature in a game that's rendered as a hi-poly 3D model may in the physics engine be represented just as a simple sphere). Furthermore the bodies can be **[static](static.md)** (cannot move, this is sometimes done by setting their mass to infinity) or **[dynamic](dynamic.md)** (can move); static bodies normally represent the environment (e.g. the game level), dynamic ones the entities in it (player, NPCs, projectiles, ...). Making a body static has performance benefits as its movement doesn't have to be calculated and the engine can also precalculate some things for it that will make e.g. collision detections faster. We then simulate the physics of the world in so called *ticks* (similar to [frames](frame.md) in rendering); in simple cases one tick can be equivalent to one rendering frame, but properly it shouldn't be so (physics shouldn't be affected by the rendering speed, and also for the physics simulation we can usually get away with smaller "[FPS](fps.md)" than for rendering, saving some performance). Usually one tick has set some constant time length (e.g. 1/60th of a second). In each tick the engine performs a **[collision detection](collision.md)**, i.e. it finds out which bodies are touching or penetrating other bodies (this is accelerated with things such as [bounding spheres](bounding_volume.md)). Then it performs so called **collision resolution**, i.e. updating the positions, velocities and forces so that the bodies no longer collide and react to these collisions as they would in the real world (e.g. a ball will bounce after hitting the floor). There can be many more things, for example **constraints**: we may e.g. say that one body must never get further away from another body than 10 meters (imagine it's tied to it by a rope) and the engine will try to make it so that this always holds. The engine will also offer a number of other functions such as casting rays and calculating where it hits (obviously useful for shooter games).
**Integrating physics with graphics**: you will most likely use some kind of graphics engine along with physics engine, even if just for [debugging](debugging.md). As said above, keep in mind a graphics and physics engines should be **strictly separated** ([decoupled](coupling.md), for a number of reasons such as [reusability](reusability.md), easier debugging, being able to switch graphics and physics engines etc.), even though they closely interact and may affect each other in their design, e.g. by the data structures you choose for your program (voxel graphics will imply voxel physics etc.). In your program you will have a **physics world and a graphics scene**, both contain their own elements: the scene has graphics elements such as 3D models or particle systems, the physics world has elements such as rigid bodies and force fields. Some of the graphical and physics entities are connected, for example a 3D model of a tree may be connected to a physics rigid body of a cone shape. NOT ALL graphics elements have counterparts in the physics simulation (e.g. a smoke effect or light aren't present in the physics simulation) and vice versa (e.g. player in a first-person game has no 3D model but still has some physics shape). The connection between graphics and physics elements should be done **above** both engines (i.e. do NOT add pointers to physics object to graphics elements etc.). This means that e.g. in a game you create a higher abstract environment -- for example a level -- which stands above the graphics scene and physics world and has its own game elements, each game element may be connected to a graphics or physics element. These game elements have attributes such as a position which gets updated according to the physics engine and which is transferred to the graphics elements for rendering. Furthermore remember that **graphics and physics should often run on different "FPS"**: graphics engines normally try to render as fast as they can, i.e. reach the highest [FPS](fps.md), while physics engines often have a time step, called a **tick**, of fixed time length (e.g. 1/30th of a second) -- this is so that they stay [deterministic](determinism.md), accurate and also because physics may also run on much lower FPS without the user noticing ([interpolation](interpolation.md) can be used in the graphics engine to smooth out the physics animation for rendering). "[Modern](modern.md)" engines often implement graphics and physics in separate [threads](thread.md), however this is not [suckless](suckless.md), in most cases we recommend the [KISS](kiss.md) approach of a single thread (in the main loop keep a timer for when the next physics tick should be simulated).
## Existing Engines

@ -4,4 +4,4 @@ Programming is the act and [art](art.md) of writing computer [programs](program.
You may also encounter the term [coding](coding.md) which is used by [noob](noob.md) [wannabe programmers](soydev.md), so called "coders" or [code monkeys](code_monkey.md). "Coding" doesn't reach the quality of programming, it is done in baby handholding languages like [Python](python.md) and [JavaScript](javascript.md) by people with very shallow knowledge of technology and its context, barely qualified to turn on a computer (like [jewtubers](youtube.md)), who have flooded the computer industry since it became lucrative. What they do is not real programming. Do not try to imitate them.
At high level programming becomes [spiritual](spirituality.md). Check out e.g. the famous [Tao of Programming](tao.md) (yes, it's kind of a [joke](jokes.md) but it's based on reality, programming can truly be kind of a [meditation](meditation.md)). Many people say that learning programming opens your eyes in a certain new way, you then see the world like never before (but that's probably kind of true of almost all skills so this may be a [shit](shit.md) statement). Others say too much programming cripples you mentally and gives you [autism](autism.md). Anyway it's [fun](fun.md). Programming requires a good knowledge of advanced [math](math.md). Also probably at least above average [IQ](iq.md), as well as below average social intelligence. Being [man](man.md) is an advantage.
At high level programming becomes [spiritual](spirituality.md). Check out e.g. the famous [Tao of Programming](tao.md) (yes, it's kind of a [joke](jokes.md) but it's based on reality, programming can truly be kind of a [meditation](meditation.md) and pursuit of enlightenment). Many people say that learning programming opens your eyes in a certain new way, you then see the world like never before (but that's probably kind of true of almost all skills so this may be a [shit](shit.md) statement). Others say too much programming cripples you mentally and gives you [autism](autism.md). Anyway it's [fun](fun.md). Programming requires a good knowledge of advanced [math](math.md). Also probably at least above average [IQ](iq.md), as well as below average social intelligence. Being [man](man.md) is an advantage.

@ -2,4 +2,6 @@
Pseudominimalism is the property of technology of trying to appear [minimalist](minimalism.md) on the surface while being [bloated](bloat.md) on the inside. A typical example could be a website that has minimal look -- a blank white background with some fancy-font text perhaps -- which in the background uses dozens of [JavaScript](js.md) frameworks and libraries and requires a high end CPU to even appear responsive. [Apple](apple.md) is heavily practicing pseudominimalism.
Another example are many [modern](modern.md) [CLI](cli.md) programs that [code monkeys](coder.md) use to impress their [YouTube](youtube.md) viewers or to feel like matrix haxors. Some people think that anything running in command line is minimalist which is less and less true as we progress into the future. A lot of [capitalist software](capitalist_software.md) add a CLI interface ex post **on top** of an already bloated program, often by simply disabling [GUI](gui.md) (but leaving all its dependencies in). An example may be the [gomux](gomux.md) chat client.
Another example are many [modern](modern.md) [CLI](cli.md) programs that [code monkeys](coder.md) use to impress their [YouTube](youtube.md) viewers or to feel like matrix haxors. Some people think that anything running in the command line is minimalist which is less and less true as we progress into the future. A lot of [capitalist software](capitalist_software.md) add a CLI interface ex post **on top** of an already bloated program, often by simply disabling [GUI](gui.md) (but leaving all its dependencies in). An example may be the [gomux](gomux.md) chat client.
Yet another kind of pseudominimalism appearing among the new generation of pseudoprogrammers is about writing very few LOC in some hugely bloated language and calling that "minimalism". Something like a *Minecraft clone in 100 LOC of Python using only Python standard library*, the catch of course being that [Python](python.md) itself is hugely bloated and its standard library is enormous, therefore they just hide all the complexity out of view. Such effort is of course completely useless and only serves for flexing in front of beginners who can't spot the trick.

@ -0,0 +1,26 @@
# Signed Distance Function
Signed distance function (SDF, also signed distance field) is a [function](function.md) that for any point in space returns its distance to the closest point of some geometric shape, and also the information whether that point is outside or inside that shape (if inside, the distance is negative, outside it's positive and exactly on the surface it is zero -- hence *signed* distance function). SDFs find use in elegantly representing some surfaces and solving some problems, most notably in computer [graphics](graphics.md), e.g. for smoothly rendering upscaled [fonts](font.md), in [raymarching](raymarching.md), implementing [global illumination](gi.md), as a 3D model storage representation, for [collision detection](collision_detection.md) etc. SDFs can exist anywhere where [distances](distance.md) exist, i.e. in 2D, 3D, even non-[Euclidean](euclidean.md) spaces etc. (and also note the distance doesn't always have to be Euclidean distance, it can be anything satisfying the [axioms](axiom.md) of a distance metric, e.g. [taxicab distance](taxicab.md)).
Sometimes SDF is extended to also return additional information, e.g. the whole [vector](vector.md) to the closest surface point (i.e. not only the distance but also a direction towards it) which may be useful for specific algorithms.
**What is it all good for?** We can for example implement quite fast [raytracing](raytracing.md)-like rendering of environments for which we have a fast SDF. While traditional raytracing has to somehow test each ray for potential intersection against all 3D elements in the scene, which can be slow (and complicated), with SDF we can performs so called [raymarching](raymarching.md), i.e. iteratively stepping along the ray according to the distance function (which hints us on how big of a step we can make so that we can potentially quickly jump over big empty areas) until we get close enough to a surface which we interpret as an intersection -- if the SDF is fast, this approach may be pretty efficient ([Godot](godot.md) implemented this algorithm to render real-time global illumination and reflections even in GPUs that don't support accelerated raytracing). Programs for rendering 3D [fractals](fractal.md) (such as Mandelbulber) work on this principle as well. SDFs can also be used as a format for representing shapes such as [fonts](font.md) -- there exists a method (called multi-channel SDF) that stores font glyphs in bitmaps of quite low-resolution that can be rendered at arbitrary scale in a quality almost matching that of the traditional vector font representation -- the advantage over the traditional vector format is obviously greater simplicity and better compatibility with GPU hardware that's optimized for storing and handling bitmaps. Furthermore we can trivially increase or decrease weight (boldness) of a font represented by SDFs simply by adjusting the rendering distance threshold. SDFs can also be used for [collision detection](collision_detection.md) and many other things. One advantage of using SDFs is their **generality** -- if we have an SDF raymarching algorithm, we can plug in any shape and environment just by constructing its SDF, while with traditional raytracing we normally have to write many specialized algorithms for detecting intersections of rays with different kinds of shapes, i.e. we have many special cases to handle.
**How is an SDF implemented?** Well, it's a [function](function.md), it can be implemented however we wish and need, it depends on the use case, but we probably want it to be **fast** because algorithms that work with SDFs commonly call it often. SDF of simple mathematical shapes (and their possible combinations such as unions, see. e.g. [CSG](csg.md)), e.g. spheres, can be implemented very easily (SDF of a sphere = distance to the sphere center minus its radius); even the already mentioned 3D [fractals](fractal.md) have functions that can be used to quickly estimate the distance towards their surface. Other times -- e.g. where arbitrary shapes may appear -- the function may be [precomputed](precomputing.md) into some kind of N dimensional [array](array.md), we might say we use a precomputed [look up table](LUT.md). This can be done in a number of ways, but as a simple example we can imagine raymarching mirror reflections with which we can subdivide the 3D scene into a grid and into each cell we store the SDF value at its center point (which here may be computed by even a relatively slow algorithm), which will allow for relatively fast search of intersections of rays with the surface (at any point along the ray we may check the SDF value of the current cell which will likely provide information for how big a step we can make next).
```
. . . . . . . . 3 2 2 2 2 2 2 2
. . . . . . . . 3 2 1 1 1 1 1 1
. . . X X X X X 2 2 1 0 0 0 0 0
. . . X X X X X 2 1 1 0-1-1-1 0
. . X X X X X X 2 1 0 0-1-2-1 0
. . X X X X X X 2 1 0-1-1-2-1 0
. . X X X X X X 2 1 0-1-1-1-1 0
. . X X X X X X 2 1 0 0 0-1-1 0
. . . . X X X X 2 1 1 1 0 0 0 0
. . . . . . . . 2 2 2 1 1 1 1 1
```
*Shape (left) and its SDF (right, distances rounded to integers).*
SDFs in computer graphics were being explored a long time ago but seem to have start to become popular since around the year 2000 when Frisken [et al](et_al.md) used adaptive SDFs as an efficient representation for 3D models preserving fine details. In 2007 [Valve](valve.md) published a paper at [SIGGRAPH](siggraph.md) showing the bitmap representation of SDF shapes that they integrated into their [Source](source_engine.md) engine.

@ -2,8 +2,6 @@
Sine, abbreviated *sin*, is a [trigonometric](trigonometry.md) [function](function.md) that simply said models a smooth oscillation, it is one of the most important and basic functions in geometry, [mathematics](math.md) and [physics](physics.md), and of course in [programming](programming.md). Along with [cosine](cos.md), [tangent](tan.md) and [cotangent](cot.md) it belongs to a group of functions that can be defined by ratios of sides of a right triangle depending on one of the angles in it (hence *trigonometric* -- "triangle measuring"). If some measurement looks like sine function, we say it is *harmonic*. This is very common in nature and technology, e.g. a weight on a spring goes up and down by this function, [alternating current](ac.md) voltage has the sine shape (because it is generated by a circular motion) etc.
The function is most commonly defined using a right triangle as follows. Consider the following triangle:
```
@ -39,7 +37,7 @@ The graph of the sine function is following:
Some additional facts and properties regarding the sine functions are:
- The domain are all [real numbers](real_number.md), the [codomain](codomain.md) are real numbers in interval <-1,1> (including both bounds).
- It is an [odd function](odd_function.md) (-sin(x) = sin(-x)).
- It is an [odd function](odd_function.md) (*-sin(x) = sin(-x)*).
- It is periodic, with a period of 2 [pi](pi.md).
- Sine is just shifted [cosine](cos.md), i.e. *sin(x) = cos(x - 1/2 pi)*
- Its inverse function is [arcus sine](asin.md), abbreviated *asin*, also written as *sin^-1* -- this function tells you what argument you need to give to sin to get a specific result number. It's actually an inverse of only part of the sine function because the whole sine function can't be inverted, it isn't [bijective](bijection.md).
@ -74,6 +72,39 @@ Indeed, sine looks similar to a mere line near 0, but you can see it quickly div
When implementing your own `sin` function, consider what you expect from it.
If you want a small, fast and perhaps integer only `sin` function (the one we'd prefer in [LRS](lrs.md)) that doesn't need extreme accuracy, consider using a **[look up table](lut.md)**. You simply precompute the values of the sine function into a static table in memory and the function just retrieves them when called -- this is super fast. Note that you can save a lot of space by **only storing sine values between 0 and 1/2 pi**, the remaining parts of the function are just different transformation of this part. You can further save space and/or make the function work with [floats](float.md) by further [interpolating](interpolation.md) (e.g. just linearly) between the stored values, for example if `sin(3.45)` is called and you only have values stored for `sin(3.4)` and `sin(3.5)`, you simply average them.
If you want a small, fast and perhaps integer only `sin` function (the one we'd prefer in [LRS](lrs.md)) that doesn't need extreme accuracy, consider using a **[look up table](lut.md)**. You simply precompute the values of the sine function into a static table in memory and the function just retrieves them when called -- this is super fast. Note that you can save a lot of space by **only storing sine values between 0 and 1/2 pi**, the remaining parts of the function are just different transformations of this part. You can further save space and/or make the function work with [floats](float.md) by further [interpolating](interpolation.md) (even just linearly) between the stored values, for example if `sin(3.45)` is called and you only have values stored for `sin(3.4)` and `sin(3.5)`, you simply average them.
If you don't need extreme speed there exist nice sine [approximation](approximation.md), e.g. the extremely accurate **Bhaskara I's approximation** (angle in radians): *sin(x) ~= (16 * x * (pi - x)) / (5 * pi^2 - 4 * x * (pi - x))*. (This formula is actually more elegant for cosine, so it may be even better to consider using that.) Here is a [C](c.md) [fixed point](fixed_point.md) implementation:
```
#define UNIT 1024
#define PI ((int) (UNIT * 3.14159265))
/* Integer sine using Bhaskara's approx. Returns a number
in <-UNIT, UNIT> interval. Argument is in radians * UNIT. */
int sinInt(int x)
{
int sign = 1;
if (x < 0) // odd function
{
x *= -1;
sign = -1;
}
x %= 2 * PI;
if (x > PI)
{
x -= PI;
sign *= -1;
}
int tmp = PI - x;
return sign * (16 * x * tmp) / ((5 * PI * PI - 4 * x * tmp) / UNIT);
}
```
Another approach is to use [Taylor series](taylor_series.md) to approximate sine with a [polynomial](polynomial.md) to whatever precision we need (this is used in calculators etc.).
Another approach is to use [Taylor series](taylor_series.md) to approximate sine with a [polynomial](polynomial.md) to whatever precision we need (this is used e.g. in calculators etc.).

@ -1,3 +1,5 @@
# Soyence
Soyence is a mainstream propaganda and [business](business.md) claiming itself to be [science](science.md). It's what typical reddit atheists believe is science. It's what Neil De Grass Tyson tells you is science.
Soyence is a mainstream propaganda and [business](business.md) claiming itself to be [science](science.md). It is what the typical reddit [atheist](atheism.md) believes is science or what Neil De Grass Tyson tells you is science. Soyence calls itself science and [gatekeeps](gatekeeping.md) itself by calling unpopular science -- such as that regarding human [race](race.md) or questioning big pharma [vaccines](vaccine.md) -- [pseudoscience](pseudoscience.md).
Soyence relies on low [IQ](iq.md) and shallow education of its followers while making them believe they are smart, it produces propaganda such as "documentaries" with Morgan Freeman, series like The Big Bang Theory and [YouTube](youtube.md) videos with titles like "Debunking Flat Earth with FACTS AND LOGIC", so there's a huge mass of [NPCs](npc.md) thinking they are Einsteins who blindly support this cult. Soyence tries to ridicule and punish thinking outside the box and asking specific questions, i.e. it is not dissimilar to a mass [religion](religion.md).

@ -18,6 +18,8 @@ Note that SW rendering doesn't mean our program is never touching [GPU](gpu.md)
Some SW renderers make use of specialized CPU instructions such as [MMX](mmx.md) which can make SW rendering faster thanks to handling multiple data in a single step. This is kind of a mid way: it is not using a GPU per se but only a mild form of hardware acceleration. The speed won't reach that of a GPU but will outperform a "pure" SW renderer. However the disadvantage of a hardware dependency is still present: the CPU has to support the MMX instruction set. Good renderers only use these instructions optionally and fall back to general implementation in case MMX is not supported.
**Programming your own 3D software rasterizer** (in case [small3dlib](small3dlib.md) is somehow not enough for you): difficulty of this task depends on features you want -- a super simple [flat shaded](flat_shading.md) (no textures, no smooth shading) renderer is relatively easy to make, especially if you don't need movable camera, can afford to use [floating point](float.md) etc. The core of these renderers is the **[triangle](triangle.md) [rasterization](rasterization.md)** algorithm which, if you want, can be very simple -- even a naive one will give workable results -- or pretty complex and advanced, using various optimizations and things such as the [top-left rule](top_left_rule.md) to guarantee no holes and overlaps of triangles. Remember this function will likely be the performance [bottleneck](bottleneck.md) of your renderer so you want to put effort into [optimizing](optimization.md) it to achieve good [FPS](fps.md). Once you have triangle rasterization, you can draw 3D models which consist of vertices (points in 3D space) and triangles between these vertices (it's very simple to load simple 3D models e.g. from the [obj](obj.md) format) -- you simply project (using [perspective](perspective.md)) 3D position of each vertex to screen coordinates and draw triangles between these pixels with the rasterization algorithm. Here you need to also solve [visibility](visibility.md), i.e. possible overlap of triangles on the screen and correctly drawing those nearer the view in front of those that are further away -- a very simple solution is a [z buffer](z_buffer.md), but to save memory you can also e.g. [sort](sorting.md) the triangles by distance and draw them back-to-front ([painter's algorithm](painters_algorithm.md)). You may add a [scene](scene.md) data structure that can hold multiple models to be rendered. If you additionally want to have movable camera and models that can be transformed (moved, rotated, scaled, ...), you will additionally need to look into some [linear algebra](linear_algebra.md) and [transform matrices](transform_matrix.md) that allow to efficiently compute positions of vertices of a transformed model against a transformed camera -- you do this the same way as basically all other 3D engines (look up e.g. some [OpenGL](opengl.md) tutorials). If you also want texturing, the matter gets again a bit more complicated, you need to compute [barycentric](barycentric.md) coordinates (special coordinates within a triangle) as you're rasterizing the triangle, and possibly apply [perspective correction](perspective_correction.md) (otherwise you'll be seeing distortions). You then map the barycentrics of each rasterized pixel to [UV](uv.md) (texturing) coordinates which you use to retrieve specific pixels from a texture. On top of all this you may start adding all the advanced features of typical engines such as [acceleration structures](acceleration_structure.md) that for example discard models that are completely out of view, [LOD](lod.mf), instancing, [MIP maps](mip_map.md) and so on.
## Specific Renderers
These are some notable software renderers:

@ -11,7 +11,26 @@ In 1978 [Douglas McIlroy](mcilroy.md) has written a short overview of the Unix s
This has later been condensed into: do one thing well, write programs to work together, make programs communicate via text streams, a universal interface.
{ I have come up with a possible interpretation of Unix philosophy: in short it says there's an upper but also lower limit on complexity. "Do one thing" means the program shouldn't be too complex, we can simplify this to e.g. "Your program shouldn't surpass 10 KLOC". "Do it well" means the programs shouldn't bee too trivial because then it is hardly doing it well, we could e.g. say "Your program shouldn't be shorter than 10 LOC". E.g. we shouldn't literally make a separate program for printing each ASCII symbol, such programs would be too simple and not doing a thing well. We rather make a [cat](cat.md) program, that's neither too complex nor too trivial, which can print any ASCII symbol. ~drummyfish }
**Example**: maybe the most common practical example that can be given is [piping](pipe.md) small [command line](cli.md) utility programs; in Unix there exist a number of small programs that do *only one thing but do it well*, for example the [`cat`](cat.md) program that only displays the content of a file, the [`grep`](grep.md) program that searches for patterns in text etc. In a command line we may use so called [pipes](pipe.md) to chain some of these simple programs into more complex processing pipelines. Let's say we want to for example automatically list all first and second level headings on given webpage and write them out alphabetically sorted. We can do it with a command such as this one:
```
curl "https://www.tastyfish.cz/lrs/main.html" | grep "<h[12]>.*</h[12]>" | sed "s/[^>]*> *\([^<]*\) *<.*/\1/g" | sort
```
Which may output for example:
```
Are You A Noob?
Some Interesting Topics
Welcome To The Less Retarded Wiki
What Is Less Retarded Software
```
In the command the pipes (`|`) chain multiple programs together so that the output of one becomes the input of the next. The first command, [`curl`](curl.md), downloads the [HTML](html.md) content of the webpage and passes it to the second command, [`grep`](grep.md), which filters the text and only prints lines with headings, this is passed to [`sed`](sed.md) that removes the HTML code and the result is passed to `sort` that sorts the lines alphabetically -- as this is the last command, the result is then printed. This is fast, powerful and very flexible way of processing data for anyone who knows the Unix tools. Notice the relative simplicity of each command and how each works with text -- the universal communication interface.
Compare this to the opposite [Window philosophy](windows_philosophy.md) in which combining programs into collaborating units is not intended or even purposefully prevented, and therefore very difficult, slow and impractical to do -- such programs are designed for manually performing some predefined actions, e.g. painting pictures with a mouse, but aren't made to collaborate or be automatized, they can rarely be used in unintended, inventive ways needed for [hacking](hacking.md).
{ One possible practical interpretation of Unix philosophy I came up with is this: there's an upper but also lower limit on complexity. "Do one thing" means the program shouldn't be too complex, we can simplify this to e.g. "Your program shouldn't surpass 10 KLOC". "Do it well" means the programs shouldn't bee too trivial because then it is hardly doing it well, we could e.g. say "Your program shouldn't be shorter than 10 LOC". E.g. we shouldn't literally make a separate program for printing each ASCII symbol, such programs would be too simple and not doing a thing well. We rather make a [cat](cat.md) program, that's neither too complex nor too trivial, which can really print any ASCII symbol. By this point of view Unix philosophy is really about balance of triviality and huge complexity, but hints that the right balance tends to be much closer to the triviality than we humans are tempted to intuitively choose. Without guidance we tend to make programs too complex and so the philosophy exists to remind us to force ourselves to rather minimize our programs to strike the correct balance. ~drummyfish }
## See Also

@ -10,7 +10,7 @@ Usenet was originally [ASCII](ascii.md) only, but people started to post binary
It worked like this: there were a number of Usenet servers that all collaborated on keeping a database of *articles* that users posted (very roughly this is similar to how [blockchain](blockchain.md) works nowadays); the servers would more or less mirror each other's content. These servers were called *providers* as they also allowed access to Usenet but this was usually for a fee. The system uses a [NNTP](nntp.md) (Network News Transfer Protocol) protocol. The articles users posted were also called *posts* or *news*, they were in plain text and were similar to email messages. Other users could reply to posts, creating a discussion thread. Every post was also categorized under certain **newsgroup** that formed a hierarchy (e.g. *comp.lang.java*). After so called *Big Renaming* in 1987 the system eventually settled on 8 top level hierarchies (called the *Big 8*): comp.* (computers), news.* (news), sci.* (science), rec.* (recreation), soc.* (social), talk.* (talk), misc.* (other) and humanities.* (humanities). There was also another one called alt.* for controversial topics. According to [Jargon File](jargon_file.md), by 1996 there was over 10000 different newsgroups.
Usenet was the pre-[web](www.md) web, kind of like an 80s [reddit](reddit.md) which contained huge amounts of historical information and countless discussions of true computer [nerds](nerd.md) which are however not easily accessible anymore as there aren't so many archives, they aren't well indexed and Usenet access is normally paid. It's a shame. It is possible to find e.g. initial reactions to the [AIDS](aids.md) disease, people asking what the [Internet](internet.md) was, people discussing future technologies, the German cannibal (Meiwes) looking for someone to eat (which he eventually did), [Bezos](bezos.md) looking for [Amazon](amazon.md) programmers, a heated debate between [Linus Torvalds](torvalds.md) and [Andrew Tanenbaum](tanenbaum.md) about the best OS architecture (the "Linux is obsolete" discussion) or [Douglas Adams](douglas_adams.md) talking to his fans. There are also some politically incorrect groups like *alt.niggers* [lol](lol.md).
Usenet was the pre-[web](www.md) web, kind of like an 80s [reddit](reddit.md) which contained huge amounts of historical information and countless discussions of true computer [nerds](nerd.md) which are however not easily accessible anymore as there aren't so many archives, they aren't well indexed and direct Usenet access is normally paid. It's a shame. It is possible to find e.g. initial reactions to the [AIDS](aids.md) disease, people asking what the [Internet](internet.md) was, people discussing future technologies, the German cannibal (Meiwes) looking for someone to eat (which he eventually did), [Bezos](bezos.md) looking for [Amazon](amazon.md) programmers, a heated debate between [Linus Torvalds](torvalds.md) and [Andrew Tanenbaum](tanenbaum.md) about the best OS architecture (the "Linux is obsolete" discussion) or [Douglas Adams](douglas_adams.md) talking to his fans. There were [memes](meme.md) and characters like [BIFF](biff.md), a kind of hilarious noob wannabe cool personality. Some users became kind of famous, e.g. Scott Abraham who was banned from Usenet by court after an extremely long flame war, Alexander Abian, a mathematician who argued for blowing up the Moon (which according to his theory would solve all Earth's issues), Archimedes Plutonium who suggested the Universe was really a big plutonium atom (he later literally changed his name to Plutonium lol) or John Titor (pretend time traveler). There are also some politically incorrect groups like *alt.niggers* [lol](lol.md).
{ I mean I don't remember it either, I'm not that old, I've just been digging on the Internet and in the archives, and I find it all fascinating. ~drummyfish }

@ -4,9 +4,7 @@ This page serves to establish usage rights for the whole LRS wiki. It is here to
Everything on this wiki has been created from scratch solely by people listed in [wiki authors](wiki_authors.md). Great care has been taken to make sure no copyrighted content created by other people has been included in any way. This is because one of the goals of this wiki is to be completely in the public domain world wide.
Each contributor has agreed to release the whole LRS Wiki under the Creative Commons Zero 1.0 (CC0 1.O) waiver, available at https://creativecommons.org/publicdomain/zero/1.0/.
You may also freely decide to use this wiki under the following waiver:
Each contributor has agreed to release the whole LRS Wiki under the Creative Commons Zero 1.0 (CC0 1.O) waiver, available at https://creativecommons.org/publicdomain/zero/1.0/, with an additional option for you to also freely choose the following waiver instead:
The intent of this waiver is to ensure that this work will never be encumbered by any exclusive intellectual property rights and will always be in the public domain world-wide, i.e. not putting any restrictions on its use.

@ -1,4 +1,4 @@
## Wikipedia
# Wikipedia
Wikipedia is a non-commercial, [free/open](free_culture.md) [online](www.md) encyclopedia written mostly by volunteers, running on [free software](free_software.md), allowing almost anyone to edit its content (i.e. being a [wiki](wiki.md)); it is the largest and perhaps most famous encyclopedia created to date. It is licensed under [CC-BY-SA](cc_by_sa.md) and is run by the nonprofit organization Wikimedia Foundation. It is accessible at https://wikipedia.org.
@ -6,11 +6,11 @@ Wikipedia exists in many (more than 200) versions differing mostly by the langua
There are also many sister projects of Wikipedia such as [Wikimedia Commons](wm_commons.md) that gathers [free as in freedom](free_culture.md) media for use on Wikipedia, [WikiData](wikidata.md), Wikinews or Wikisources.
Information about hardware and software used by Wikimedia Foundation can be found at https://meta.wikimedia.org/wiki/Wikimedia_servers. As of 2022 Wikipedia runs of the traditional [LAMP](lamp.md) framework and its website doesn't require [JavaScript](javascript.md). [Debian](debian.md) [GNU](gnu.md)/[Linux](linux.md) is used on web servers (switched from [Ubunatu](ubuntu.md) in 2019). The foundation uses its own [wiki](wiki.md) engine called [MediaWiki](mediawiki.md) that's written mainly in [PHP](php.md). Database used is [MariaDB](mariadb.md). The servers run on server clusters in 6 different data centers around the world which are rented: 3 in the [US](usa.md), 3 in [Europe](europe.md) and 1 in [Asia](asia.md).
Information about hardware and software used by Wikimedia Foundation can be found at https://meta.wikimedia.org/wiki/Wikimedia_servers. As of 2022 Wikipedia runs of the traditional [LAMP](lamp.md) framework and its website doesn't require [JavaScript](javascript.md) (amazing!). [Debian](debian.md) [GNU](gnu.md)/[Linux](linux.md) is used on web servers (switched from [Ubunatu](ubuntu.md) in 2019). The foundation uses its own [wiki](wiki.md) engine called [MediaWiki](mediawiki.md) that's written mainly in [PHP](php.md). Database used is [MariaDB](mariadb.md). The servers run on server clusters in 6 different data centers around the world which are rented: 3 in the [US](usa.md), 3 in [Europe](europe.md) and 1 in [Asia](asia.md).
Wikipedia was created by [Jimmy Wales](jimmy_wales.md) and [Larry Sanger](larry_sanger.md) and was launched on 15 January 2001. It was made as a complementary project alongside [Nupedia](nupedia.md), an earlier encyclopedia by Wales and Sanger to which only verified experts could contribute. Wikipedia of course has shown to be a much more successful project.
There exist [forks](fork.md) and alternatives to Wikipedia. Simple English Wikipedia can offer a simpler alternative to sometimes overly complicated articles on the main English Wikipedia. [Citizendium](citizendium.md) is a similar, free online encyclopedia co-founded by [Larry Sanger](larry_sanger.md), a co-founder of Wikipedia itself. Citizendium's goal is to improve on some weak point of Wikipedia such as its reliability or quality of writing. [Metapedia](metapedia.md) is a Wikipedia fork that's written from a [rightist](left_right.md) point of view. Encyclopedia Britannica can also be used as a nice resource: its older versions are already [public domain](public_domain.md) and can be found e.g. at [Project Gutenberg](gutenberg.md), and there is also a modern online version of Britannica which is [proprietary](proprietary.md) but has pretty good articles even on modern topics (of course facts are always in the public domain). Practically for any specialized topic it is nowadays possible to find its own wiki on the Internet.
There exist [forks](fork.md) and alternatives to Wikipedia. Simple English Wikipedia can offer a simpler alternative to sometimes overly complicated articles on the main English Wikipedia. [Citizendium](citizendium.md) is a similar, free online encyclopedia co-founded by [Larry Sanger](larry_sanger.md), a co-founder of Wikipedia itself. Citizendium's goal is to improve on some weak point of Wikipedia such as its reliability or quality of writing. [Metapedia](metapedia.md) is a Wikipedia fork that's written from a [rightist](left_right.md) point of view. Encyclopedia Britannica can also be used as a nice resource: its older versions are already [public domain](public_domain.md) and can be found e.g. at [Project Gutenberg](gutenberg.md), and there is also a modern online version of Britannica which is [proprietary](proprietary.md) (and littered with ads) but has pretty good articles even on modern topics (of course facts you find there are in the public domain). Practically for any specialized topic it is nowadays possible to find its own wiki on the Internet.
## Good And Bad Things About Wikipedia

@ -1,6 +1,6 @@
# WikiWikiWeb
WikiWikiWeb (also *c2 Wiki* or just *Wiki*) was the first ever created [wiki](wiki.md) (user editable) website, created in 1995 in [Perl](perl.md) by [Ward Cunningham](cunningham.md). It was focused on [software engineering](sw_engineering.md) and computer technology in general but included a lot of discussion and pages touching on other topics, e.g. those of politics, humor or nerd and [hacker](hacking.md) culture. The principles on which this site worked, i.e. allowing users to edit its pages, greatly influenced a lot of pages that came after that are now generally called [wikis](wiki.md), of which most famous is [Wikipedia](wikipedia.md). The style of WikiWikiWeb was partly an inspiration for our [LRS wiki](lrs_wiki.md).
WikiWikiWeb (also *c2 Wiki* or just *Wiki*) was the first ever created [wiki](wiki.md) (user editable) website, created in 1995 in [Perl](perl.md) by [Ward Cunningham](cunningham.md). It was focused on [software engineering](sw_engineering.md) and computer technology in general but included a lot of discussion and pages touching on other topics, e.g. those of politics, humor or nerd and [hacker](hacking.md) culture. The principles on which this site worked, i.e. allowing users to edit its pages, greatly influenced a lot of sites that came after that are now generally called [wikis](wiki.md), of which most famous is [Wikipedia](wikipedia.md). The style of WikiWikiWeb was partly an inspiration for our [LRS wiki](lrs_wiki.md).
It had over 36000 pages (http://c2.com/cgi/wikiPages). Since 2014 the wiki can no longer be edited due to vandalism, but it's still online. It was originally available at http://www.c2.com/cgi/wiki, now at http://wiki.c2.com/ (sadly now requires [JavaScript](js.md), WTF how is this a hacker site???).

@ -20,7 +20,7 @@ Some properties of and facts about this number follow:
- As it is one of the most commonly used numbers in programming, computers sometimes deal with it in special ways, for example in [assembly](assembly.md) languages there are often special instructions for comparing to 0 (e.g. `NEZ`, not equals zero) which can save memory and also be faster. So as a programmer you may optimize your program by trying to use zeros if possible.
- In [C](c.md) 0 represents the [false](false.md) value, a function returning 0 many times signifies an [error](error.md) during the execution of that function. However 0 also sometimes means success, e.g. as a return value from the main function.
**Dividing by zero is not defined**, it is a forbidden operation for a number of reasons, e.g. because it breaks equations (allowing dividing by zero would also allow us to make basically any equation hold, even those that normally don't). In programming dividing by zero typically causes an error, crash of a program or an [exception](exception.md). When operating with [limits](limit.md) however, we can handle divisions by zero in a special way (find out what value an [expression](expression.md) approaches if we get infinitely close to dividing by 0).
**Dividing by zero is not defined**, it is a forbidden operation mainly because it breaks equations (allowing dividing by zero would also allow us to make basically any equation hold, even those that normally don't). In programming dividing by zero typically causes an error, crash of a program or an [exception](exception.md). When operating with [limits](limit.md) however, we can handle divisions by zero in a special way (find out what value an [expression](expression.md) approaches if we get infinitely close to dividing by 0).
## See Also

Loading…
Cancel
Save