Skip to content

Commit

Permalink
Merge pull request #21 from qaqFei/main
Browse files Browse the repository at this point in the history
更新: 些许Python代码示例
  • Loading branch information
NuanRMxi authored Oct 20, 2024
2 parents 4e61c1e + f8847c7 commit 79a1d27
Show file tree
Hide file tree
Showing 4 changed files with 554 additions and 4 deletions.
52 changes: 51 additions & 1 deletion src/chart-standard/chart-format/rpe/beat.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,54 @@
double beat = RPEBeat[1] / RPEBeat[2] + RPEBeat[0];
double seconds = BPM * beat / 60;
```
多BPM计算方式待补充。
多BPM计算方式待补充。

## Python 示例
-`self.BPMList` 为一个 `list[BPMEvent]`
- `BPMEvent`定义:
```python
@dataclass
class BPMEvent:
startTime: Beat
bpm: float
```
- `sec2beat``t` 为秒数, `bpmfactor` 为判定线中的 `bpmfactor` 字段`
- `beat2sec``t` 为拍数, `bpmfactor` 为判定线中的 `bpmfactor` 字段`
-`beat2sec(sec2beat(x)) == x``sec2beat(beat2sec(x)) == x` 的结果均为 `True`
- 则有:
```python
def sec2beat(self, t: float, bpmfactor: float):
beat = 0.0
for i, e in enumerate(self.BPMList):
bpmv = e.bpm * bpmfactor
if i != len(self.BPMList) - 1:
et_beat = self.BPMList[i + 1].startTime.value - e.startTime.value
et_sec = et_beat * (60 / bpmv)

if t >= et_sec:
beat += et_beat
t -= et_sec
else:
beat += t / (60 / bpmv)
break
else:
beat += t / (60 / bpmv)
return beat

def beat2sec(self, t: float, bpmfactor: float):
sec = 0.0
for i, e in enumerate(self.BPMList):
bpmv = e.bpm * bpmfactor
if i != len(self.BPMList) - 1:
et_beat = self.BPMList[i + 1].startTime.value - e.startTime.value

if t >= et_beat:
sec += et_beat * (60 / bpmv)
t -= et_beat
else:
sec += t * (60 / bpmv)
break
else:
sec += t * (60 / bpmv)
return sec
```
63 changes: 62 additions & 1 deletion src/chart-standard/chart-format/rpe/event.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,65 @@
- 若不透明度事件数值为负数,则会在隐藏判定线的同时隐藏这条判定线上的所有音符。(根据作者所述,此功能是废弃的非法功能但它仍然有效)
- 音符流速事件只有上述的 `startTime``endTime``start``end``linkgroup` 字段。
- 音符流速事件**不支持缓动**,即只有线性变化。
- 流速为负数时,音符会向上飞,若音符为 `Hold`,在 `Hold` 尾出现时,整个音符都会出现(即使 `Hold` 还没完全回到判定线正面)。
- 流速为负数时,音符会向上飞,若音符为 `Hold`,在 `Hold` 尾出现时,整个音符都会出现(即使 `Hold` 还没完全回到判定线正面)。

## Python 示例 (不支持bezier):
- 定义 `rpe_easing.py` (略)
- 定义 `Beat`:
```python
@dataclass
class Beat:
var1: int
var2: int
var3: int

def __post_init__(self):
self.value = self.var1 + (self.var2 / self.var3)
self._hash = hash(self.value)

def __hash__(self) -> int:
return self._hash
```
- 定义 `LineEvent`
```python
@dataclass
class LineEvent:
startTime: Beat
endTime: Beat
start: float|str|list[int]
end: float|str|list[int]
easingType: int
easingFunc: typing.Callable[[float], float] = rpe_easing.ease_funcs[0]

def __post_init__(self):
if not isinstance(self.easingType, int): self.easingType = 1
self.easingType = 1 if self.easingType < 1 else (len(rpe_easing.ease_funcs) if self.easingType > len(rpe_easing.ease_funcs) else self.easingType)
self.easingFunc = rpe_easing.ease_funcs[self.easingType - 1]
```
- 定义 `easing_interpolation`
```python
def easing_interpolation(
t: float, st: float,
et: float, sv: float,
ev: float, f: typing.Callable[[float], float]
):
if t == st: return sv
return f((t - st) / (et - st)) * (ev - sv) + sv
```
- `default` 为事件默认值
- 则有:
```python
def GetEventValue(t: float, es: list[LineEvent], default):
for e in es:
if e.startTime.value <= t <= e.endTime.value:
if isinstance(e.start, float|int):
return easing_interpolation(t, e.startTime.value, e.endTime.value, e.start, e.end, e.easingFunc)
elif isinstance(e.start, str):
return e.start
elif isinstance(e.start, list):
r = easing_interpolation(t, e.startTime.value, e.endTime.value, e.start[0], e.end[0], e.easingFunc)
g = easing_interpolation(t, e.startTime.value, e.endTime.value, e.start[1], e.end[1], e.easingFunc)
b = easing_interpolation(t, e.startTime.value, e.endTime.value, e.start[2], e.end[2], e.easingFunc)
return (r, g, b)
return default
```
38 changes: 36 additions & 2 deletions src/chart-standard/chart-format/rpe/extend.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,40 @@ RPE允许你设置判定线的 `Texture` 字段来修改判定线的纹理,当

你可以在[这个网站](https://easings.net/zh-cn)查看它们的函数等信息。

### Python 缓动示例
```python
import math
import typing



