Pixel-Composer/scripts/curve_bezier_function/curve_bezier_function.gml

129 lines
2.8 KiB
Plaintext
Raw Normal View History

2023-01-09 03:14:20 +01:00
#macro CURVE_DEF_01 [0, 1/3, 1/3, 2/3, 2/3, 1]
2023-01-25 06:49:00 +01:00
#macro CURVE_DEF_10 [1, 1/3, 2/3, 2/3, 1/3, 0]
2023-01-09 03:14:20 +01:00
#macro CURVE_DEF_11 [1, 1/3, 1, 2/3, 1, 1]
function draw_line_bezier_cubic(x0, y0, _w, _h, _bz) {
2022-01-13 05:24:03 +01:00
static SAMPLE = 32;
2023-01-09 03:14:20 +01:00
var _ox, _oy;
2022-01-13 05:24:03 +01:00
for(var i = 0; i <= SAMPLE; i++) {
var t = i / SAMPLE;
2023-01-09 03:14:20 +01:00
var _r = eval_bezier_cubic(t, _bz);
var _rx = _r[0], _ry = _r[1];
var _nx = _rx * _w + x0;
2022-01-13 05:24:03 +01:00
var _ny = (_h? _ry : 1 - _ry) * abs(_h) + y0;
2023-01-09 03:14:20 +01:00
if(i)
draw_line(_ox, _oy, _nx, _ny);
_ox = _nx;
2022-01-13 05:24:03 +01:00
_oy = _ny;
}
}
2023-01-09 03:14:20 +01:00
function eval_bezier_cubic(t, _bz) {
return [
power(1 - t, 3) * 0
+ 3 * power(1 - t, 2) * t * _bz[1]
+ 3 * (1 - t) * power(t, 2) * _bz[3]
+ power(t, 3) * 1,
power(1 - t, 3) * _bz[0]
+ 3 * power(1 - t, 2) * t * _bz[2]
+ 3 * (1 - t) * power(t, 2) * _bz[4]
+ power(t, 3) * _bz[5]
];
}
function eval_curve_bezier_cubic_x(_bz, _x, _prec = 0.00001) {
var st = 0;
var ed = 1;
var _xt = _x;
var _binRep = 5;
2023-01-25 06:49:00 +01:00
if(_x == 0) return _bz[0];
if(_x == 1) return _bz[5];
2023-01-17 08:11:55 +01:00
if(_bz[0] == _bz[2] && _bz[0] == _bz[4] && _bz[0] == _bz[5]) return _bz[0];
2023-01-09 03:14:20 +01:00
repeat(_binRep) {
var _ftx = power(1 - _xt, 3) * 0
+ 3 * power(1 - _xt, 2) * _xt * _bz[1]
+ 3 * (1 - _xt) * power(_xt, 2) * _bz[3]
+ power(_xt, 3) * 1;
if(abs(_ftx - _x) < _prec)
return eval_curve_bezier_cubic_t(_bz, _xt);
if(_xt < _x)
st = _xt;
else
ed = _xt;
_xt = (st + ed) / 2;
}
var _newRep = 8;
repeat(_newRep) {
var slope = (9 * _bz[1] - 9 * _bz[3] + 3) * _xt * _xt
+ (-12 * _bz[1] + 6 * _bz[3]) * _xt
+ 3 * _bz[1];
var _ftx = power(1 - _xt, 3) * 0
+ 3 * power(1 - _xt, 2) * _xt * _bz[1]
+ 3 * (1 - _xt) * power(_xt, 2) * _bz[3]
+ power(_xt, 3) * 1
- _x;
_xt -= _ftx / slope;
if(abs(_ftx) < _prec)
break;
}
return eval_curve_bezier_cubic_t(_bz, _xt);
2022-01-13 05:24:03 +01:00
}
2023-01-09 03:14:20 +01:00
function eval_curve_bezier_cubic_t(_bz, t) {
return power(1 - t, 3) * _bz[0]
+ 3 * power(1 - t, 2) * t * _bz[2]
+ 3 * (1 - t) * power(t, 2) * _bz[4]
+ power(t, 3) * _bz[5];
2022-01-13 05:24:03 +01:00
}
2023-01-09 03:14:20 +01:00
function bezier_range(bz) {
return [ min(bz[0], bz[2], bz[4], bz[5]), max(bz[0], bz[2], bz[4], bz[5]) ];
2022-01-13 05:24:03 +01:00
}
2022-12-27 04:00:50 +01:00
function bezier_interpol_x(a, b, t, iteration = 10) {
2022-01-13 05:24:03 +01:00
var fx, _x = 0.5, _x1, slope;
repeat(iteration) {
fx = (3 * a - 3 * b + 1) * _x * _x * _x
+ (3 * b - 6 * a) * _x * _x
+ 3 * a * _x
- t;
slope = 3 * (3 * a - 3 * b + 1) * _x * _x
+ 2 * (3 * b - 6 * a) * _x
+ 3 * a;
_x -= fx / slope;
}
return 3 * (1 - _x) * _x * _x + _x * _x * _x;
2022-09-23 13:28:42 +02:00
}
2022-12-27 04:00:50 +01:00
function ease_bezier(t, a, b) {
return 3 * power(1 - t, 2) * t * a + 3 * (1 - t) * power(t, 2) * b + power(t, 3);
}
2022-09-23 13:28:42 +02:00
function ease_cubic_in(rat) {
2022-12-27 04:00:50 +01:00
return power(rat, 3);
2022-09-23 13:28:42 +02:00
}
function ease_cubic_out(rat) {
return 1 - power(1 - rat, 3);
}
function ease_cubic_inout(rat) {
return rat < 0.5 ? 4 * power(rat, 3) : 1 - power(-2 * rat + 2, 3) / 2;
2022-01-13 05:24:03 +01:00
}