[libadwaita/wip/exalm/spring-animation-swipes: 22/36] math fixes




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]