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  }