@@ -1018,6 +1018,9 @@ class Sketch
1018
1018
m_rand(0 )
1019
1019
{
1020
1020
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);
1021
1024
}
1022
1025
1023
1026
unsigned vertex (double *x, double *y)
@@ -1037,18 +1040,31 @@ class Sketch
1037
1040
// We want the "cursor" along the sine wave to move at a
1038
1041
// random rate.
1039
1042
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);
1043
1057
double den = m_last_x - *x;
1044
1058
double num = m_last_y - *y;
1045
1059
double len = num * num + den * den;
1046
1060
m_last_x = *x;
1047
1061
m_last_y = *y;
1048
1062
if (len != 0 ) {
1049
1063
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;
1052
1068
}
1053
1069
} else {
1054
1070
m_last_x = *x;
@@ -1083,6 +1099,8 @@ class Sketch
1083
1099
bool m_has_last;
1084
1100
double m_p;
1085
1101
RandomNumberGenerator m_rand;
1102
+ double m_p_scale;
1103
+ double m_log_randomness;
1086
1104
};
1087
1105
1088
1106
#endif // MPL_PATH_CONVERTERS_H
0 commit comments