File size: 1,405 Bytes
c19ca42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import itertools

import numpy as np


class ValueNoise:
    def __init__(self, dimensions: int, seed: int):
        self.dimensions = dimensions

        self.values = np.arange(16, dtype="float32")
        self.values = self.values / max(self.values)

        np.random.seed(seed)
        self.permutation_table = np.arange(self.values.size * 16)
        np.random.shuffle(self.permutation_table)

    def evaluate(self, points: np.ndarray):
        block, fractional = np.divmod(points, 1)

        corners = np.zeros(
            (points.shape[0], 2**self.dimensions, self.dimensions), dtype="int32"
        )
        weights = np.zeros((points.shape[0], 2**self.dimensions))

        for i, pattern in enumerate(itertools.product([0, 1], repeat=self.dimensions)):
            pattern = np.array(pattern, dtype=np.int32)
            corners[:, i] = block + pattern

            # linear interpolation
            weights[:, i] = np.prod(
                fractional * pattern + (1 - fractional) * (1 - pattern), axis=1
            )

        value_index = np.zeros(corners.shape[:2], dtype="int32")
        for i in range(corners.shape[2]):
            value_index = (value_index + corners[:, :, i]) % self.permutation_table.size
            value_index = self.permutation_table[value_index]
        values = self.values[value_index % self.values.size]

        return np.sum(values * weights, axis=1)