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  }