gonum.org/v1/gonum@v0.14.0/num/quat/quat_example_test.go (about) 1 // Copyright ©2018 The Gonum Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package quat_test 6 7 import ( 8 "fmt" 9 "math" 10 11 "gonum.org/v1/gonum/floats/scalar" 12 "gonum.org/v1/gonum/num/quat" 13 ) 14 15 // point is a 3-dimensional point/vector. 16 type point struct { 17 x, y, z float64 18 } 19 20 // raise raises the dimensionality of a point to a quaternion. 21 func raise(p point) quat.Number { 22 return quat.Number{Imag: p.x, Jmag: p.y, Kmag: p.z} 23 } 24 25 // rotate performs the quaternion rotation of p by the given quaternion 26 // and scaling by the scale factor. 27 func rotate(p point, by quat.Number, scale float64) point { 28 // Ensure the modulus of by is correctly scaled. 29 if len := quat.Abs(by); len != scale { 30 by = quat.Scale(math.Sqrt(scale)/len, by) 31 } 32 33 // Perform the rotation/scaling. 34 pp := quat.Mul(quat.Mul(by, raise(p)), quat.Conj(by)) 35 36 // Extract the point. 37 return point{x: pp.Imag, y: pp.Jmag, z: pp.Kmag} 38 } 39 40 // Rotate a cube 120° around the diagonal vector [1, 1, 1]. 41 func Example_rotate() { 42 alpha := 2 * math.Pi / 3 43 q := raise(point{1, 1, 1}) 44 scale := 1.0 45 46 q = quat.Scale(math.Sin(alpha/2)/quat.Abs(q), q) 47 q.Real += math.Cos(alpha / 2) 48 49 for i, p := range []point{ 50 {x: 0, y: 0, z: 0}, 51 {x: 0, y: 0, z: 1}, 52 {x: 0, y: 1, z: 0}, 53 {x: 0, y: 1, z: 1}, 54 {x: 1, y: 0, z: 0}, 55 {x: 1, y: 0, z: 1}, 56 {x: 1, y: 1, z: 0}, 57 {x: 1, y: 1, z: 1}, 58 } { 59 pp := rotate(p, q, scale) 60 61 // Clean up floating point error for clarity. 62 pp.x = scalar.Round(pp.x, 2) 63 pp.y = scalar.Round(pp.y, 2) 64 pp.z = scalar.Round(pp.z, 2) 65 66 fmt.Printf("%d %+v -> %+v\n", i, p, pp) 67 } 68 69 // Output: 70 // 71 // 0 {x:0 y:0 z:0} -> {x:0 y:0 z:0} 72 // 1 {x:0 y:0 z:1} -> {x:1 y:0 z:0} 73 // 2 {x:0 y:1 z:0} -> {x:0 y:0 z:1} 74 // 3 {x:0 y:1 z:1} -> {x:1 y:0 z:1} 75 // 4 {x:1 y:0 z:0} -> {x:0 y:1 z:0} 76 // 5 {x:1 y:0 z:1} -> {x:1 y:1 z:0} 77 // 6 {x:1 y:1 z:0} -> {x:0 y:1 z:1} 78 // 7 {x:1 y:1 z:1} -> {x:1 y:1 z:1} 79 }