github.com/pavlo67/common@v0.5.3/common/mathlib/plane/contour.go (about) 1 package plane 2 3 type Contour PolyChain 4 5 func (c Contour) Rotations() []XToYAngle { 6 rotations := make([]XToYAngle, len(c)) 7 8 for i, p := range c { 9 rotations[i] = c[(i+1)%len(c)].Sub(p).XToYAngleFromOx() 10 } 11 12 return rotations 13 } 14 15 func (c Contour) Distances() []float64 { 16 distances := make([]float64, len(c)) 17 18 for i, p := range c { 19 distances[i] = p.DistanceTo(c[(i+1)%len(c)]) 20 } 21 22 return distances 23 } 24 25 func (c Contour) Approximate(deviationMax float64) Contour { 26 if len(c) <= 2 { 27 return c 28 } 29 30 distances := c.Distances() 31 var i0, i1 int 32 var d0, d1 float64 33 34 for i, d := range distances { 35 d2 := d + distances[(i+len(distances)-1)%len(distances)] 36 if d2 >= d0 { 37 d1, i1 = d0, i0 38 d0, i0 = d2, i 39 } else if d2 >= d1 { 40 d1, i1 = d2, i 41 } 42 } 43 44 if i1 < i0 { 45 i0, i1 = i1, i0 46 } 47 48 pCh0 := PolyChain(c[i0 : i1+1]) 49 pCh1 := append(PolyChain(c[i1:]), PolyChain(c[:i0+1])...) 50 51 pCh0Approx, pCh1Approx := pCh0.Approximate(deviationMax), pCh1.Approximate(deviationMax) 52 53 return Contour(append(pCh0Approx, pCh1Approx[1:len(pCh1Approx)-1]...)) 54 }