github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/physicscompress2/pos/pos.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "math" 6 "math/rand" 7 "time" 8 ) 9 10 func sin(v float32) float32 { return float32(math.Sin(float64(v))) } 11 func cos(v float32) float32 { return float32(math.Cos(float64(v))) } 12 func sqrt(v float32) float32 { return float32(math.Sqrt(float64(v))) } 13 14 func atan2(x, y float32) float32 { return float32(math.Atan2(float64(x), float64(y))) } 15 func acos(x float32) float32 { return float32(math.Acos(float64(x))) } 16 17 type XYZ struct{ X, Y, Z float32 } 18 19 func (p XYZ) Polar() Polar { 20 r := p.Len() 21 return Polar{ 22 R: r, 23 O: atan2(p.Y, p.X), 24 F: acos(p.Z / r), 25 } 26 } 27 28 func (a XYZ) Sub(b XYZ) XYZ { 29 return XYZ{X: a.X - b.X, Y: a.Y - b.Y, Z: a.Z - b.Z} 30 } 31 32 func (p XYZ) Len() float32 { 33 return sqrt(p.X*p.X + p.Y*p.Y + p.Z*p.Z) 34 } 35 36 func (p XYZ) Norm() XYZ { return p.Div(p.Len()) } 37 func (p XYZ) Div(v float32) XYZ { return XYZ{X: p.X / v, Y: p.Y / v, Z: p.Z / v} } 38 func (p XYZ) Mul(v float32) XYZ { return XYZ{X: p.X * v, Y: p.Y * v, Z: p.Z * v} } 39 40 func (p XYZ) Round(t float32) XYZ { 41 return XYZ{ 42 X: float32(int(p.X*t)) / t, 43 Y: float32(int(p.Y*t)) / t, 44 Z: float32(int(p.Z*t)) / t, 45 } 46 } 47 48 type Polar struct{ R, F, O float32 } 49 50 func (p Polar) XYZ() XYZ { 51 return XYZ{ 52 X: p.R * cos(p.O) * sin(p.F), 53 Y: p.R * sin(p.O) * sin(p.F), 54 Z: p.R * cos(p.F), 55 } 56 } 57 58 func (p Polar) Round(t float32) Polar { 59 return Polar{ 60 R: float32(int(p.R*t)) / t, 61 O: float32(int(p.O*t)) / t, 62 F: float32(int(p.F*t)) / t, 63 } 64 } 65 66 func Rand(s float32) XYZ { 67 return XYZ{ 68 X: rand.Float32()*s - s/2, 69 Y: rand.Float32()*s - s/2, 70 Z: rand.Float32()*s - s/2, 71 } 72 } 73 74 func RandLen(x float32) XYZ { 75 return XYZ{ 76 X: rand.Float32() - 1/2, 77 Y: rand.Float32() - 1/2, 78 Z: rand.Float32() - 1/2, 79 }.Norm().Mul(x) 80 } 81 82 func main() { 83 rand.Seed(time.Now().UnixNano()) 84 85 a := RandLen(40.0) 86 for i := 0; i < 8; i += 1 { 87 t := a.Polar().Round(float32(uint(1) << uint(i))) 88 b := t.XYZ() 89 d := a.Sub(b) 90 l := d.Len() 91 92 fmt.Println(i) 93 fmt.Println(" L:", l) 94 fmt.Println(" S:", a) 95 fmt.Println(" S2:", a.Round(float32(uint(1)<<uint(i)))) 96 fmt.Println(" E:", b) 97 fmt.Println(" D:", d) 98 } 99 100 }