void quaternion::slerp(const quaternion &p, const quaternion &q, float time, quaternion &result) { if (time <= 0.0f) { result = p; return; } if (time >= 1.0f) { result = q; return; } float cos_omega = p.s * q.s + p.x * q.x + p.y * q.y + p.z * q.z; quaternion temp = q; if (cos_omega < 0.0f) { temp = -temp; cos_omega = -cos_omega; } /* // I really dont think this is faster, but I'll check it out later float sin_omega = sqrt(1.0f - cos_omega * cos_omega); float omega = atan2(sin_omega, cos_omega); float inv_sin = 1.0f / sin_omega; float k0 = sin((1.0f - time) * omega) * inv_sin; float k1 = sin(time * omega) * inv_sin; result = p * k0 + temp * k1; */ float omega = (float)facos(p.s * q.s + p.x * q.x + p.y * q.y + p.z * q.z); result = ((p * ((float)fsin(omega * (1.0f - time))) + (q * (float)fsin(omega*time)))) / (float)fsin(omega); }
static BOOL act(int p,int q) { /* act on selected key */ int k,n,c; aprint(PRESSED,4+5*p,6+3*q,keys[q][p]); switch(p+7*q) { case 0: if (degrees) fmul(x,radeg,x); if (hyp) fsinh(x,x); else fsin(x,x); newx=TRUE; break; case 1: if (degrees) fmul(x,radeg,x); if (hyp) fcosh(x,x); else fcos(x,x); newx=TRUE; break; case 2: if (degrees) fmul(x,radeg,x); if (hyp) ftanh(x,x); else ftan(x,x); newx=TRUE; break; case 3: if (lgbase>0) { n=size(x); if (abs(n)<MR_TOOBIG) { convert(lgbase,x); if (n<0) frecip(x,x); fpower(x,abs(n),x); newx=TRUE; break; } if (lgbase==2) fmul(x,loge2,x); if (lgbase==10) fmul(x,loge10,x); } fexp(x,x); newx=TRUE; break; case 4: mip->RPOINT=!mip->RPOINT; newx=TRUE; break; case 5: clrall(); newx=TRUE; break; case 6: return TRUE; case 7: if (hyp) fasinh(x,x); else fasin(x,x); if (degrees) fdiv(x,radeg,x); newx=TRUE; break; case 8: if (hyp) facosh(x,x); else facos(x,x); if (degrees) fdiv(x,radeg,x); newx=TRUE; break; case 9: if (hyp) fatanh(x,x); else fatan(x,x); if (degrees) fdiv(x,radeg,x); newx=TRUE; break; case 10: flog(x,x); if (lgbase==2) fdiv(x,loge2,x); if (lgbase==10) fdiv(x,loge10,x); newx=TRUE; break; case 11: newx=TRUE; k=3; forever { aprint(INVER,2+stptr[k],2,settings[k][option[k]]); curser(2+stptr[k],2); c=arrow(gethit()); if (c==1) { if (option[k]==nops[k]) option[k]=0; else option[k]+=1; continue; } aprint(STATCOL,2+stptr[k],2,settings[k][option[k]]); if (c==0 || c==2) break; if (c==4 && k>0) k--; if (c==3 && k<3) k++; } setopts(); break; case 12: chekit(7); break; case 13: result=FALSE; if (ipt==0) break; ipt--; mybuff[ipt]='\0'; if (ipt==0) clr(); just(mybuff); cinstr(x,mybuff); newx=TRUE; break; case 14: if (!next('7')) putchar(BELL); break; case 15: if (!next('8')) putchar(BELL); break; case 16: if (!next('9')) putchar(BELL); break; case 17: chekit(6); break; case 18: chekit(5); break; case 19: chekit(4); break; case 20: copy(m,x); newx=TRUE; break; case 21: if (!next('4')) putchar(BELL); break; case 22: if (!next('5')) putchar(BELL); break; case 23: if (!next('6')) putchar(BELL); break; case 24: fmul(x,x,x); newx=TRUE; break; case 25: froot(x,2,x); newx=TRUE; break; case 26: chekit(3); break; case 27: brkt=0; chekit(0); flag=OFF; fadd(m,x,m); newx=TRUE; break; case 28: if (!next('1')) putchar(BELL); break; case 29: if (!next('2')) putchar(BELL); break; case 30: if (!next('3')) putchar(BELL); break; case 31: frecip(x,x); newx=TRUE; break; case 32: fpi(x); newx=TRUE; break; case 33: chekit(2); break; case 34: negify(x,x); newx=TRUE; break; case 35: if (!next('0')) putchar(BELL); break; case 36: if (!next('/')) putchar(BELL); break; case 37: if (!next('.')) putchar(BELL); break; case 38: if (ipt>0) { putchar(BELL); result=FALSE; } else { zero(x); brkt+=1; newx=TRUE; } break; case 39: if (brkt>0) { chekit(0); brkt-=1; } else { putchar(BELL); result=FALSE; } break; case 40: chekit(1); break; case 41: brkt=0; equals(0); flag=OFF; break; } return FALSE; }