проблема с Random.nextGaussian ()

Я закончил тем, что выбрал свое собственное решение, которое звучало более практично и просто, чем ответ @ arthur . Не уверен, что будет более производительным, хотя. Подводя итог, я сопоставляю, какие блоки перекрываются друг с другом, с помощью вложенного цикла и Path.intersects (path), а затем выполняю другой вложенный цикл, чтобы разделить каждый блок с его перекрывающимися блоками с помощью Path.divide (path), который обрезает исходный путь с тем путем, по которому ты его разделяешь.

Вот мой реальный код, который я использую в своем проекте с комментариями.

    setupGrid() {
        // Setup block row and column positions
        for (let i = 0;i < this.total;i++) {
            let x
            let y

            if (!odd(i)) {
                x = firstColumnStartX + (this.size/2)
                y = firstColumnStartY + ((i/2) * (this.size + this.gap)) + (this.size/2)
            } else {
                x = secondColumnStartX + (this.size/2)
                y = secondColumnStartY + (Math.floor(i/2) * (this.size + this.gap)) + (this.size/2)
            }

            this.blocks.push(new paper.Path.Rectangle({
                position: [x, y],
                size: this.size,
                strokeColor: '#ff000050'
            }))
        }

        // Setup array to check what blocks are intersecting
        const intersects = []

        // Setup empty array with a nested array mapped to other blocks [5 x [5 x undefined]]
        for (let i = 0;i < this.total;i++) {
            intersects[i] = new Array(this.total).fill(undefined)
        }

        // Intersect checking
        for (let i = 0;i < this.total;i++) {
            const block = this.blocks[i]

            for (let _i = 0;_i < this.total;_i++) {
                const otherBlock = this.blocks[_i]

                if (block !== otherBlock && intersects[i][_i] === undefined) {
                    intersects[_i][i] = intersects[i][_i] = block.intersects(otherBlock)
                }
            }
        }

        // First loop through all blocks
        for (let i = 0;i < this.total;i++) {
            let block = this.blocks[i]

            // Then loop through other blocks only if they were intersected with the original block
            for (let _i = 0;_i < this.total;_i++) {
                const otherBlock = this.blocks[_i]

                if (intersects[i][_i]) {
                    /* divide returns {
                        pieces: array of separated pieces that would be inside the original block's boundaries
                        leftoverBlock: what's leftover of the other block if the original block was subtracted from it
                    } */
                    const divide = this.divide(block, otherBlock)
                    block.remove()
                    otherBlock.remove()

                    // Override current block with the array of pieces
                    block = this.blocks[i] = divide.pieces

                    // Override other block with leftover
                    this.blocks[_i] = divide.leftoverBlock

                    // Don't let other block divide with original block since we already did it here
                    intersects[_i][i] = undefined
                }
            }
        }

        // Set random color for each piece to check if successful
        for (let i = 0;i < this.blocks.length;i++) {
            let block = this.blocks[i]

            if (block instanceof Array) {
                for (let _i = 0;_i < block.length;_i++) {
                    block[_i].fillColor = new paper.Color(Math.random(), Math.random(), Math.random(), 0.1)
                }
            } else {
                block.fillColor = new paper.Color(Math.random(), Math.random(), Math.random(), 0.1)
            }
        }
    }

    // Divide blockA with blockB and expand
    divideBlocks(blockA, blockB, pieces = []) {
        const divideA = blockA.divide(blockB)

        if (divideA instanceof paper.CompoundPath) {
            for (let i = divideA.children.length;i--;) {
                const child = divideA.children[i]
                child.insertAbove(divideA)
                pieces.push(child)
            }
            divideA.remove()
        } else {
            pieces.push(divideA)
        }

        return pieces
    }

    // Divide group (array of paths) with divider
    divideGroup(children, divider, pieces = [], parent) {
        for (let i = children.length;i--;) {
            const child = children[i]

            if (parent) {
                child.insertAbove(parent)
            }

            if (child.intersects(divider)) {
                this.divideBlocks(child, divider, pieces)
            } else {
                pieces.push(child)
            }
        }
    }

    // Subtract group (array of paths) from block
    subtractGroupFromBlock(block, group) {
        let oldBlock
        let newBlock = block

        for (let i = group.length;i--;) {
            const child = group[i]

            if (child.intersects(block)) {
                newBlock = newBlock.subtract(child)

                if (oldBlock) {
                    oldBlock.remove()
                }

                oldBlock = newBlock
            }
        }

        return newBlock
    }

    // Check what kind of divide method to use
    divide(blockA, blockB) {
        const pieces = []
        let leftoverBlock

        if (blockA instanceof paper.Path) {
            this.divideBlocks(blockA, blockB, pieces)
            leftoverBlock = blockB.subtract(blockA)
        } else if (blockA instanceof Array) {
            this.divideGroup(blockA, blockB, pieces)
            leftoverBlock = this.subtractGroupFromBlock(blockB, blockA)
        }

        return {
            pieces,
            leftoverBlock
        }
    }

