Initial Commit
This commit is contained in:
commit
1098b3b3f0
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
|
||||||
|
class Equation:
|
||||||
|
|
||||||
|
def __init__(self, xf, yf, cf=(255,255,255), wf=1):
|
||||||
|
self.xf = xf
|
||||||
|
self.yf = yf
|
||||||
|
self.cf = cf
|
||||||
|
self.wf = wf
|
||||||
|
|
||||||
|
def _xf(self, t):
|
||||||
|
if callable(self.xf):
|
||||||
|
return self.xf(t)
|
||||||
|
else:
|
||||||
|
return t
|
||||||
|
|
||||||
|
def _yf(self, t):
|
||||||
|
if callable(self.yf):
|
||||||
|
return self.yf(t)
|
||||||
|
else:
|
||||||
|
return t
|
||||||
|
|
||||||
|
def _cf(self, t, r):
|
||||||
|
if callable(self.cf):
|
||||||
|
return self.cf(t, r)
|
||||||
|
else:
|
||||||
|
return self.cf
|
||||||
|
|
||||||
|
def _wf(self, t, r):
|
||||||
|
if callable(self.wf):
|
||||||
|
return self.wf(t, r)
|
||||||
|
else:
|
||||||
|
return self.wf
|
||||||
|
|
||||||
|
def plot(self, r=(0, 12, 0.1), scale=(1,1)):
|
||||||
|
t = r[0]
|
||||||
|
prev_x = self._xf(t)
|
||||||
|
prev_y = self._yf(t)
|
||||||
|
while t <= r[1]:
|
||||||
|
x = self._xf(t)
|
||||||
|
y = self._yf(t)
|
||||||
|
c = self._cf(t, r)
|
||||||
|
w = self._wf(t, r)
|
||||||
|
yield (
|
||||||
|
int(prev_x * scale[0]),
|
||||||
|
int(prev_y * scale[1]),
|
||||||
|
int(x * scale[0]),
|
||||||
|
int(y * scale[1]),
|
||||||
|
c,
|
||||||
|
w,
|
||||||
|
)
|
||||||
|
prev_x, prev_y = x, y
|
||||||
|
t += r[2]
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Kyler Olsen
|
||||||
|
# Apr 2024
|
||||||
|
# Hypotrochoid Example
|
||||||
|
|
||||||
|
SCREEN {
|
||||||
|
Width Scale: 100,
|
||||||
|
Height Scale: 100,
|
||||||
|
|
||||||
|
FPS: 60,
|
||||||
|
}
|
||||||
|
|
||||||
|
R = 7;
|
||||||
|
r = 4;
|
||||||
|
d = 1;
|
||||||
|
|
||||||
|
ANIM offset {R:0 <= x <= 8*pi,S:π/128}
|
||||||
|
|
||||||
|
GRAPH {
|
||||||
|
X: (R - r) * cos(t) + d * cos(((R - r) / r) * t),
|
||||||
|
Y: (R - r) * sin(t) - d * sin(((R - r) / r) * t),
|
||||||
|
T: ANIM {R:0+offset <= x <= 8*pi+offset,S:π/32},
|
||||||
|
C_w: ((t - r[0]) / (r[1] - r[0]))
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
import pygame
|
||||||
|
import sys
|
||||||
|
import math
|
||||||
|
from equation import Equation
|
||||||
|
|
||||||
|
# Initialize Pygame
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
# Screen dimensions
|
||||||
|
|
||||||
|
# Screen setup
|
||||||
|
# screen = pygame.display.set_mode((800, 600))
|
||||||
|
screen = pygame.display.set_mode()
|
||||||
|
pygame.display.set_caption("Equation Plotter")
|
||||||
|
|
||||||
|
class Hypotrochoid(Equation):
|
||||||
|
|
||||||
|
def __init__(self, R, r, d, c=(255,255,255)):
|
||||||
|
self.R = R
|
||||||
|
self.r = r
|
||||||
|
self.d = d
|
||||||
|
super().__init__(self._h_xf, self._h_yf, self._h_cf, 5)
|
||||||
|
|
||||||
|
def _h_xf(self, t):
|
||||||
|
return (self.R - self.r) * math.cos(t) + self.d * math.cos(((self.R - self.r) / self.r) * t)
|
||||||
|
|
||||||
|
def _h_yf(self, t):
|
||||||
|
return (self.R - self.r) * math.sin(t) - self.d * math.sin(((self.R - self.r) / self.r) * t)
|
||||||
|
|
||||||
|
def _h_cf(self, t, r):
|
||||||
|
c = int(((t - r[0]) / (r[1] - r[0])) * 255)
|
||||||
|
return c, c, c
|
||||||
|
|
||||||
|
# def _h_wf(self, t, r):
|
||||||
|
# return int(((t - r[0]) / (r[1] - r[0])) * 5)
|
||||||
|
|
||||||
|
def main(equ):
|
||||||
|
SCREEN_WIDTH = screen.get_width()
|
||||||
|
SCREEN_HEIGHT = screen.get_height()
|
||||||
|
HALF_WIDTH = SCREEN_WIDTH // 2
|
||||||
|
HALF_HEIGHT = SCREEN_HEIGHT // 2
|
||||||
|
# Main loop
|
||||||
|
off = 0
|
||||||
|
mouse_x_last, mouse_y_last = pygame.mouse.get_pos()
|
||||||
|
running = True
|
||||||
|
while running:
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
running = False
|
||||||
|
|
||||||
|
# Clear the screen
|
||||||
|
screen.fill((0,0,0))
|
||||||
|
|
||||||
|
for prev_x, prev_y, x, y, c, w in equ.plot((0 + off, (8 * math.pi) + off, math.pi/32), (100, 100)):
|
||||||
|
pygame.draw.line(screen, c, (prev_x + HALF_WIDTH, HALF_HEIGHT - prev_y), (x + HALF_WIDTH, HALF_HEIGHT - y), w)
|
||||||
|
|
||||||
|
pygame.display.flip()
|
||||||
|
pygame.time.Clock().tick(60)
|
||||||
|
off += math.pi/128
|
||||||
|
|
||||||
|
# if direction:
|
||||||
|
# equ.R += 0.1
|
||||||
|
# equ.r += 0.05
|
||||||
|
# if equ.R >= 20:
|
||||||
|
# direction = False
|
||||||
|
# else:
|
||||||
|
# equ.R -= 0.1
|
||||||
|
# equ.r -= 0.05
|
||||||
|
# if equ.R <= 6:
|
||||||
|
# direction = True
|
||||||
|
|
||||||
|
mouse_x, mouse_y = pygame.mouse.get_pos()
|
||||||
|
if 5 < math.sqrt(pow(mouse_x_last - mouse_x, 2) + pow(mouse_y_last - mouse_y, 2)):
|
||||||
|
running = False
|
||||||
|
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
# main(Equation(None, lambda t: math.sin(t)))
|
||||||
|
# main(Hypotrochoid(6, 4, 1))
|
||||||
|
main(Hypotrochoid(7, 4, 1))
|
||||||
|
# main(Hypotrochoid(15, 14, 1))
|
|
@ -0,0 +1,362 @@
|
||||||
|
# YTD Graphing Language
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Lexical Definition
|
||||||
|
|
||||||
|
### Comments
|
||||||
|
|
||||||
|
Comments can either be single-line comments or multi-line comments.
|
||||||
|
|
||||||
|
Single-line comments start with `#` and end at the end of a line.
|
||||||
|
|
||||||
|
### Identifiers
|
||||||
|
|
||||||
|
Can be up to 31 characters in length, and are case sensitive.
|
||||||
|
They cannot be a keyword.
|
||||||
|
|
||||||
|
```
|
||||||
|
Identifier ::= ID_Start*
|
||||||
|
ID_Start ::= <Any latin alphabet ligature: "A"-"Z", "a"-"z">
|
||||||
|
```
|
||||||
|
|
||||||
|
### Keywords
|
||||||
|
|
||||||
|
Keywords are not case sensitive.
|
||||||
|
|
||||||
|
```
|
||||||
|
screen graph anim img
|
||||||
|
sum pi alpha beta
|
||||||
|
theta inf product integral
|
||||||
|
```
|
||||||
|
|
||||||
|
### Literals
|
||||||
|
|
||||||
|
```
|
||||||
|
number ::= decinteger | pointfloat | exponentfloat
|
||||||
|
decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")*
|
||||||
|
nonzerodigit ::= "1"..."9"
|
||||||
|
digit ::= "0"..."9"
|
||||||
|
pointfloat ::= ([digitpart] fraction) | (digitpart ".")
|
||||||
|
exponentfloat ::= (digitpart | pointfloat) exponent
|
||||||
|
digitpart ::= digit (["_"] digit)*
|
||||||
|
fraction ::= "." digitpart
|
||||||
|
exponent ::= ("e" | "E") ["+" | "-"] digitpart
|
||||||
|
```
|
||||||
|
|
||||||
|
### Punctuation
|
||||||
|
|
||||||
|
```
|
||||||
|
+ - * / % ^
|
||||||
|
= ! < <= > >=
|
||||||
|
{ } [ ] ( )
|
||||||
|
_ -> , ; : ∑
|
||||||
|
∏ ∞ ≠ ≤ ≥ ∫
|
||||||
|
α β π → θ
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Punctuation Conversions
|
||||||
|
|
||||||
|
| Original | New |
|
||||||
|
| -- | -- |
|
||||||
|
| <= | ≤ |
|
||||||
|
| >= | ≥ |
|
||||||
|
| -> | → |
|
||||||
|
|
||||||
|
#### Keyword Conversions
|
||||||
|
|
||||||
|
| Original | New |
|
||||||
|
| -- | -- |
|
||||||
|
| sum | ∑ |
|
||||||
|
| pi | π |
|
||||||
|
| alpha | α |
|
||||||
|
| beta | β |
|
||||||
|
| inf | ∞ |
|
||||||
|
| product | ∏ |
|
||||||
|
| integral | ∫ |
|
||||||
|
| theta | θ |
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
The syntactical structure starts with a `file` at the root.
|
||||||
|
|
||||||
|
### File
|
||||||
|
|
||||||
|
A `file` can contain any number of the following elements:
|
||||||
|
- *Screen*
|
||||||
|
- *Graph*
|
||||||
|
- *Animation*
|
||||||
|
<!-- - *Image* -->
|
||||||
|
|
||||||
|
### Screen
|
||||||
|
|
||||||
|
A *screen* begins with the `screen` keyword. It then has a comma (`,`)
|
||||||
|
separated list enclosed in curly braces (`{` and `}`) of *screen parameters*.
|
||||||
|
At most only one screen block is allowed per `file`.
|
||||||
|
|
||||||
|
#### Screen parameter
|
||||||
|
|
||||||
|
A *screen parameter* begins with its parameter name then a colon (`:`) followed
|
||||||
|
by its value.
|
||||||
|
|
||||||
|
Listed bellow are the possible parameters.
|
||||||
|
|
||||||
|
**Top**
|
||||||
|
- Role:
|
||||||
|
Sets the Y-Coordinate of the top of the screen to the given value.
|
||||||
|
- Required:
|
||||||
|
False
|
||||||
|
- Default:
|
||||||
|
`Unset`
|
||||||
|
- Possible Values: Integers, `Unset`
|
||||||
|
|
||||||
|
**Bottom**
|
||||||
|
- Role:
|
||||||
|
Sets the Y-Coordinate of the bottom of the screen to the given value.
|
||||||
|
- Required:
|
||||||
|
False
|
||||||
|
- Default:
|
||||||
|
`Unset`
|
||||||
|
- Possible Values: Integers, `Unset`
|
||||||
|
|
||||||
|
**Right**
|
||||||
|
- Role:
|
||||||
|
Sets the X-Coordinate of the right of the screen to the given value.
|
||||||
|
- Required:
|
||||||
|
False
|
||||||
|
- Default:
|
||||||
|
`Unset`
|
||||||
|
- Possible Values: Integers, `Unset`
|
||||||
|
|
||||||
|
**Left**
|
||||||
|
- Role:
|
||||||
|
Sets the X-Coordinate of the left of the screen to the given value
|
||||||
|
- Required:
|
||||||
|
False
|
||||||
|
- Default:
|
||||||
|
`Unset`
|
||||||
|
- Possible Values: Integers, `Unset`
|
||||||
|
|
||||||
|
**Width**
|
||||||
|
- Role:
|
||||||
|
Sets the X-Coordinate range of the screen to the given value
|
||||||
|
- Required:
|
||||||
|
False
|
||||||
|
- Default:
|
||||||
|
`Unset`
|
||||||
|
- Possible Values: Natural Numbers, `Unset`
|
||||||
|
- Note:
|
||||||
|
Centered on zero if `right` and `left` are unset.
|
||||||
|
Has no affect if `right` and `left` are set.
|
||||||
|
|
||||||
|
**Height**
|
||||||
|
- Role:
|
||||||
|
Sets the Y-Coordinate range of the screen to the given value
|
||||||
|
- Required:
|
||||||
|
False
|
||||||
|
- Default:
|
||||||
|
`Unset`
|
||||||
|
- Possible Values: Natural Numbers, `Unset`
|
||||||
|
- Note:
|
||||||
|
Centered on zero if `top` and `bottom` are unset.
|
||||||
|
Has no affect if `top` and `bottom` are set.
|
||||||
|
|
||||||
|
**Width Scale**
|
||||||
|
- Role:
|
||||||
|
Sets the X-Coordinate range of the screen to the screen pixel
|
||||||
|
width divided by the given value
|
||||||
|
- Required:
|
||||||
|
False
|
||||||
|
- Default:
|
||||||
|
`20`
|
||||||
|
- Possible Values: Positive Real Numbers
|
||||||
|
- Note:
|
||||||
|
Centered on zero if `right` and `left` are unset.
|
||||||
|
Has no affect if `right` and `left` are set or if `width` are set.
|
||||||
|
|
||||||
|
**Height Scale**
|
||||||
|
- Role:
|
||||||
|
Sets the Y-Coordinate range of the screen to the screen pixel
|
||||||
|
height divided by the given value
|
||||||
|
- Required:
|
||||||
|
False
|
||||||
|
- Default:
|
||||||
|
`20`
|
||||||
|
- Possible Values: Positive Real Numbers
|
||||||
|
- Note:
|
||||||
|
Centered on zero if `top` and `bottom` are unset.
|
||||||
|
Has no affect if `top` and `bottom` are set or if `height` are set.
|
||||||
|
|
||||||
|
**FPS**
|
||||||
|
- Role:
|
||||||
|
Sets the refresh rate of the screen
|
||||||
|
- Required:
|
||||||
|
False
|
||||||
|
- Default:
|
||||||
|
`30`
|
||||||
|
- Possible Values: Natural Numbers
|
||||||
|
|
||||||
|
### Graph
|
||||||
|
|
||||||
|
A *graph* begins with the `graph` keyword. It then has a comma (`,`)
|
||||||
|
separated list enclosed in curly braces (`{` and `}`) of *graph parameters*.
|
||||||
|
A graph block defines a graph to be drawn.
|
||||||
|
|
||||||
|
#### Graph parameter
|
||||||
|
|
||||||
|
A *graph parameter* begins with its parameter name then a colon (`:`) followed
|
||||||
|
by an `expression`.
|
||||||
|
|
||||||
|
Listed bellow are the possible parameters and their possible roles.
|
||||||
|
Any ranges can be the `identifier` of an *animation* or an *inline animation*.
|
||||||
|
|
||||||
|
**X**
|
||||||
|
- The `x = f(y)` function for `y` independent cartesian equations.
|
||||||
|
- The `x = f(t)` function for parametric equations.
|
||||||
|
- The `x` range (animation) for `x` independent cartesian equations.
|
||||||
|
|
||||||
|
**Y**
|
||||||
|
- The `y = f(x)` function for `x` independent cartesian equations.
|
||||||
|
- The `y = f(t)` function for parametric equations.
|
||||||
|
- The `y` range (animation) for `y` independent cartesian equations.
|
||||||
|
|
||||||
|
**T**
|
||||||
|
- The `t` range (animation) for parametric equations.
|
||||||
|
|
||||||
|
**R**
|
||||||
|
- The `r = f(θ)` function for polar equations.
|
||||||
|
|
||||||
|
**θ**
|
||||||
|
- The `θ` range (animation) for polar equations.
|
||||||
|
|
||||||
|
*Color functions*
|
||||||
|
- The `c = f(x)` function for `x` independent cartesian equations.
|
||||||
|
- The `c = f(y)` function for `y` independent cartesian equations.
|
||||||
|
- The `c = f(t)` function for parametric equations.
|
||||||
|
- The `c = f(θ)` function for polar equations.
|
||||||
|
|
||||||
|
#### Color Functions
|
||||||
|
|
||||||
|
*Color function* parameter names are **C_x** where the *x* is color space part
|
||||||
|
subscript.
|
||||||
|
Only one color space can be used in each graph.
|
||||||
|
If only alpha is set the default color space is **Grey-scale**.
|
||||||
|
|
||||||
|
Listed bellow are the available color spaces and their subscripts.
|
||||||
|
Default value in parenthesis for the unused subscripts of the color spaces.
|
||||||
|
|
||||||
|
- **Grey-scale**: `wa` - Grey-scale (1), Alpha (1)
|
||||||
|
- **RGB**: `rgba` - Red (0), Green (0), Blue (0), Alpha (1)
|
||||||
|
- **HSL**: `hsla` - Hue (0), Saturation (1), Luminosity (0.5), Alpha (1)
|
||||||
|
|
||||||
|
All values can be a real number between 0 and 1 inclusive.
|
||||||
|
Values bellow this range will be interpreted as 0.
|
||||||
|
Values above this range will be interpreted as 1.
|
||||||
|
|
||||||
|
### Animation
|
||||||
|
|
||||||
|
An *animation* begins with the `anim` keyword. Unless it is an
|
||||||
|
*inline animation* block, the keyword is followed by its `identifier`. It then
|
||||||
|
has a comma (`,`) separated list enclosed in curly braces (`{` and `}`)
|
||||||
|
of *animation parameters*.
|
||||||
|
|
||||||
|
When an animation is used in an expression, the value it is evaluated as is in
|
||||||
|
the range defined, changing by the step every frame.
|
||||||
|
|
||||||
|
#### Animation parameter
|
||||||
|
|
||||||
|
An *animation parameter* begins with its parameter name then a colon (`:`)
|
||||||
|
followed by an `expression`. If it is the only parameter the parameter name for
|
||||||
|
the range is optional.
|
||||||
|
|
||||||
|
Listed bellow are the possible parameters. Only the *range* parameter is
|
||||||
|
required.
|
||||||
|
|
||||||
|
**R** Range: `R:` *expression* `≤ x ≤` *expression*
|
||||||
|
|
||||||
|
**S** Step: `S:` *expression*
|
||||||
|
- Default is `1/10` unless a range expression is multiplied by `π` then it
|
||||||
|
is `π/32`.
|
||||||
|
|
||||||
|
**D** Direction: `D:` *direction*
|
||||||
|
- `increase` (default)
|
||||||
|
- `decrease`
|
||||||
|
- `bounce`
|
||||||
|
|
||||||
|
### Expressions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### Unary Expression
|
||||||
|
|
||||||
|
A `unary expression` is made up of one `expression` and one `unary operator`.
|
||||||
|
The operator may come before or after the expression.
|
||||||
|
|
||||||
|
#### Binary Expression
|
||||||
|
|
||||||
|
A `binary expression` is made up of one `expression`, then one
|
||||||
|
`binary operator`, then another `expression`.
|
||||||
|
|
||||||
|
#### Function
|
||||||
|
|
||||||
|
A `function` starts with an `identifier` followed by a comma (`,`)
|
||||||
|
separated list enclosed in parentheses (`(` and `)`) of *function arguments*.
|
||||||
|
|
||||||
|
##### Function Argument
|
||||||
|
|
||||||
|
A *function argument* is an `expression`.
|
||||||
|
|
||||||
|
#### Enclosed Expression
|
||||||
|
|
||||||
|
An `enclosed expression` is simply an `expression` enclosed in parentheses
|
||||||
|
(`(` and `)`).
|
||||||
|
|
||||||
|
#### Operator
|
||||||
|
|
||||||
|
Here are all operators and their types and names in order of precedence.
|
||||||
|
|
||||||
|
| Operator | Type | Name |
|
||||||
|
| -- | -- | -- |
|
||||||
|
| `-` | Unary (Prefix) | Negate *Operator* |
|
||||||
|
| `!` | Unary (Postfix) | Factorial *Operator* |
|
||||||
|
| `^` | Binary | Exponential *Operator* |
|
||||||
|
| `_` | Binary | Subscript *Operator* |
|
||||||
|
| `/` | Binary | Division *Operator* |
|
||||||
|
| `%` | Binary | Modulus *Operator* |
|
||||||
|
| `*` | Binary | Multiplication *Operator* |
|
||||||
|
| `-` | Binary | Subtraction *Operator* |
|
||||||
|
| `+` | Binary | Addition *Operator* |
|
||||||
|
| `=` | Binary | Assignment *Operator* |
|
||||||
|
|
||||||
|
#### Literal
|
||||||
|
|
||||||
|
A `literal` is just simply the content of the literal.
|
||||||
|
|
||||||
|
#### Identifier
|
||||||
|
|
||||||
|
A `identifier` is just simply the name of the identifier.
|
||||||
|
|
||||||
|
#### Statement
|
||||||
|
|
||||||
|
A `statement` is made up of an `expression` followed by a semicolon (`;`).
|
||||||
|
|
||||||
|
## Semantics
|
||||||
|
|
||||||
|
### Screen Block
|
||||||
|
|
||||||
|
### Graph Block
|
||||||
|
|
||||||
|
<!-- ### Image Block
|
||||||
|
|
||||||
|
Defines a background image.
|
||||||
|
|
||||||
|
Additional image blocks will stack on top of the previous one in the order they
|
||||||
|
are in the file.
|
||||||
|
|
||||||
|
- **X**: The `x` range (animation) for the background.
|
||||||
|
- **Y**: The `y` range (animation) for the background.
|
||||||
|
- **R**: The `r` range (animation) for the background.
|
||||||
|
- **A or Theta**: The `theta` range (animation) for the background.
|
||||||
|
- **C_x**: The color function of the background. -->
|
||||||
|
|
||||||
|
### Animation Block
|
Loading…
Reference in New Issue