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