Oscillo is a C++ terminal application designed to render mathematical functions with higher quality than traditional ASCII drawings. By utilising Unicode Braille patterns, the project achieves a 2x4 sub-pixel resolution within a single character cell, allowing for smooth curves and detailed mathematical visualisation directly in the terminal.
- Custom Math Engine: Features a custom Lexer and Recursive Descent Parser that tokenises mathematical strings and transforms them into an Abstract Syntax Tree (AST). This allows for recursive evaluation of different values of x, used to plot each point of the function.
- High-Resolution Braille Rendering: Instead of plotting one point per character, this project maps mathematical coordinates to a virtual bit-grid. Every 8 bits are then encoded into a specific Unicode Braille character where every character cell acts as a 2x4 pixel display. This effectively quadruples the vertical resolution and doubles the horizontal resolution of the terminal.
- Bresenham's Line Algorithm: To ensure a continuous curve without gaps, the plotter implements a customised Bresenham algorithm.
| Category | Syntax | Examples |
|---|---|---|
| Arithmetic | +, -, *, / |
x + 5, x / 2, (x + 1) * (x - 1) |
| Trigonometry | sin(), cos(), tan() |
sin(x), cos(x / 2), tan(x) |
| Logarithms | log(), exp() |
log(x), exp(x) |
| Power | base^(exp) |
x^(2), 2^(x+1), (x+1)^(0.5) |
| Root/Misc | sqrt(), abs() |
sqrt(x + 10), abs(x) |
| Implicit Mult. | n(x) or (a)(b) |
2x, 5sin(x), (x+1)(x-2) |
Important
Power Operator Requirement: The exponent for the ^ operator must always be enclosed in parentheses. For example, use x^(2) instead of x^2.
Oscillo transforms a simple string of text into a terminal plot through the following pipeline:
The Lexer scans the raw input string and breaks it into a stream of meaningful tokens. It identifies literals, variables, operators, and function names (e.g sin, log, sqrt, etc), while also handling mathematical rules like implicit multiplication.
- Input:
"2x + sin(x)" - Output:
[LITERAL: 2], [VARIABLE: x], [OPERATOR: +], [FUNCTION: sin], [SEPARATOR: (], [VARIABLE: x], [SEPARATOR: )]
The Parser consumes the token stream following mathematical precedence (BIDMAS). It constructs an Abstract Syntax Tree (AST), a hierarchical representation of the formula. This structure allows the engine to evaluate nested expressions by recursively traversing the tree.
The Evaluator determines the terminal's dimensions and iterates through the horizontal range (
- It resolves the AST for the specific
$x$ value to calculate$y$ . - It maps these mathematical coordinates (
$x, y$ ) to the plotter's local pixel grid. - It utilises Bresenham's Line Algorithm to connect these points, ensuring a continuous curve.
Instead of standard ASCII characters, Oscillo uses Unicode Braille patterns (U+2800 - U+28FF) to achieve more detail.
- Sub-pixel Resolution: Each terminal character cell is treated as a 2x4 bit-grid.
- Bit Manipulation: When a point is plotted, the corresponding bit in that cell's grid is toggled via a bitwise OR operation.
- The Final Character: The 8-bit grid is converted into a hex offset added to the base Braille character code. This quadruples the vertical resolution and doubles the horizontal resolution compared to traditional ASCII plotting.
You will need a C++ compiler supporting C++20 and the ncurses library installed on your system.
- Ubuntu/Debian:
sudo apt-get install libncurses5-dev libncursesw5-dev
Oscillo uses a standard CMake build pipeline:
git clone https://github.com/Krissal1234/oscillo.git
cd oscillomkdir build && cd buildcmake ..
makeRun these commands to see the Braille rendering in action:
- Wave Interference:
./oscillo "sin(x) + cos(2x)" - Discontinuities:
./oscillo "tan(x)"


