【问题标题】:Making a fractal landscape look more realistic使分形景观看起来更逼真
【发布时间】:2020-04-26 19:25:28
【问题描述】:

在 STL 格式中,这就是 my current landscape 的样子。而this 就是风景应该看起来的样子。我想我知道问题是什么,但我不知道如何解决它。

我认为我需要设置相对于它周围其他点的 Z 坐标,以便整个景观的 Z 坐标不在 0 和 1 之间,而是它们“相加”。

不想要一个解决方案,只需要一个正确方向的提示。

import java.io.*; 
import java.util.Random;

class Point3D {
    double x, y, z;

    Point3D(double dx, double dy, double dz) {
        x = dx;
        y = dy;
        z = dz;
    }

    Point3D middlePoint(Point3D p) {
        Point3D m = new Point3D(0.0, 0.0, 0.0);
        m.x = (this.x + p.x) / 2.0;
        m.y = (this.y + p.y) / 2.0;
        m.z = (this.z + p.z) / 2.0;
        return m;
    }
}

public class Aufgabe3 {

    public static void recursion(Point3D p1, Point3D p2, Point3D p3, int n) {
        if (n > 0) {
            if (n == 1) {
                System.out.println("    facet normal 0.0 0.0 0.0");
                System.out.println("        outer loop");
                System.out.println("            vertex " + p1.x + " " + p1.y + " " + p1.z);
                System.out.println("            vertex " + p2.x + " " + p2.y + " " + p2.z);
                System.out.println("            vertex " + p3.x + " " + p3.y + " " + p3.z);
                System.out.println("        endloop");
                System.out.println("    endfacet");
            }
            Random r = new Random();
            Point3D a = p1.middlePoint(p2);
            Point3D b = p3.middlePoint(p1);
            Point3D c = p2.middlePoint(p3);
            long seedA = (long) ((p1.x + p1.y + p1.z + p2.x + p2.y + p2.z) * 1000000);
            r.setSeed(seedA);
            a.z = r.nextDouble() / 10;
            long seedB = (long) ((p3.x + p3.y + p3.z + p1.x + p1.y + p1.z) * 1000000);
            r.setSeed(seedB);
            b.z = r.nextDouble() / 10;
            long seedC = (long) ((p2.x + p2.y + p2.z + p3.x + p3.y + p3.z) * 1000000);
            r.setSeed(seedC);
            c.z = r.nextDouble() / 10;
            recursion(p1, a, b, n-1);
            recursion(a, p2, c, n-1);
            recursion(b, c, p3, n-1);
            recursion(a, b, c, n-1);
        } 
    }

    public static void main(String args[]) throws FileNotFoundException {
        int n;
        try {
            n = Integer.parseInt(args[0]);
        } 
        catch (Exception e) {
            n = 7;
        }
        System.out.println("Aufgabe 3: Landschaftsgenerator");
        System.out.println("n = " + n);
        Random r = new Random();
        Point3D p1 = new Point3D(0.8, -1.2, 0.0);
        Point3D p2 = new Point3D(1.0, 1.3, 0.0);
        Point3D p3 = new Point3D(-1.0, 0.0, 0.0);
        System.setOut(new PrintStream(new FileOutputStream("Aufgabe3.stl"))); 
        System.out.println("solid Aufgabe3");
        recursion(p1, p2, p3, n);
        System.out.println("endsolid");
    }
}

【问题讨论】:

  • 你知道你必须“加起来”价值,你为什么不这样做呢?新点的Z 坐标将与之前的Z 坐标随机不同。请记住,您可能需要限制这些值,以免值过高或过低。
  • a.z += 0.1 * r.nextDouble() * Math.pow(2.0,n)。其他点类似
  • @Progman 我很尴尬。我想我在那里有严重的隧道视野。 @MattTimmermans 我不太确定我理解为什么它可以与Math.pow(2.0,n) 一起使用,但效果很好。 (不过我不得不将 0.1 降低到 0.003 左右)

标签: java fractals


【解决方案1】:

问题在于您添加的位移的频率分布。分形景观的位移必须遵循 1/(f^b) 分布,否则您会得到随机噪声。

在这种情况下,无论细分规模如何,您都会添加相同的垂直位移,这将导致景观以最高频率为主。形式上,分形表面是具有“分数”或“分形”几何维度的表面,高于表面的拓扑维度,但低于嵌入空间的拓扑维度。例如,对于在 3 维中位移的 2D 表面,分形维数应该在 2 到 3 之间。

对于细分和位移,分形维数与beta的关系如下:

Dim = (7 - b)/2

因此分形行为发生在 b = 1 和 b = 3 之间,并且随机位移遵循以下分布:

displacement = k * rand / (f^b)

这意味着,如果每次将三角形一分为二,则必须至少将位移减半,否则最终会得到一个噪波表面而不是分形表面。景观的最佳选择通常在 b = 2 左右。

参考:https://fractal-landscapes.co.uk/maths.html

【讨论】:

    猜你喜欢
    • 2015-02-15
    • 2020-04-18
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 2011-12-25
    相关资源
    最近更新 更多