//by Rick Companje
//www.companje.nl
//18-11-2007

//more info
//* http://home.wanadoo.nl/rule-off/wis/reeksen.htm
//* http://lab.polygonal.de/
//* http://lab.polygonal.de/wp-content/articles/fast_trig/fastTrig.as

final float C1 = 4/PI;
final float C2 = 4/(PI*PI);
int time;

float qsinLow1(float x) {
  //efficient maar minder nauwkeurig
  //1856ms voor 100.000.000 aanroepen
  return C1*x + (C2*x*x) * (x<0?1:-1);
}

float qsinLow2(float x) {
  //efficient maar minder nauwkeurig
  //hierbij wordt geen gebruik gemaakt van de constanten
  //C1 en C2. Het scheel op 100.000.000.000 berekeningen
  //een paar milliseconden en is echt verwaarloosaar.
  //gebruik dus prima constanten (final float).
  return 1.2732395*x + (0.4052847*x*x) * (x<0?1:-1);
}

float qsinHigh1(float x) {
  //trager dan qsin1 maar een stuk nauwkeuriger
  //3851ms voor 100.000.000 aanroepen
  float sinX = qsinLow1(x);
  return .225*((x<0?-1:1)*sinX*sinX-sinX)+sinX;
}

float qsinHigh2(float x) {
  //niet efficient maar waarom? geen idee.
  //8867ms voor 100.000.000.000
  //het leek mij het overslaan van het aanroepen
  //van qsin1 en in plaats daarvan de code inline
  //uitvoeren voordelig zou moeten zijn maar integendeel.
  float sinX = C1*x + (C2*x*x) * (x<0?1:-1);
  return .225*((x<0?-1:1)*sinX*sinX-sinX)+sinX;
}

float qsinHigh3(float x) {
  //snelste nauwkeurige benadering
  //verwaarloosbaar  sneller dan qsin2
  float sinX = qsinLow2(x);
  return .225*((x<0?-1:1)*sinX*sinX-sinX)+sinX;
}

float qsinHigh4(float x) {
  //een stuk trager net als qsin3 door het juist
  //niet aanroepen van qsin4. ik vind heet vreemd.
  float sinX = 1.2732395*x + (0.4052847*x*x) * (x<0?1:-1);
  return .225*((x<0?-1:1)*sinX*sinX-sinX)+sinX;
}

void setup() {
  background(0);
  size(400,400);
  
  int maxi=100000000;
  float result;
  float x=PI;
  
  delay(1000);
  
  startTimer(); for (int i=0; i<maxi; i++) result = sin(x);  stopTimer("sin");
  startTimer(); for (int i=0; i<maxi; i++) result = qsinLow1(x); stopTimer("qsinLow1");
  startTimer(); for (int i=0; i<maxi; i++) result = qsinLow2(x); stopTimer("qsinLow2");
  startTimer(); for (int i=0; i<maxi; i++) result = qsinHigh1(x); stopTimer("qsinHigh1");
  startTimer(); for (int i=0; i<maxi; i++) result = qsinHigh2(x); stopTimer("qsinHigh2");
  startTimer(); for (int i=0; i<maxi; i++) result = qsinHigh3(x); stopTimer("qsinHigh3");
  startTimer(); for (int i=0; i<maxi; i++) result = qsinHigh4(x); stopTimer("qsinHigh4");

  //inline versie, lage nauwkeurigheid. Is het
  //snelst bij lage nauwkeurigheid.
  //kost  1233 voor 100.000.000.000 aanroepen.
  startTimer();
      for (int i=0; i<maxi; i++) result = 1.2732395*x + (0.4052847*x*x) * (x<0?1:-1);
  stopTimer("inline low");
  
  //inline versie, hoge nauwkeurigheid.
  //Is snelst bij hoge nauwkeurigheid
  //kost 2818 voor 100.000.000.000 aanroepen.
  startTimer();
  float sinX;
  for (int i=0; i<maxi; i++) {
      sinX = 1.2732395*x + (0.4052847*x*x) * (x<0?1:-1);
      result = .225*((x<0?-1:1)*sinX*sinX-sinX)+sinX;
  }
  stopTimer("inline high");
}

void startTimer() {
  time = millis();
}

void stopTimer(String descr) {
  println(descr + ": " + (millis()-time));
}


======Resultaat========
sin: 23232
qsinLow1: 1436
qsinLow2: 1421
qsinHigh1: 3195
qsinHigh2: 7443
qsinHigh3: 3154
qsinHigh4: 7532
inline low: 1233
inline high: 2818