1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package r3
16
17 import (
18 "fmt"
19 "math/big"
20 )
21
22 const (
23
24
25
26 prec = big.MaxPrec
27 )
28
29
30 var (
31 precise0 = precInt(0)
32 precise1 = precInt(1)
33 )
34
35
36
37
38 func precStr(s string) *big.Float {
39
40 f, _ := new(big.Float).SetPrec(prec).SetString(s)
41 return f
42 }
43
44 func precInt(i int64) *big.Float {
45 return new(big.Float).SetPrec(prec).SetInt64(i)
46 }
47
48 func precFloat(f float64) *big.Float {
49 return new(big.Float).SetPrec(prec).SetFloat64(f)
50 }
51
52 func precAdd(a, b *big.Float) *big.Float {
53 return new(big.Float).SetPrec(prec).Add(a, b)
54 }
55
56 func precSub(a, b *big.Float) *big.Float {
57 return new(big.Float).SetPrec(prec).Sub(a, b)
58 }
59
60 func precMul(a, b *big.Float) *big.Float {
61 return new(big.Float).SetPrec(prec).Mul(a, b)
62 }
63
64
65
66
67
68
69 type PreciseVector struct {
70 X, Y, Z *big.Float
71 }
72
73
74 func PreciseVectorFromVector(v Vector) PreciseVector {
75 return NewPreciseVector(v.X, v.Y, v.Z)
76 }
77
78
79 func NewPreciseVector(x, y, z float64) PreciseVector {
80 return PreciseVector{
81 X: precFloat(x),
82 Y: precFloat(y),
83 Z: precFloat(z),
84 }
85 }
86
87
88 func (v PreciseVector) Vector() Vector {
89
90 x, _ := v.X.Float64()
91 y, _ := v.Y.Float64()
92 z, _ := v.Z.Float64()
93 return Vector{x, y, z}.Normalize()
94 }
95
96
97 func (v PreciseVector) Equal(ov PreciseVector) bool {
98 return v.X.Cmp(ov.X) == 0 && v.Y.Cmp(ov.Y) == 0 && v.Z.Cmp(ov.Z) == 0
99 }
100
101 func (v PreciseVector) String() string {
102 return fmt.Sprintf("(%10g, %10g, %10g)", v.X, v.Y, v.Z)
103 }
104
105
106 func (v PreciseVector) Norm2() *big.Float { return v.Dot(v) }
107
108
109 func (v PreciseVector) IsUnit() bool {
110 return v.Norm2().Cmp(precise1) == 0
111 }
112
113
114 func (v PreciseVector) Abs() PreciseVector {
115 return PreciseVector{
116 X: new(big.Float).Abs(v.X),
117 Y: new(big.Float).Abs(v.Y),
118 Z: new(big.Float).Abs(v.Z),
119 }
120 }
121
122
123 func (v PreciseVector) Add(ov PreciseVector) PreciseVector {
124 return PreciseVector{
125 X: precAdd(v.X, ov.X),
126 Y: precAdd(v.Y, ov.Y),
127 Z: precAdd(v.Z, ov.Z),
128 }
129 }
130
131
132 func (v PreciseVector) Sub(ov PreciseVector) PreciseVector {
133 return PreciseVector{
134 X: precSub(v.X, ov.X),
135 Y: precSub(v.Y, ov.Y),
136 Z: precSub(v.Z, ov.Z),
137 }
138 }
139
140
141 func (v PreciseVector) Mul(f *big.Float) PreciseVector {
142 return PreciseVector{
143 X: precMul(v.X, f),
144 Y: precMul(v.Y, f),
145 Z: precMul(v.Z, f),
146 }
147 }
148
149
150 func (v PreciseVector) MulByFloat64(f float64) PreciseVector {
151 return v.Mul(precFloat(f))
152 }
153
154
155 func (v PreciseVector) Dot(ov PreciseVector) *big.Float {
156 return precAdd(precMul(v.X, ov.X), precAdd(precMul(v.Y, ov.Y), precMul(v.Z, ov.Z)))
157 }
158
159
160 func (v PreciseVector) Cross(ov PreciseVector) PreciseVector {
161 return PreciseVector{
162 X: precSub(precMul(v.Y, ov.Z), precMul(v.Z, ov.Y)),
163 Y: precSub(precMul(v.Z, ov.X), precMul(v.X, ov.Z)),
164 Z: precSub(precMul(v.X, ov.Y), precMul(v.Y, ov.X)),
165 }
166 }
167
168
169 func (v PreciseVector) LargestComponent() Axis {
170 t := v.Abs()
171
172 if t.X.Cmp(t.Y) > 0 {
173 if t.X.Cmp(t.Z) > 0 {
174 return XAxis
175 }
176 return ZAxis
177 }
178 if t.Y.Cmp(t.Z) > 0 {
179 return YAxis
180 }
181 return ZAxis
182 }
183
184
185 func (v PreciseVector) SmallestComponent() Axis {
186 t := v.Abs()
187
188 if t.X.Cmp(t.Y) < 0 {
189 if t.X.Cmp(t.Z) < 0 {
190 return XAxis
191 }
192 return ZAxis
193 }
194 if t.Y.Cmp(t.Z) < 0 {
195 return YAxis
196 }
197 return ZAxis
198 }
199
200
201 func (v PreciseVector) IsZero() bool {
202 return v.X.Sign() == 0 && v.Y.Sign() == 0 && v.Z.Sign() == 0
203 }
204
View as plain text