鱼C论坛

 找回密码
 立即注册
查看: 2028|回复: 1

有关柏林噪声生成噪声不连续的问题

[复制链接]
发表于 2022-12-3 16:36:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 bilbil路陌人 于 2022-12-3 16:44 编辑
# 尝试实现柏林噪声
import numpy as np
import matplotlib.pyplot as plt
import random


# 存储二维坐标梯度向量的数组(x,y)
G2 = [(-0.56, -0.39), (-0.88, 0.04), (0.84, 0.35), (-0.17, -0.62), (0.53, -0.49), (0.07, -0.89), (0.11, -0.38), (0.37, 0.5), (-0.7, -0.43), (-0.75, 0.09), (0.24, 0.23), (-0.59, -0.76), (0.53, 0.57), (0.67, -0.23), (0.18, -0.24), (0.43, 0.94), (0.58, 0.46), (0.32, 0.37), (-0.32, 0.58), (0.32, 0.52), (0.48, 0.75), (-0.9, 0.37), (-0.16, -0.33), (0.04, -0.36), (0.04, 0.68), (-0.75, 0.56), (0.87, 0.5), (0.66, 0.14), (0.94, -0.83), (-0.83, 0.18), (-0.53, 0.86), (0.41, -0.24), (0.64, -0.65), (-0.55, -0.86), (0.36, 0.58), (0.02, 0.55), (-0.27, 0.42), (0.45, -0.52), (-0.53, -0.71), (-0.44, 0.91), (-0.16, 0.18), (-0.21, -0.07), (0.77, 0.53), (-0.06, -0.02), (-0.53, 0.29), (-0.29, 0.35), (-0.63, -0.22), (0.26, -0.43), (0.53, -0.99), (-0.76, 0.25), (0.1, -0.86), (-0.36, -0.71), (-0.62, 0.51), (0.23, -0.69), (0.43, -0.29), (0.06, -0.04), (0.25, 0.75), (-0.0, 0.81), (0.64, 0.82), (-0.96, 0.12), (0.36, 0.42), (0.74, 0.61), (0.24, 0.57), (-0.28, -0.08), (-0.93, 0.45), (-0.83, -0.96), (0.68, 0.43), (0.7, 0.87), (0.12, 0.19), (-0.73, 0.82), (0.51, -0.03), (0.61, -0.33), (-0.47, 0.19), (0.71, -0.61), (0.41, -0.76), (-0.85, -0.2), (-0.65, 0.69), (0.89, 0.17), (-0.26, 0.36), (-0.59, 0.09), (-0.69, -0.15), (0.62, 0.5), (0.79, 0.97), (0.24, 0.6), (0.53, 0.69), (0.48, -0.06), (-0.27, -0.72), (-0.4, 0.29), (-0.01, -0.05), (0.61, -0.92), (0.18, -0.36), (0.76, -0.15), (-0.13, 0.33), (0.17, 0.06), (0.54, -0.79), (-0.78, -0.96), (-0.02, 0.47), (-0.97, 0.38), (0.78, 0.91), (0.58, 0.74), (0.79, 0.93), (-0.94, 0.15), (0.05, 0.15), (0.24, -0.77), (0.5, 0.14), (0.67, -0.98), (0.43, 0.01), (0.67, 0.52), (0.01, 0.1), (0.73, 0.6), (0.48, -0.22), (-0.79, 0.34), (0.98, 0.23), (-0.87, -0.93), (0.41, -0.22), (-0.98, -0.07), (0.68, 0.27), (-0.64, -0.02), (0.43, 0.7), (0.36, 0.2), (0.63, 0.48), (-0.36, -0.09), (-0.6, -0.86), (0.11, -0.16), (0.57, 0.75), (0.77, 0.41), (-0.91, 0.76), (-0.01, 0.71), (-0.8, 0.74), (-0.38, 0.1), (0.12, 0.22), (-0.19, 0.88), (0.44, -0.82), (-0.01, -0.86), (0.13, 0.05), (-0.58, 0.48), (-0.56, 0.34), (0.28, -0.63), (-0.35, -0.44), (0.73, -0.4), (0.82, 0.74), (0.07, 0.93), (-0.52, 0.66), (0.86, -0.85), (-0.86, 0.9), (0.95, -0.88), (-0.09, 0.46), (0.12, -0.72), (0.24, 0.51), (0.87, 0.77), (-0.82, -0.44), (-0.17,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  -0.98), (0.34, -0.21), (0.49, 0.15), (-0.85, -0.62), (0.5, -0.78), (-0.36, 0.73), (-0.42, -0.13), (-0.09, -0.65), (0.96, 0.72), (0.76, 0.12), (0.74, -0.65), (0.3, -0.01), (-0.41, 0.52), (-0.75, -0.66), (0.89, -0.39), (-0.82, 0.45), (0.98, 0.63), (0.3, -0.6), (0.83, -0.52), (-0.1, -0.78), (0.84, -0.39), (0.37, 0.38), (-0.53, -0.83), (-0.08, -0.98), (-0.95, 0.44), (-0.54, -0.4), (0.73, -0.13), (0.68, -0.44), (-0.36, -0.7), (-0.84, -0.34), (0.22, 0.54), (0.06, -0.31), (0.66, -0.71), (-0.43, 0.71), (-0.77, -0.99), (-0.54, 0.4), (-0.16, 0.97), (0.93, -0.37), (-0.0, -0.68), (0.29, 0.67), (-0.95, -0.81), (0.67, -0.53), (0.56, 0.16), (-0.26, -0.04), (-0.1, 0.5), (0.21, 0.71), (-0.76, 0.79), (0.06, 0.65), (-0.78, 0.29), (0.03, -0.68), (0.78, 0.76), (-0.75, 0.61), (-0.11, -0.58), (0.57, 0.06), (0.51, -0.2), (0.44, -0.9), (0.21, 0.22), (0.32, -0.52), (-0.38, 0.23), (0.57, 0.27), (-0.32, 0.49), (-0.09, -0.94), (0.13, 0.12), (-0.68, 0.16), (-0.11, -0.28), (-0.93, 0.62), (-0.52, 0.82), (-0.15, -0.97), (-0.83, 0.22), (0.18, 0.25), (0.06, -0.77), (0.53, 0.42), (0.73, -0.19), (-0.68, 0.38), (-0.45, -0.57), (0.75, -0.01), (-0.89, -0.1), (-0.97, 0.55), (0.24, 0.0), (-0.02, 0.65), (0.44, 0.87), (0.91, -0.51), (-0.33, -0.51), (-0.57, 0.05), (0.53, 0.68), (0.06, 0.83), (-0.46, 0.54), (-0.86, 0.46), (0.53, 0.6), (0.56, -0.76), (0.8, 0.95), (0.47, -0.24), (-0.85, -0.98), (-0.26, -0.89), (-1.0, -0.03), (0.04, 0.37), (-0.15, -0.7), (0.0, -0.69), (0.46, 0.57), (-0.47, -0.8), (0.31, 0.32), (-0.04, -0.1), (0.08, 0.82), (-0.48, 0.47), (0.64, -0.9)]*2
# 存储G2下表的数组P2
P2 = [149, 97, 137, 184, 58, 1, 220, 152, 41, 235, 246, 191, 36, 188, 190, 108, 222, 52, 39, 159, 104, 90, 197, 202, 5, 245, 93, 134, 157, 146, 38, 17, 124, 32, 203, 28, 106, 12, 233, 227, 77, 27, 155, 214, 114, 154, 242, 53, 139, 183, 16, 70, 130, 23, 229, 119, 101, 181, 228, 98, 230, 136, 107, 55, 225, 24, 199, 67, 34, 113, 182, 44, 215, 169, 66,
      208, 247, 131, 22, 80, 100, 212, 232, 87, 221, 167, 194, 29, 14, 33, 196, 115, 19, 170, 171, 240, 150, 63, 43, 244, 111, 206, 83, 51, 85, 151, 205, 249, 9, 163, 250, 75, 164, 195, 84, 147, 237, 209, 138, 79, 176, 248, 4, 129, 82, 73, 180, 239, 30, 234, 35, 173, 236, 76, 74, 89, 125, 189, 123, 20, 117, 148, 179, 207, 48, 251, 241, 140, 26, 172,
      18, 158, 92, 141, 94, 254, 71, 120, 62, 177, 186, 109, 56, 10, 226, 144, 61, 161, 72, 122, 187, 160, 49, 128, 7, 116, 68, 118, 112, 95, 238, 231, 252, 178, 166, 69, 88, 86,
      255, 105, 192, 210, 0, 174, 201, 31, 185, 57, 253, 59, 243, 142, 65, 224, 217, 135, 219, 145, 25, 126, 211, 2, 102, 162, 133, 153, 213, 37, 110, 54, 96, 165, 200, 15, 3, 21, 156, 78, 64, 121, 204, 218, 198, 127, 40, 103, 91, 143, 47, 216, 175, 11, 13, 132, 60, 6, 168, 8, 223, 193, 81, 50, 42, 46, 99, 45]


