@@ -1018,6 +1018,9 @@ class Sketch
10181018 m_rand(0 )
10191019 {
10201020 rewind (0 );
1021+ const double d_M_PI = 3.14159265358979323846 ;
1022+ m_p_scale = (2.0 * d_M_PI) / (m_length * m_randomness);
1023+ m_log_randomness = 2.0 * log (m_randomness);
10211024 }
10221025
10231026 unsigned vertex (double *x, double *y)
@@ -1037,18 +1040,31 @@ class Sketch
10371040 // We want the "cursor" along the sine wave to move at a
10381041 // random rate.
10391042 double d_rand = m_rand.get_double ();
1040- double d_M_PI = 3.14159265358979323846 ;
1041- m_p += pow (m_randomness, d_rand * 2.0 - 1.0 );
1042- double r = sin (m_p / (m_length / (d_M_PI * 2.0 ))) * m_scale;
1043+ // Original computation
1044+ // p += pow(k, 2*rand - 1)
1045+ // r = sin(p * c)
1046+ // x86 computes pow(a, b) as exp(b*log(a))
1047+ // First, move -1 out, so
1048+ // p' += pow(k, 2*rand)
1049+ // r = sin(p * c') where c' = c / k
1050+ // Next, use x86 logic (will not be worse on other platforms as
1051+ // the log is only computed once and pow and exp are, at worst,
1052+ // the same)
1053+ // So p+= exp(2*rand*log(k))
1054+ // lk = 2*log(k)
1055+ // p += exp(rand*lk)
1056+ m_p += exp (d_rand * m_log_randomness);
10431057 double den = m_last_x - *x;
10441058 double num = m_last_y - *y;
10451059 double len = num * num + den * den;
10461060 m_last_x = *x;
10471061 m_last_y = *y;
10481062 if (len != 0 ) {
10491063 len = sqrt (len);
1050- *x += r * num / len;
1051- *y += r * -den / len;
1064+ double r = sin (m_p * m_p_scale) * m_scale;
1065+ double roverlen = r / len;
1066+ *x += roverlen * num;
1067+ *y -= roverlen * den;
10521068 }
10531069 } else {
10541070 m_last_x = *x;
@@ -1083,6 +1099,8 @@ class Sketch
10831099 bool m_has_last;
10841100 double m_p;
10851101 RandomNumberGenerator m_rand;
1102+ double m_p_scale;
1103+ double m_log_randomness;
10861104};
10871105
10881106#endif // MPL_PATH_CONVERTERS_H
0 commit comments