Mercurial > gemma
view pkg/mesh/areas.go @ 5472:9321d9fb719f
improve README.md about licensing
* Use meanwhile established `SPDX-FileCopyrightText:` line to give the
holder of the usage rights, improve the explanation.
* Use `SPDX-License-Identifier:` also here.
author | Bernhard Reiter <bernhard@intevation.de> |
---|---|
date | Tue, 20 Jul 2021 11:50:17 +0200 |
parents | 181c2c05b12a |
children |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2018 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package mesh import ( "runtime" "sync" "gemma.intevation.de/gemma/pkg/common" ) // GenerateRandomVertices generates n random vertices. // X/Y values are diced between the X/Y components of min and max. // eval is called to find out the corresponding Z value. // The random vertices are are transfered in chunks to // the callback function. func GenerateRandomVertices( n int, min, max Vertex, eval func(float64, float64) (float64, bool), callback func([]Vertex), ) { var wg sync.WaitGroup jobs := make(chan int) out := make(chan []Vertex) done := make(chan struct{}) cpus := runtime.NumCPU() free := make(chan []Vertex, cpus) for i := 0; i < cpus; i++ { wg.Add(1) go func() { defer wg.Done() xRange := common.Random(min.X, max.X) yRange := common.Random(min.Y, max.Y) for size := range jobs { var vertices []Vertex select { case vertices = <-free: default: vertices = make([]Vertex, 0, 1000) } for len(vertices) < size { x, y := xRange(), yRange() if z, ok := eval(x, y); ok { vertices = append(vertices, Vertex{X: x, Y: y, Z: z}) } } out <- vertices } }() } go func() { defer close(done) for vertices := range out { callback(vertices) select { case free <- vertices[:0]: default: } } }() for remain := n; remain > 0; { if remain > 1000 { jobs <- 1000 remain -= 1000 } else { jobs <- remain remain = 0 } } close(jobs) wg.Wait() close(out) <-done }