def square(length, width) -> int:
    '''定义单位正方形形成网格,x纵坐标为width,y横坐标为length
    [A, ,B]
    [     ]
    [C, ,D]'''
    # 存储单位正方形网格的二维数组
    square_list = [[0]*length for y in range(width)]
    for x in range(width):
        for y in range(length):
            # 定义梯度向量,存储到单位正方形中
            G = G2[P2[x]+y]
            square_list[x][y] = G
    # 返回填充完毕的单位正方形网格
    return square_list  # ?我当时加这个干嘛 *2


def dot(width, length):
    '''随机生成的输入点'''
    return (round(random.uniform(0, width-1), 2), round(random.uniform(0, length-1), 2))


def lerp(a, b, x):
    '''线性插值'''
    return a + x * (b-a)


def fade(t):
    '''fade函数计算u,v进行非线性差值,0<=t<=1'''
    return 6 * t**5 - 15 * t**4 + 10 * t**3


def perlin(dots, squares, persistence, cover_num) -> list:
    '''计算传入点的影响值,在地形中就是海拔,dot为一个[x,y]数组
    persistence为振幅,cover_num为叠加次数
    [Ga, ,Gb]
    [       ]
    [Gc, ,Gd]
    '''
    persistence = persistence
    dots_influence_value = []
    for map_num in range(1, cover_num+1):
        # TODO 叠加噪声仍然等待解决
        frequency = 2**map_num
        amplitude = persistence**map_num
    for num in range(len(dots)):
        # 获取点的xy坐标
        x = dots[num][0]
        y = dots[num][1]
        # 定位点所在的单位正方形
        x0 = int(x//1)
        y0 = int(y//1)
        x1 = int(x0 + 1)
        y1 = int(y0 + 1)
        # 计算距离向量
        distanceA = (x-x0, y-y0)
        distanceB = (x-x0, y-y1)
        distanceC = (x-x1, y-y0)
        distanceD = (x-x1, y-y1)
        # 获取四个顶点上的梯度向量
        Ga = squares[x0][y0]
        Gb = squares[x0][y1]
        Gc = squares[x1][y0]
        Gd = squares[x1][y1]
        # 对各个顶点上的梯度向量和距离向量做数量积运算,就是AB*AC = |AB|*|AC|*cosΘ
        # cosΘ = (AB * AC)/(|AB|*|AC|)
        # |AB| = (x**2 + y**2)**0.5
        #!草了,其实就是点乘运算x1x2+y1y2
        #! 计算出四个顶点的影响值
        valueA = Ga[0]*distanceA[0]+Ga[1]*distanceA[1]
        valueB = Gb[0]*distanceB[0]+Gb[1]*distanceB[1]
        valueC = Gc[0]*distanceC[0]+Gc[1]*distanceC[1]
        valueD = Gd[0]*distanceD[0]+Gd[1]*distanceD[1]
        #! 利用lerp和fade进行双线性插值计算,y为u,x为f)
        u = fade(y-y0)
        v = fade(x-x0)
        # 双线性插值的两个点
        #! 是对四个顶点的影响值进行插值
        y1 = lerp(valueA, valueB, u)
        y2 = lerp(valueC, valueD, u)
        # 用v进行最终输入点影响值计算
        dots_influence_value.append(lerp(y1, y2, v))
    return dots_influence_value


# 设定地图和单位正方形的长和宽
length = 100
width = 50
# TODO持续度(0~1)
persistence = 0.5

squares = square(length, width)
#print('单位正方形:\n',squares)

# 创建点坐标的列表,循环里的是个数
dots = [dot(width, length) for x in range(50)]
'''
dots = []
for x in range(10):
    for y in range(10):
        dots.append([x,y])
        '''
dots_position_x = []
dots_position_y = []
dots_num = len(dots)
# 分离两点坐标放到列表中形成映射
for x in range(dots_num):
    dots_position_x.append(dots[x][0])
    dots_position_y.append(dots[x][1])

# 整理两点坐标
dots_position_x.sort()
dots_position_y.sort()
dots_position = []
print('dots')
print(dots_position_x)
print(dots_position_y)

# 对两点坐标进行重组
for x in range(dots_num):
    for y in range(dots_num):
        dots_position.append([dots_position_x[x], dots_position_y[y]])
influence_value_list = perlin(dots_position, squares,persistence,cover_num=3)
#print(influence_value_list)

#将点的影响值转化为二维数组,其xy坐标与position_x,y形成映射
twoD_influence_value_list = []
counts = 0
for x in range(len(dots_position_x)):
    temp = []
    for y in range(len(dots_position_y)):
        temp.append(influence_value_list[counts])
        counts += 1
    twoD_influence_value_list.append(temp)
    
print(twoD_influence_value_list)
print(len(twoD_influence_value_list))

#print(dots_position)
#print(influence_value_list)
#?实际出点的数量应该是上述长度**2
plt.contourf(dots_position_y, dots_position_x, twoD_influence_value_list, 10)
plt.show()
#?并没有什么问题,但是不连续性还是有点强,可能是没有噪声叠加的原因

                               
登录/注册后可看大图

这个是可视化结果,不知道为什么连续性很差
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-12-3 22:08:01 | 显示全部楼层
666666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-15 18:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表