在python中实现Perlin噪声的问题

2024-05-14 17:35:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图实现生成2dperlin噪声here的算法,但在Python中实现时遇到了一些问题(我对Python比较陌生)。在

我希望最终的噪波值(链接示例中的“z”)介于0.0和1.0之间,但这不是我得到的结果。我的代码在下面,我真的很感谢任何输入。在

谢谢!在

在柏林.py公司名称:

import math
import numpy
import random
import vector as vctr

from PIL import Image


def dot(v1, v2):
    """
    Returns the dot product of the two input vectors.

    Args:
    v1 - First vector
    v2 - Second vector

    Return:
    Resulting dot product
    """
    return (v1.x * v2.x) + (v1.y * v2.y)


def fade(t):
    """
    Fade 3t^2 - 2t^3

    Args:
    t  - Value to fade.

    Return:
    Faded value.
    """
    return (3 * (t ** 2)) - (2 * (t ** 3))


def lerp(minVal, maxVal, term):
    """
    Args:

    Return:
    """
    return (maxVal - minVal) * term + minVal


def generateImage(noises, file="perlin.png"):
    """
    Generates a image on disc of the resulting noise values

    Args:
    noises (list) - 2d list of noise values
    file (str) - location of file to write to
    """
    pixels = numpy.zeros((height, width, 3), dtype=numpy.uint8)

    for x in range(0, width):
        for y in range(0, height):  
            rgb = 255 * noises[x][y]
            pixels[x, y] = [rgb, rgb, rgb]

    # Print pixels as image    
    img = Image.fromarray(pixels, 'RGB')
    img.save(file)

# Define the noise region
width  = 300
height = 300

# Column ordered array of generated gradient vectors
g = numpy.zeros((width + 1, height + 1)).tolist()

# List of final noise values
z = numpy.zeros((width, height)).tolist()


# Fill list with randomly directed unit vectors (one for each grid point)
for x in range(0, width + 1):
    for y in range(0, height + 1):
        randX = random.uniform(-1.0, 1.0)
        randY = random.uniform(-1.0, 1.0)
        length = math.sqrt(randX**2 + randY**2)
        g[x][y] = vctr.vector(randX / length, randY / length)


# For each cell in the sampling space (i.e. each pixel)
for x in range(0, width):
    for y in range(0, height):

        # Generate random point (p) within and relative to current cell
        pX = random.uniform(0.0, 1.0)
        pY = random.uniform(0.0, 1.0)

        # Get the gradient vectors for each cell corner
        g_tl = g[x][y]
        g_tr = g[x + 1][y]
        g_bl = g[x][y + 1]
        g_br = g[x + 1][y + 1]

        # Vectors from each cell corner to the generated point
        # X axis is positive going right, Y is positive going down
        tl = vctr.vector(pX, pY)
        tr = vctr.vector(pX - 1, pY)
        bl = vctr.vector(pX, pY - 1)
        br = vctr.vector(pX - 1, pY - 1)

        # Dot product these vectors to get gradient values
        u = dot(tl, g_tl)
        v = dot(tr, g_tr)
        s = dot(bl, g_bl)
        t = dot(br, g_br)

        # Interpolate the gradient values
        sX = fade(pX)
        sY = fade(pY)

        a = s + (sX * (t - s))
        b = u + (sX * (v - u))
        value = a + (sY * (a - b))

        if (value < 0.0) or (value > 1.0):
            print("VALUE IS OUT OF BOUNDS??? " + str(value))

        z[x][y] = value


generateImage(z)
print("Completed Perlin noise generation!")

在向量.py公司名称:

^{2}$

Tags: ofthetoinpyforvaluerange

热门问题