[libadwaita/wip/exalm/spring-animation-swipes: 22/36] math fixes
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libadwaita/wip/exalm/spring-animation-swipes: 22/36] math fixes
- Date: Mon, 6 Dec 2021 12:06:05 +0000 (UTC)
commit cb457f08375d45fa4274b0a9a756cb59d613cb44
Author: Manuel Genovés <manuel genoves gmail com>
Date: Sat Dec 4 19:10:11 2021 +0100
math fixes
src/adw-spring-animation.c | 33 +++++++++++++++++++++------------
1 file changed, 21 insertions(+), 12 deletions(-)
---
diff --git a/src/adw-spring-animation.c b/src/adw-spring-animation.c
index ef1bcbfd..4bf28a88 100644
--- a/src/adw-spring-animation.c
+++ b/src/adw-spring-animation.c
@@ -78,6 +78,9 @@ oscillate (AdwAnimation *animation,
double envelope = exp (-beta * t);
+ if (!G_APPROX_VALUE (self->value_from, self->value_to, FLT_EPSILON))
+ v0 = self->initial_velocity / (ABS (self->value_from - self->value_to));
+
/*
* Solutions of the form C1*e^(lambda1*x) + C2*e^(lambda2*x)
* for the differential equation m*ẍ+b*ẋ+kx = 0
@@ -94,7 +97,7 @@ oscillate (AdwAnimation *animation,
if (beta > omega0) {
double omega2 = sqrt ((beta * beta) - (omega0 * omega0));
- return -x0 + envelope * (x0 * cosh (omega2 * t) + ((beta * x0 + v0) / omega2) * sinh (omega2 * t));
+ return -x0 + envelope * (x0 * coshl (omega2 * t) + ((beta * x0 + v0) / omega2) * sinhl (omega2 * t));
}
/* Critically damped */
@@ -116,6 +119,8 @@ adw_spring_animation_estimate_duration (AdwAnimation *animation)
double x1, y1;
double m;
+ int i = 0;
+
if (beta <= 0)
return ADW_DURATION_INFINITE;
@@ -137,20 +142,23 @@ adw_spring_animation_estimate_duration (AdwAnimation *animation)
* Newton's root finding method is a good candidate in this particular case:
* https://en.wikipedia.org/wiki/Newton%27s_method
*/
- y0 = oscillate (animation, -1, x0);
- m = (oscillate (animation, -1, x0 + DELTA) - y0) / DELTA;
+ y0 = oscillate (animation, -1, x0*1000);
+ m = (oscillate (animation, -1, (x0 + DELTA) * 1000) - y0) / DELTA;
x1 = (1 - y0 + m * x0) / m;
- y1 = oscillate (animation, -1, x1);
+ y1 = oscillate (animation, -1, x1*1000);
while (ABS (1 - y1) > self->epsilon) {
+ if (i>1000)
+ return 0;
x0 = x1;
y0 = y1;
- m = (oscillate (animation, -1, x0 + DELTA) - y0) / DELTA;
+ m = (oscillate (animation, -1, (x0 + DELTA) * 1000) - y0) / DELTA;
x1 = (1 - y0 + m * x0) / m;
- y1 = oscillate (animation, -1, x1);
+ y1 = oscillate (animation, -1, x1*1000);
+ i++;
}
return x1 * 1000;
@@ -321,7 +329,7 @@ adw_spring_animation_class_init (AdwSpringAnimationClass *klass)
-G_MAXDOUBLE,
G_MAXDOUBLE,
0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+ G_PARAM_READWRITE);
props[PROP_EPSILON] =
g_param_spec_double ("epsilon",
@@ -330,7 +338,7 @@ adw_spring_animation_class_init (AdwSpringAnimationClass *klass)
0,
G_MAXDOUBLE,
0.001,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+ G_PARAM_READWRITE);
props[PROP_ESTIMATED_DURATION] =
g_param_spec_uint ("estimated-duration",
@@ -347,6 +355,7 @@ adw_spring_animation_class_init (AdwSpringAnimationClass *klass)
static void
adw_spring_animation_init (AdwSpringAnimation *self)
{
+ self->epsilon = 0.001;
}
AdwAnimation *
@@ -389,7 +398,7 @@ adw_spring_animation_set_value_from (AdwSpringAnimation *self,
{
g_return_if_fail (ADW_IS_SPRING_ANIMATION (self));
- if (self->value_from == value)
+ if (G_APPROX_VALUE (self->value_from, value, FLT_EPSILON))
return;
self->value_from = value;
@@ -413,7 +422,7 @@ adw_spring_animation_set_value_to (AdwSpringAnimation *self,
{
g_return_if_fail (ADW_IS_SPRING_ANIMATION (self));
- if (self->value_to == value)
+ if (G_APPROX_VALUE (self->value_to, value, FLT_EPSILON))
return;
self->value_to = value;
@@ -467,7 +476,7 @@ adw_spring_animation_set_initial_velocity (AdwSpringAnimation *self,
{
g_return_if_fail (ADW_IS_SPRING_ANIMATION (self));
- if (self->initial_velocity == value)
+ if (G_APPROX_VALUE (self->initial_velocity, value, FLT_EPSILON))
return;
self->initial_velocity = value;
@@ -492,7 +501,7 @@ adw_spring_animation_set_epsilon (AdwSpringAnimation *self,
g_return_if_fail (ADW_IS_SPRING_ANIMATION (self));
g_return_if_fail (value > 0.0);
- if (self->epsilon == value)
+ if (G_APPROX_VALUE (self->epsilon, value, FLT_EPSILON))
return;
self->epsilon = value;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]