【问题标题】:Diminishing returns based on distance within a square根据正方形内的距离递减收益
【发布时间】:2016-04-10 17:23:53
【问题描述】:

简而言之,我正在将地形(2d 高度图)从生成的值平滑回其在距离上的原始值。

有一个 6 单位的平坦区域仅使用生成的值,然后是一个 3 单位的平滑区域,从生成的值移回原始值(总共 9 个)

在平坦区域中,所有 x,z 值都分配了一个 y 值,例如 4,然后 3 个平滑单元应移回零,即 3,然后是 2,然后是 1,这将进行下一步(在如果零是我们的原始数字,则方程返回 0。

从反复试验看来,我需要分别计算角和边缘,因为角的最大距离是对角线,即 4.24,而边缘的最大距离仅为 3。我尝试了很多冗长的方法才能到达我所在的位置,但它仍然无法正常工作。不用说,虽然我还是要说,我不是数学天才。

谁能比我更好地解决这个问题?

    Vector3 pos = holeCenter - terrain.transform.position;

    //flatten area
    int posX = Mathf.FloorToInt(pos.x * (td.heightmapResolution / td.size.x));
    int posZ = Mathf.FloorToInt(pos.z * (td.heightmapResolution / td.size.z));
    float[,] heightMap = td.GetHeights(0, 0, td.heightmapResolution, td.heightmapResolution);
    float height =  heightMap[posZ, posX];
    int modZone = 9;
    int flatZone = 6;
    for (int x = posX - modZone; x <= posX + modZone; x++) {
        for (int z = posZ - modZone; z <= posZ + modZone; z++) {
            //if within 6 of cave ent (flat zone)
            if (x >= posX - flatZone && x <= posX + flatZone && z >= posZ - flatZone && z <= posZ + flatZone) {
                heightMap[z, x] = height + Random.Range(-0.00015f, 0.00015f);
            }
            //otherwise apply gently to the three rings around the flat area
            else {
                //if on a corner
                bool corner = false;
                if (x < posX - flatZone) {
                    if (z > posZ + flatZone) {
                        corner = true;
                    }
                    else if (z < posZ - flatZone) {
                        corner = true;
                    }
                }
                else if (x > posX + flatZone) {
                    if (z > posZ + flatZone) {
                        corner = true;
                    }
                    else if (z < posZ - flatZone) {
                        corner = true;
                    }
                }

                if (corner) {
                    //apply the new height to the old height decreasingly based on distance
                    float dist = Mathf.Sqrt(Mathf.Pow(Mathf.Abs(posX - x) - flatZone, 2f) +
                        Mathf.Pow(Mathf.Abs(posZ - z) - flatZone, 2f));
                    float maxDist = Mathf.Sqrt(Mathf.Pow(modZone - flatZone, 2f) * 2);
                    float multiplier = dist / maxDist;
                    heightMap[z, x] = (heightMap[z, x] * multiplier) + (height * (1 - multiplier)) + Random.Range(-0.00015f, 0.00015f);
                }
                else { //for an edge, only one value is in the modZone, find which, then apply
                    if (x < posX - flatZone || x > posX + flatZone) {
                        float multiplier = (Mathf.Abs(x - posX) - flatZone) / 4f;
                        heightMap[x, z] = (heightMap[z, x] * multiplier) + (height * (1 - multiplier)) + Random.Range(-0.00015f, 0.00015f);
                    }
                    else {
                        float multiplier = (Mathf.Abs(z - posZ) - flatZone) / 4f;
                        heightMap[x, z] = (heightMap[z, x] * multiplier) + (height * (1 - multiplier)) + Random.Range(-0.00015f, 0.00015f);
                    }
                }
            }
        }
    }
    td.SetHeights(0, 0, heightMap);

【问题讨论】:

    标签: c# math unity3d terrain


    【解决方案1】:

    我回到它之后就开始工作了。

        int modZone = 11;
        int flatZone = 7;
        for (int x = posX - modZone; x <= posX + modZone; x++) {
            for (int z = posZ - modZone; z <= posZ + modZone; z++) {
                float dist = Mathf.Sqrt(Mathf.Pow(Mathf.Abs(x - posX), 2f) + Mathf.Pow(Mathf.Abs(z - posZ), 2f));
                if (dist <= flatZone) { heightMap[z, x] = height + Random.Range(-0.00015f, 0.00015f); }
                else {
                    float multiplier = Mathf.Clamp01((modZone - dist) / (modZone - flatZone));
                    heightMap[z, x] = (heightMap[z, x] * (1 - multiplier)) + ((height + Random.Range(0, 0.0003f)) * multiplier);
                }
            }
        }
    

    我放弃了方形方法,但效果很好,圆形方法效果很好。也可能在更多样化的情况下工作得更好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-25
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      • 2013-09-28
      相关资源
      最近更新 更多