From dc7f9bef93bffb9a35cca1e11df85039fa78f7ad Mon Sep 17 00:00:00 2001 From: Jiri Pittner Date: Wed, 28 Oct 2026 23:06:08 +0100 Subject: [PATCH] bugfixes in quaternion --- quaternion.cc | 16 +++++++++++++++- quaternion.h | 8 ++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/quaternion.cc b/quaternion.cc index f8a4914..e6787aa 100644 --- a/quaternion.cc +++ b/quaternion.cc @@ -362,7 +362,7 @@ Quaternion exp(const Quaternion &x) Quaternion r; T vnorm = sqrt(x[1]*x[1]+x[2]*x[2]+x[3]*x[3]); r[0] = cos(vnorm); -vnorm = sin(vnorm)/vnorm; +vnorm = vnorm==0 ? (T)1 : sin(vnorm)/vnorm; //limit for a real quaternion r[1] = x[1] * vnorm; r[2] = x[2] * vnorm; r[3] = x[3] * vnorm; @@ -378,6 +378,13 @@ Quaternion log(const Quaternion &x) { Quaternion r; T vnorm = x[1]*x[1]+x[2]*x[2]+x[3]*x[3]; +if(vnorm==0) //real quaternion; for a negative one the i axis is chosen (as for complex numbers) + { + r[0] = ::log(x[0]<0? -x[0] : x[0]); + r[1] = x[0]<0? (T)M_PI : (T)0; + r[2] = r[3] = 0; + return r; + } T xnorm = vnorm + x[0]*x[0]; vnorm = sqrt(vnorm); xnorm = sqrt(xnorm); @@ -395,6 +402,13 @@ Quaternion pow(const Quaternion &x, const T &y) { Quaternion r; T vnorm = x[1]*x[1]+x[2]*x[2]+x[3]*x[3]; +if(vnorm==0) //real quaternion; for a negative one the i axis is chosen (as for complex numbers) + { + if(x[0]>=0) {r[0] = ::pow(x[0],y); r[1]=0;} + else {T a = ::pow(-x[0],y); r[0] = a*cos((T)M_PI*y); r[1] = a*sin((T)M_PI*y);} + r[2] = r[3] = 0; + return r; + } T xnorm = vnorm + x[0]*x[0]; vnorm = sqrt(vnorm); xnorm = sqrt(xnorm); diff --git a/quaternion.h b/quaternion.h index 58bd457..24e148d 100644 --- a/quaternion.h +++ b/quaternion.h @@ -131,8 +131,8 @@ public: //C-style IO int fprintf(FILE *f, const char *format) const {return ::fprintf(f,format,q[0],q[1],q[2],q[3]);}; int sprintf(char *f, const char *format) const {return ::sprintf(f,format,q[0],q[1],q[2],q[3]);}; - int fscanf(FILE *f, const char *format) const {return ::fscanf(f,format,q[0],q[1],q[2],q[3]);}; - int sscanf(char *f, const char *format) const {return ::sscanf(f,format,q[0],q[1],q[2],q[3]);}; + int fscanf(FILE *f, const char *format) {return ::fscanf(f,format,&q[0],&q[1],&q[2],&q[3]);}; + int sscanf(const char *f, const char *format) {return ::sscanf(f,format,&q[0],&q[1],&q[2],&q[3]);}; }; @@ -206,8 +206,8 @@ T q23= q[2]*q[3]; if(transpose) //effectively sign change of the temporaries { q01 = -q01; - q02 = -q03; - q03 = -q02; + q02 = -q02; + q03 = -q03; } a[0][1] = 2*(q12+q03); a[1][0] = 2*(q12-q03);