ease_funcs:list[typing.Callable[[float], float]] = [
lambda t: t, # linear - 1
lambda t: math.sin((t * math.pi) / 2), # out sine - 2
lambda t: 1 - math.cos((t * math.pi) / 2), # in sine - 3
lambda t: 1 - (1 - t) * (1 - t), # out quad - 4
lambda t: t ** 2, # in quad - 5
lambda t: -(math.cos(math.pi * t) - 1) / 2, # io sine - 6
lambda t: 2 * (t ** 2) if t < 0.5 else 1 - (-2 * t + 2) ** 2 / 2, # io quad - 7
lambda t: 1 - (1 - t) ** 3, # out cubic - 8
lambda t: t ** 3, # in cubic - 9
lambda t: 1 - (1 - t) ** 4, # out quart - 10
lambda t: t ** 4, # in quart - 11
lambda t: 4 * (t ** 3) if t < 0.5 else 1 - (-2 * t + 2) ** 3 / 2, # io cubic - 12
lambda t: 8 * (t ** 4) if t < 0.5 else 1 - (-2 * t + 2) ** 4 / 2, # io quart - 13
lambda t: 1 - (1 - t) ** 5, # out quint - 14
lambda t: t ** 5, # in quint - 15
lambda t: 1 if t == 1 else 1 - 2 ** (-10 * t), # out expo - 16
lambda t: 0 if t == 0 else 2 ** (10 * t - 10), # in expo - 17
lambda t: (1 - (t - 1) ** 2) ** 0.5, # out circ - 18
lambda t: 1 - (1 - t ** 2) ** 0.5, # in circ - 19
lambda t: 1 + 2.70158 * ((t - 1) ** 3) + 1.70158 * ((t - 1) ** 2), # out back - 20
lambda t: 2.70158 * (t ** 3) - 1.70158 * (t ** 2), # in back - 21
lambda t: (1 - (1 - (2 * t) ** 2) ** 0.5) / 2 if t < 0.5 else (((1 - (-2 * t + 2) ** 2) ** 0.5) + 1) / 2, # io circ - 22
lambda t: ((2 * t) ** 2 * ((2.5949095 + 1) * 2 * t - 2.5949095)) / 2 if t < 0.5 else ((2 * t - 2) ** 2 * ((2.5949095 + 1) * (t * 2 - 2) + 2.5949095) + 2) / 2, # io back - 23
lambda t: 0 if t == 0 else (1 if t == 1 else 2 ** (-10 * t) * math.sin((t * 10 - 0.75) * (2 * math.pi / 3)) + 1), # out elastic - 24
lambda t: 0 if t == 0 else (1 if t == 1 else - 2 ** (10 * t - 10) * math.sin((t * 10 - 10.75) * (2 * math.pi / 3))), # in elastic - 25
lambda t: 7.5625 * (t ** 2) if (t < 1 / 2.75) else (7.5625 * (t - (1.5 / 2.75)) * (t - (1.5 / 2.75)) + 0.75 if (t < 2 / 2.75) else (7.5625 * (t - (2.25 / 2.75)) * (t - (2.25 / 2.75)) + 0.9375 if (t < 2.5 / 2.75) else (7.5625 * (t - (2.625 / 2.75)) * (t - (2.625 / 2.75)) + 0.984375))), # out bounce - 26
lambda t: 1 - (7.5625 * ((1 - t) ** 2) if ((1 - t) < 1 / 2.75) else (7.5625 * ((1 - t) - (1.5 / 2.75)) * ((1 - t) - (1.5 / 2.75)) + 0.75 if ((1 - t) < 2 / 2.75) else (7.5625 * ((1 - t) - (2.25 / 2.75)) * ((1 - t) - (2.25 / 2.75)) + 0.9375 if ((1 - t) < 2.5 / 2.75) else (7.5625 * ((1 - t) - (2.625 / 2.75)) * ((1 - t) - (2.625 / 2.75)) + 0.984375)))), # in bounce - 27
lambda t: (1 - (7.5625 * ((1 - 2 * t) ** 2) if ((1 - 2 * t) < 1 / 2.75) else (7.5625 * ((1 - 2 * t) - (1.5 / 2.75)) * ((1 - 2 * t) - (1.5 / 2.75)) + 0.75 if ((1 - 2 * t) < 2 / 2.75) else (7.5625 * ((1 - 2 * t) - (2.25 / 2.75)) * ((1 - 2 * t) - (2.25 / 2.75)) + 0.9375 if ((1 - 2 * t) < 2.5 / 2.75) else (7.5625 * ((1 - 2 * t) - (2.625 / 2.75)) * ((1 - 2 * t) - (2.625 / 2.75)) + 0.984375))))) / 2 if t < 0.5 else (1 +(7.5625 * ((2 * t - 1) ** 2) if ((2 * t - 1) < 1 / 2.75) else (7.5625 * ((2 * t - 1) - (1.5 / 2.75)) * ((2 * t - 1) - (1.5 / 2.75)) + 0.75 if ((2 * t - 1) < 2 / 2.75) else (7.5625 * ((2 * t - 1) - (2.25 / 2.75)) * ((2 * t - 1) - (2.25 / 2.75)) + 0.9375 if ((2 * t - 1) < 2.5 / 2.75) else (7.5625 * ((2 * t - 1) - (2.625 / 2.75)) * ((2 * t - 1) - (2.625 / 2.75)) + 0.984375))))) / 2, # io bounce - 28
lambda t: 0 if t == 0 else (1 if t == 0 else (-2 ** (20 * t - 10) * math.sin((20 * t - 11.125) * ((2 * math.pi) / 4.5))) / 2 if t < 0.5 else (2 ** (-20 * t + 10) * math.sin((20 * t - 11.125) * ((2 * math.pi) / 4.5))) / 2 + 1) # io elastic - 29
]
```
Loading

0 comments on commit 79a1d27

Please sign in to comment.