-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathquaternion.scrbl
99 lines (74 loc) · 2.77 KB
/
quaternion.scrbl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#lang scribble/manual
@require[
@for-label[;quaternion
racket
racket/base
racket/flonum
]]
@title{Quaternion}
@author{APOS80}
@defmodule[quaternion]
@section{Intro}
Quaternions are used for rotation of koordinates and vectors.
@section{Structures}
@defstruct*[qvector ([x flonum?][y flonum?][z flonum?]) #:mutable #:transparent]
@defstruct*[quaternion ([w flonum?] [v qvector?]) #:mutable #:transparent]
@section{Basic procedures}
@defproc[(q-add [q1 (quaternion?)]
[q2 (quaternion?)])
quaternion?]
@defproc[(q-sub [q1 (quaternion?)]
[q2 (quaternion?)])
quaternion?]
@defproc[(q-norm [q (quaternion?)])
quaternion?]
@defproc[(q-normalize [q (quaternion?)])
quaternion?]
@defproc[(q-multiply-qq [q1 (quaternion?)]
[q2 (quaternion?)])
quaternion?]
@defproc[(q-divide-qs [q (quaternion?)]
[s (flonum?)])
quaternion?]
@defproc[(q-negate [q (quaternion?)])
quaternion?]
@defproc[(q-conjugate [q (quaternion?)])
quaternion?]
@defproc[(q-inverse [q (quaternion?)])
quaternion?]
@section{Rotation}
@defproc[(q-rotation [angl (flonum?)]
[qv (qvector?)])
quaternion?]
Rotation in radians about an arbitrary axis.
Positive rotation is anticlockwise!
@defproc[(q-rotate [rotation (quaternion?)]
[object (quaternion?)])
quaternion?]
Applyes the rotation on an object.
Object quaternion's w has to be 0!
@section{Examples}
@racketblock[
(code:comment "Rotation about one axis:")
(let*
([A (q-rotation (fl/ pi 2.0) (qvector 0.0 1.0 0.0))](code:comment "Rotation 90degrees about Y-axis.")
[B (q-rotate A (quaternion 0.0 (qvector 0.0 0.0 1.0)))])(code:comment "Apply rotation on quaternion with A.")
(begin
(printf "X: ~a\n" (~r(qvector-x (quaternion-v B))))(code:comment "Print results.")
(printf "Y: ~a\n" (~r(qvector-y (quaternion-v B))))
(printf "Z: ~a\n" (~r(qvector-z (quaternion-v B))))
))
]
@racketblock[
(code:comment "Rotation about two axis:")
(let*
([A1 (q-rotation (fl/ pi 4.0) (qvector 0.0 1.0 0.0))](code:comment "Rotation 90degrees about Y-axis.")
[A2 (q-rotation (fl/ pi 4.0) (qvector 1.0 0.0 0.0))](code:comment "Rotation 90degrees about X-axis.")
[AS (q-multiply-qq A1 A2)](code:comment "Combine rotations.")
[B (q-rotate AS (quaternion 0.0 (qvector 0.0 0.0 1.0)))])(code:comment "Apply rotation on quaternion with A.")
(begin
(printf "X: ~a\n" (~r(qvector-x (quaternion-v B))))(code:comment "Print results.")
(printf "Y: ~a\n" (~r(qvector-y (quaternion-v B))))
(printf "Z: ~a\n" (~r(qvector-z (quaternion-v B))))
))
]