Мои блоки установлены со случайными цветами для дифференциации каждой фигуры:

Перекрывающиеся блоки перед: https://i.imgur.com/j9ZSUC5.png

[ 118] Перекрывающиеся блоки, разделенные на части: https://i.imgur.com/mc83IH6.png

.

6
задан dirkgently 10 March 2009 в 11:52
поделиться

5 ответов

Распределение Гаусса со средним 0 и стандартным отклонением, каждый подразумевает, что среднее число распределения 0 и приблизительно 70% населения, находится в диапазоне [-1, 1]. Проигнорируйте числа, которые являются вне Вашего диапазона - они формируют край 16% приблизительно с обеих сторон.

Возможно, лучшее решение состоит в том, чтобы генерировать распределение с mean=0 и std.dev=0.5. Это даст Вам распределение приблизительно с 96% значений в диапазоне [-1, 1].

Еще лучшее решение состоит в том, чтобы работать назад как выше и использовать идею, что приблизительно 99,7% значений находится в диапазоне с 3 сигмами: используйте a std.dev = 1/3. Это почти аннулирует сумму значений not-so-useful, которые Вы получаете. Когда Вы действительно доберетесь один, опустите его.

Конечно, если Вы работаете над математикой интенсивный продукт, все это не переносит значения.

17
ответ дан 8 December 2019 в 02:24
поделиться

Стандартное отклонение 1,0 влечет за собой, что много значений лягут вне эти [-1,1] диапазон.

Если необходимо остаться в рамках этого диапазона, необходимо использовать другой метод, возможно, nextDouble ().

1
ответ дан 8 December 2019 в 02:24
поделиться

Распределение Гаусса с Вашими параметрами. имеет плотность e^ (-x^2/2). В целом это имеет форму e^ (линейный (x) +linear (x^2)), что означает любые настройки, которые Вы даете ему, у Вас есть некоторая вероятность получения очень больших и очень небольших чисел.
Вы, вероятно, ищете некоторое другое распределение.

2
ответ дан 8 December 2019 в 02:24
поделиться

Нормальное распределение дает ненулевое (но "становление чрезвычайно маленьким") вероятность наблюдения значений снаружи [-1, +1] безотносительно различия Вы даете - Вы просто хлюпаете кривая, эффективно.

Вы могли использовать небольшое различие и затем просто выполнить результаты через карту, которая обрезала что-либо меньше чем-1 к-1, и что-либо большее, чем от 1 до 1, но это (строго говоря) больше не будет нормальное распределение.

Что Вам нужно это распределение для из интереса?

6
ответ дан 8 December 2019 в 02:24
поделиться

Разве нормальное распределение не включает числа, произвольно далекие от среднего, но со все больше маленькими вероятностями? Могло бы случиться так, что Ваши требования (нормальный и ограниченный определенным диапазоном) являются несовместимыми.

11
ответ дан 8 December 2019 в 02:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: