diff options
author | rgl <devnull@localhost> | 2020-02-03 22:42:28 +0100 |
---|---|---|
committer | rgl <devnull@localhost> | 2020-02-03 22:42:28 +0100 |
commit | 0373255087377122eeb10e006ffb8aa1b57e611c (patch) | |
tree | 33a4fafa4996fc2efa205b2973622c3fbd27f368 /libgeometry/quaternion.c | |
download | 3dee-0373255087377122eeb10e006ffb8aa1b57e611c.tar.gz 3dee-0373255087377122eeb10e006ffb8aa1b57e611c.tar.bz2 3dee-0373255087377122eeb10e006ffb8aa1b57e611c.zip |
after a year or so of work, i dare create a proper repo.
Diffstat (limited to 'libgeometry/quaternion.c')
-rw-r--r-- | libgeometry/quaternion.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/libgeometry/quaternion.c b/libgeometry/quaternion.c new file mode 100644 index 0000000..b8eaa88 --- /dev/null +++ b/libgeometry/quaternion.c @@ -0,0 +1,90 @@ +#include <u.h> +#include <libc.h> +#include "../geometry.h" + +Quaternion +Quat(double r, double i, double j, double k) +{ + return (Quaternion){r, i, j, k}; +} + +Quaternion +Quatvec(double s, Point3 v) +{ + return (Quaternion){s, v.x, v.y, v.z}; +} + +Quaternion +addq(Quaternion a, Quaternion b) +{ + return (Quaternion){a.r+b.r, a.i+b.i, a.j+b.j, a.k+b.k}; +} + +Quaternion +subq(Quaternion a, Quaternion b) +{ + return (Quaternion){a.r-b.r, a.i-b.i, a.j-b.j, a.k-b.k}; +} + +Quaternion +mulq(Quaternion q, Quaternion r) +{ + Point3 qv, rv, tmp; + + qv = Vec3(q.i, q.j, q.k); + rv = Vec3(r.i, r.j, r.k); + tmp = addpt3(addpt3(mulpt3(rv, q.r), mulpt3(qv, r.r)), crossvec3(qv, rv)); + return (Quaternion){q.r*r.r - dotvec3(qv, rv), tmp.x, tmp.y, tmp.z}; +} + +Quaternion +smulq(Quaternion q, double s) +{ + return (Quaternion){q.r*s, q.i*s, q.j*s, q.k*s}; +} + +Quaternion +sdivq(Quaternion q, double s) +{ + return (Quaternion){q.r/s, q.i/s, q.j/s, q.k/s}; +} + +double +dotq(Quaternion q, Quaternion r) +{ + return q.r*r.r + q.i*r.i + q.j*r.j + q.k*r.k; +} + +Quaternion +invq(Quaternion q) +{ + double len²; + + len² = dotq(q, q); + if(len² == 0) + return (Quaternion){0, 0, 0, 0}; + return (Quaternion){q.r/len², -q.i/len², -q.j/len², -q.k/len²}; +} + +double +qlen(Quaternion q) +{ + return sqrt(q.r*q.r + q.i*q.i + q.j*q.j + q.k*q.k); +} + +Quaternion +normq(Quaternion q) +{ + return sdivq(q, qlen(q)); +} + +Point3 +qrotate(Point3 p, Point3 axis, double angle) +{ + Quaternion qaxis, qr; + + angle /= 2; + qaxis = Quatvec(cos(angle), mulpt3(axis, sin(angle))); + qr = mulq(mulq(qaxis, Quatvec(0, p)), invq(qaxis)); + return Vec3(qr.i, qr.j, qr.k); +} |